diff options
author | no author <devnull@mit.edu> | 2000-06-10 23:19:31 +0000 |
---|---|---|
committer | no author <devnull@mit.edu> | 2000-06-10 23:19:31 +0000 |
commit | bd3698ca72e4779f9dad5f04da691b407946bb60 (patch) | |
tree | 84b219debb23add43152a20358a816e94e3b2d17 | |
parent | 38037332d7af42124646c268874e0833bd8ec30e (diff) | |
download | krb5-krb5-1.2-beta2.zip krb5-krb5-1.2-beta2.tar.gz krb5-krb5-1.2-beta2.tar.bz2 |
This commit was manufactured by cvs2svn to create tagkrb5-1.2-beta2
'krb5-1-2-beta2'.
git-svn-id: svn://anonsvn.mit.edu/krb5/tags/krb5-1-2-beta2@12384 dc483132-0cff-0310-8789-dd5450dbe970
287 files changed, 8303 insertions, 4730 deletions
@@ -1,19 +1,19 @@ -these were the - Kerberos Version 5, Release 1.1 + + Kerberos Version 5, Release 1.2 Release Notes -which will be updated before the next release by + The MIT Kerberos Team Unpacking the Source Distribution --------------------------------- The source distribution of Kerberos 5 comes in three gzipped tarfiles, -krb5-1.1.src.tar.gz, krb5-1.1.doc.tar.gz, and krb5-1.1.crypto.tar.gz. -The krb5-1.1.doc.tar.gz contains the doc/ directory and this README -file. The krb5-1.1.src.tar.gz contains the src/ directory and this +krb5-1.2.src.tar.gz, krb5-1.2.doc.tar.gz, and krb5-1.2.crypto.tar.gz. +The krb5-1.2.doc.tar.gz contains the doc/ directory and this README +file. The krb5-1.2.src.tar.gz contains the src/ directory and this README file, except for the crypto library sources, which are in -krb5-1.1.crypto.tar.gz. +krb5-1.2.crypto.tar.gz. Instruction on how to extract the entire distribution follow. These directions assume that you want to extract into a directory called @@ -23,21 +23,21 @@ If you have the GNU tar program and gzip installed, you can simply do: mkdir DIST cd DIST - gtar zxpf krb5-1.1.src.tar.gz - gtar zxpf krb5-1.1.crypto.tar.gz - gtar zxpf krb5-1.1.doc.tar.gz + gtar zxpf krb5-1.2.src.tar.gz + gtar zxpf krb5-1.2.crypto.tar.gz + gtar zxpf krb5-1.2.doc.tar.gz If you don't have GNU tar, you will need to get the FSF gzip distribution and use gzcat: mkdir DIST cd DIST - gzcat krb5-1.1.src.tar.gz | tar xpf - - gzcat krb5-1.1.crypto.tar.gz | tar xpf - - gzcat krb5-1.1.doc.tar.gz | tar xpf - + gzcat krb5-1.2.src.tar.gz | tar xpf - + gzcat krb5-1.2.crypto.tar.gz | tar xpf - + gzcat krb5-1.2.doc.tar.gz | tar xpf - -Both of these methods will extract the sources into DIST/krb5-1.1/src -and the documentation into DIST/krb5-1.1/doc. +Both of these methods will extract the sources into DIST/krb5-1.2/src +and the documentation into DIST/krb5-1.2/doc. Building and Installing Kerberos 5 ---------------------------------- @@ -73,50 +73,170 @@ krb5-bugs@mit.edu. Notes, Major Changes, and Known Bugs ------------------------------------ -* Triple DES support is included; however, it is only usable for - service keys at the moment, due to a large number of compatibility - issues. For example, the GSSAPI library has some (buggy) support - for a triple DES session key, but it is intentionally disabled. - ** Do not use triple-DES in your config files except as described in - ** the documentation. - -* The principal database now uses the btree backend of Berkeley DB. - This should result in improved KDC performance. - -* The lib/rpc tests do not appear to work under NetBSD-1.4, for - reasons that are not completely clear at the moment, but probably - have something to do with portmapper interfacing. This should not - affect other operations, such as kadmind operation. - -* Shared library builds are under a new framework; at this point only - Solaris (2.x), Irix (6.5), NetBSD (1.4 i386), and possibly Linux are - known to work. All other working shared library builds may be - figments of your imagination. - -* Many existing databases, especially those converted from krb4 - original databases, may contain expiration dates in 1999. You - should make sure to update these expiration dates, and also change - any config file entries that have two-digit years. - -* Hardware preauthentication is known to be broken; this will be fixed - in an upcoming release. - -* krb524d now defaults to forking into the background; use - "krb524d -nofork" to avoid forking. - -* Not all reported bugs have been fixed in this release, due to time - constraints. We are planning to make another release in the near - future with more complete triple DES support, and additional - bugfixes. Many of the bugs in our database are reported against - what is now quite old code, or require hardware that we do not have, - which make them difficult to reproduce and debug. We will work on - these older bugs and some externally submitted patches for the - following release. +* Triple DES support, for session keys as well as user or service + keys, should be nearly complete in this release. Much of the work + that has been needed is generic multiple-cryptosystem support, so + the addition of another cryptosystem should be much easier. + + * GSSAPI support for 3DES has been added. An Internet Draft is + being worked on that will describe how this works; it is not + currently standardized. Some backwards-compatibility issues in + this area mean that enabling 3DES support must be done with + caution; see below. + + * kdc.conf vs krb5.conf XXXXXXXXXXXXXXXXXXXXXXXXX + + * doc on upgrade path? XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + +* DNS support for locating KDCs is enabled by default. DNS support + for looking up the realm of a host is compiled in but disabled by + default (due to some concerns with DNS spoofing). + + We recommend that you publish your KDC information through DNS even + if you intend to rely on config files at your own site; otherwise, + sites that wish to communicate with you will have to keep their + config files updated with your information. One of the goals of + this code is to reduce the client-side configuration maintenance + requirements as much as is possible, without compromising security. + + See the administrator's guide for information on setting up DNS + information for your realm. XXXXXXXXXXXXXXXXXXXXXXXXXX + + One important effect of this for developers is that on many systems, + "-lresolv" must be added to the compiler command line when linking + Kerberos programs. + + Configure-time options are available to control the inclusion of the + DNS code and the setting of the defaults. Entries in krb5.conf will + also modify the behavior if the code has been compiled in. + XXXXXXXXXXXXXXXXXX details; man pages? + --enable-dns + --enable-dns-for-kdc + --enable-dns-for-realm + [libdefaults] ... + +* Numerous buffer-overrun problems have been found and fixed. Many of + these were in locations we don't expect can be exploited in any + useful way (for example, overrunning a buffer of MAXPATHLEN bytes if + a compiled-in pathname is too long, in a program that has no special + privileges). It may be possible to exploit a few of these to + compromise system security. + +* Partial support for IPv6 addresses has been added. It can be + enabled or disabled at configure time with --enable-ipv6 or + --disable-ipv6; by default, the configure script will search for + certain types and macros, and enable the IPv6 code if they're found. + The IPv6 support at this time mostly consists of including the + addresses in credentials. + +* A security problem in login.krb5 has been fixed. This problem was + only present if the krb4 compatibility code was not compiled in. + +* The client programs kinit, klist and kdestroy have been changed to + incorporate krb4 support. New command-line options control whether + krb4 behavior, krb5 behavior, or both are used. + +* Patches from Frank Cusack for much better hardware preauth support + have been incorporated. + +* Patches from Matt Crawford extend the kadmin ACL syntax so that + restrictions can be imposed on what certain administrators may do to + certain accounts. + +* A KDC on a host with multiple network addresses will now respond to + a client from the address that the client used to contact it. The + means used to implement this will however cause the KDC not to + listen on network addresses configured after the KDC has started. + +Minor changes +------------- + +* The shell code for searching for the Tcl package at configure time + has been modified. If a tclConfig.sh can be found, the information + it contains is used, otherwise the old searching method is tried. + Let us know if this new scheme causes any problems. + +* Shared library builds may work on HPUX, Rhapsody/MacOS X, and newer + Alpha systems now. + +* The Windows build will now include kvno and gss-sample. + +* The routine krb5_secure_config_files has been disabled. A new + routine, krb5_init_secure_context, has been added in its place. + +* The routine decode_krb5_ticket is now being exported as + krb5_decode_ticket. Any programs that used the old name (which + should be few) should be changed to use the new name; we will + probably eliminate the old name in the future. + +* The CCAPI-based credentials cache code has been changed to store the + local-clock time of issue and expiration rather than the KDC-clock + times. + +* On systems with large numbers of IP addresses, "kinit" should do a + better job of acquiring those addresses to put in the user's + credentials. + +* Several memory leaks in error cases in the gssrpc code have been + fixed. + +* A bug with login clobbering some internal static storage on AIX has + been fixed. + +* Per-library initialization and cleanup functions have been added, + for use in configurations that dynamically load and unload these + libraries. + +* Many compile-time warnings have been fixed. + +XXXXXXXXXXXXXXXXXXXXXXXXXXX login.c krb5_cc_set_default_name patch +from 1.1.1 needs including + +* The GSS sample programs have been updated to exercise more of the + API. + +* The telnet server should produce a more meaningful error message if + authentication is required but not provided. + +* Changes have been made to ksu to make it more difficult to use it to + leak information the user does not have access to. + +* The sample config file information for the CYGNUS.COM realm has been + updated, and the GNU.ORG realm has been added. + +* A configure-time option has been added to enable a replay cache in + the KDC. We recommend its use when hardware preauthentication is + being used. + +* Some new routines have been added to the library and krb5.h. + +* A new routine has been added to the prompter interface to allow the + application to determine which of the strings prompted for is the + user's password, in case it is needed for other purposes. + +* The remote kadmin interface has been enhanced to support the + specification of key/salt types for a principal. + +* New keytab entries' key values can now be specified manually with a + new command in the ktutil program. + +* A longstanding bug where certain krb4 exchanges using the + compatibility library between systems with different byte orders + would fail half the time has been fixed. + +* A source file under the GPL has been replaced with an equivalent + under the BSD license. The file, strftime.c, was part of one of the + OpenVision admin system applications, and was only used on systems + that don't have strftime() in their C libraries. + +* Many bug reports are still outstanding in our database. We are + continuing to work on this backlog. + Copyright Notice and Legal Administrivia ---------------------------------------- -Copyright (C) 1985-1999 by the Massachusetts Institute of Technology. +Copyright (C) 1985-2000 by the Massachusetts Institute of Technology. All rights reserved. diff --git a/doc/ChangeLog b/doc/ChangeLog index 38af2b8..a7b435a 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,27 @@ +2000-06-09 Tom Yu <tlyu@mit.edu> + + * admin.texinfo: Add descriptions of the kadmin {ank,cpw,ktadd} -e + flag. + +2000-06-06 Ken Raeburn <raeburn@mit.edu> + + * install.texinfo: Describe new DNS support, and 3DES upgrade + path. Update "enctypes" config file sample lines. + + * build.texinfo: No kpasswd directory. Describe new configure + options. + + * send-pr.texinfo: Suggest caution regarding tab expansion for + patches. + +2000-06-02 Ken Raeburn <raeburn@mit.edu> + + * definitions.texinfo: Update for 1.2 release. + +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * krb425.texinfo (libdefaults): Add description of v4_realm. + 1999-09-22 Tom Yu <tlyu@mit.edu> * copyright.texinfo: Update copyright again. diff --git a/doc/admin.texinfo b/doc/admin.texinfo index 2ea716b..b739435 100644 --- a/doc/admin.texinfo +++ b/doc/admin.texinfo @@ -1418,6 +1418,12 @@ security-critical. Sets the key of the principal to the specified string and does not prompt for a password (@code{add_principal} only). @value{COMPANY} does not recommend using this option. + +@item -e @i{enc:salt...} +Uses the specified list of enctype-salttype pairs for setting the key of +the principal. The quotes are necessary if there are multiple +enctype-salttype pairs. This will not function against kadmin daemons +earlier than krb5-1.2. @end table If you want to just use the default values, all you need to do is: @@ -1529,6 +1535,12 @@ Sets the key of the principal to a random value. @item @b{-pw} @i{password} Sets the password to the string @i{password}. @value{COMPANY} does not recommend using this option. + +@item @b{-e} @i{"enc:salt..."} +Uses the specified list of enctype-salttype pairs for setting the key of +the principal. The quotes are necessary if there are multiple +enctype-salttype pairs. This will not function against kadmin daemons +earlier than krb5-1.2. @end table For example: @@ -2001,6 +2013,12 @@ The @code{ktadd} command takes the following switches: use @i{keytab} as the keytab file. Otherwise, @code{ktadd} will use the default keytab file (@code{/etc/krb5.keytab}). +@item @b{-e} @i{"enc:salt..."} +Uses the specified list of enctype-salttype pairs for setting the key of +the principal. The quotes are necessary if there are multiple +enctype-salttype pairs. This will not function against kadmin daemons +earlier than krb5-1.2. + @item -q run in quiet mode. This causes @code{ktadd} to display less verbose information. diff --git a/doc/build.texinfo b/doc/build.texinfo index 78aa8b4..d41b36a 100644 --- a/doc/build.texinfo +++ b/doc/build.texinfo @@ -59,8 +59,8 @@ only need to build Kerberos for one platform, using a single directory tree which contains both the source files and the object files is the simplest. However, if you need to maintain Kerberos for a large number of platforms, you will probably want to use separate build trees for -each platform. We recommend that you look at see @ref{OS -Incompatibilities} for notes that we have on particular operating +each platform. We recommend that you look at @ref{OS +Incompatibilities}, for notes that we have on particular operating systems. @menu @@ -208,7 +208,7 @@ Kerberos and then want to run the KADM5 tests, you will need to re-configure the tree and run @code{make} at the top level again to make sure all the proper programs are built. To save time, you actually only need to reconfigure and build in the directories src/kadmin/testing, -src/lib/rpc, src/lib/kadm5, and src/kpasswd. +src/lib/rpc, src/lib/kadm5. @node Options to Configure, osconf.h, Testing the Build, Building Kerberos V5 @section Options to Configure @@ -301,12 +301,6 @@ default, Kerberos V5 configuration will look for @code{-lnsl} and (see @ref{Solaris versions 2.0 through 2.3}) or fails to pass the tests in @file{src/tests/resolv} you will need to use this option. -@item --enable-shared - -This option will turn on the building and use of shared library objects -in the Kerberos build. This option is only supported on certain -platforms. - @item --with-vague-errors If enabled, gives vague and unhelpful error messages to the client... er, @@ -329,10 +323,30 @@ Tcl. The directory specified by @code{TCLPATH} specifies where the Tcl header file (@file{TCLPATH/include/tcl.h} as well as where the Tcl library should be found (@file{TCLPATH/lib}). +@item --enable-shared + +This option will turn on the building and use of shared library objects +in the Kerberos build. This option is only supported on certain +platforms. + +@item --enable-dns +@itemx --enable-dns-for-kdc +@itemx --enable-dns-for-realm + +Enable the use of DNS to look up a host's Kerberos realm, or a realm's +KDCs. See @x @x @xxxxx. + +@item --enable-kdc-replay-cache + +Enable a cache in the KDC to detect retransmitted messages, and resend +the previous responses to them. This protects against certain types of +attempts to extract information from the KDC through some of the +hardware preauthentication systems. + @end table For example, in order to configure Kerberos on a Solaris machine using -the @samp{suncc} with the optimizer turned on, run the configure +the @samp{suncc} compiler with the optimizer turned on, run the configure script with the following options: @example @@ -465,6 +479,10 @@ was never a problem in using GCC version 2.6.3. In version 3.2 and beyond of the operating system, we have not seen any problems with the native compiler. +@c @node Alpha Tru64 UNIX 5.0 +@c @subsection Alpha Tru64 UNIX 5.0 +@c ... login.krb5 problems + @node BSDI, HPUX, Alpha OSF/1 (Digital Unix) V2.0++, OS Incompatibilities @subsection BSDI diff --git a/doc/copyright.texinfo b/doc/copyright.texinfo index 7ea4758..83fe7ef 100644 --- a/doc/copyright.texinfo +++ b/doc/copyright.texinfo @@ -1,4 +1,4 @@ -Copyright @copyright{} 1985-1999 by the Massachusetts Institute of Technology. +Copyright @copyright{} 1985-2000 by the Massachusetts Institute of Technology. @quotation Export of software employing encryption from the United States of diff --git a/doc/definitions.texinfo b/doc/definitions.texinfo index 079809d..5a5b37c 100644 --- a/doc/definitions.texinfo +++ b/doc/definitions.texinfo @@ -19,8 +19,8 @@ @set RANDOMUSER johndoe @set RANDOMUSER1 jennifer @set RANDOMUSER2 david -@set RELEASE 1.1 -@set PREVRELEASE 1.0 +@set RELEASE 1.2 +@set PREVRELEASE 1.1 @set INSTALLDIR /usr/@value{LCPRODUCT} @set PREVINSTALLDIR @value{INSTALLDIR} @set ROOTDIR /usr/local diff --git a/doc/install.texinfo b/doc/install.texinfo index 8744b0f..05c7d9a 100644 --- a/doc/install.texinfo +++ b/doc/install.texinfo @@ -229,7 +229,10 @@ BOSTON.@value{SECONDREALM} and HOUSTON.@value{SECONDREALM}. @node Mapping Hostnames onto Kerberos Realms, Ports for the KDC and Admin Services, Kerberos Realms, Realm Configuration Decisions @section Mapping Hostnames onto Kerberos Realms -Mapping hostnames onto Kerberos realms is done through a set of rules in +Mapping hostnames onto Kerberos realms is done in one of two ways. + +The first mechanism, which has been in use for years in MIT-based +Kerberos distributions, works through a set of rules in the @code{krb5.conf} configuration file. (@xref{krb5.conf}.) You can specify mappings for an entire domain or subdomain, and/or on a hostname-by-hostname basis. Since greater specificity takes precedence, @@ -240,7 +243,14 @@ The @value{PRODUCT} System Administrator's Guide contains a thorough description of the parts of the @code{krb5.conf} file and what may be specified in each. A sample @code{krb5.conf} file appears in @ref{krb5.conf}. You should be able to use this file, substituting the -relevant information for your Kerberos instllation for the samples. +relevant information for your Kerberos installation for the samples. + +The second mechanism, recently introduced into the MIT code base but not +currently used by default, works by looking up the information in +special records in the Domain Name Service. This too is described in +the @value{PRODUCT} System Administrator's Guide. Even if you do not +choose to use this mechanism within your site, you may wish to set up +anyways, for use when interacting with other sites. @node Ports for the KDC and Admin Services, Slave KDCs, Mapping Hostnames onto Kerberos Realms, Realm Configuration Decisions @section Ports for the KDC and Admin Services @@ -293,11 +303,19 @@ disasters. @section Hostnames for the Master and Slave KDCs @value{COMPANY} recommends that your KDCs have a predefined set of -CNAMEs, such as @code{@value{KDCSERVER}} for the master KDC and +CNAME records (DNS hostname aliases), such as @code{@value{KDCSERVER}} +for the master KDC and @code{@value{KDCSLAVE1}}, @code{@value{KDCSLAVE2}}, @dots{} for the slave KDCs. This way, if you need to swap a machine, you only need to change a DNS entry, rather than having to change hostnames. +A new mechanism for locating KDCs of a realm through DNS has been added +to the @value{COMPANY} @value{PRODUCT} distribution. As with the +DNS-based mechanism for determining the Kerberos realm of a host, we recommend +distributing the information this way for use by other sites that may +want to interact with yours using Kerberos, even if you don't +immediately make use of it within your own site. + @node Database Propagation, , Hostnames for the Master and Slave KDCs, Realm Configuration Decisions @section Database Propagation @@ -1007,6 +1025,7 @@ Database to Each Slave KDC}.) Switch the CNAMEs of the old and new master KDCs. (If you don't do this, you'll need to change the @code{krb5.conf} file on every client machine in your Kerberos realm.) + @end enumerate @node Installing and Configuring UNIX Client Machines, UNIX Application Servers, Installing KDCs, Installing Kerberos V5 @@ -1050,7 +1069,7 @@ counterparts @c @code{from} @code{su}, @code{passwd}, and @code{rdist}. -@node Client Machine Configuration Files, Mac OS X Configuration, Client Programs, Installing and Configuring UNIX Client Machines +@node Client Machine Configuration Files, , Client Programs, Installing and Configuring UNIX Client Machines @subsection Client Machine Configuration Files Each machine running Kerberos must have a @code{/etc/krb5.conf} file. @@ -1399,6 +1418,41 @@ To update a Slave KDC, you must stop the old server processes on the Slave KDC, install the new server binaries, reload the most recent slave dump file, and re-start the server processes. +@node Upgrading to Triple-DES Encryption Keys, , Upgrading Existing Kerberos V5 Installations, Upgrading Existing Kerberos V5 Installations +@section Upgrading to Triple-DES Encryption Keys + +Beginning with the 1.2 release from MIT, Kerberos includes a stronger +encryption algorithm called ``triple DES'' -- essentially, three +applications of the basic DES encryption algorithm, greatly increasing +the resistance to a brute-force search for the key by an attacker. This +algorithm is more secure, but encryption is much slower. We expect to +add other, faster encryption algorithms at some point in the future. + +Release 1.1 had some support for triple-DES service keys, but with +release 1.2 we have added support for user keys and session keys as +well. Release 1.0 had very little support for multiple cryptosystems, +and some of that software may not function properly in an environment +using triple-DES as well as plain DES. + +Because of the way the MIT Kerberos database is structured, the KDC will +assume that a service supports only those encryption types for which +keys are found in the database. Thus, if a service has only a +single-DES key in the database, the KDC will not issue tickets for that +service that use triple-DES session keys; it will instead issue only +single-DES session keys, even if other services are already capable of +using triple-DES. So if you make sure your application server software +is updated before adding a triple-DES key for the service, clients +should be able to talk to services at all times during the updating +process. + +Normally, the listed @code{supported_enctypes} in @code{kdc.conf} are +all used when a new key is generated. You can control this with +command-line flags to @code{kadmin} and @code{kadmin.local}. You may +want to exclude triple-DES by default until you have updated a lot of +your application servers, and then change the default to include +triple-DES. We recommend that you always include @code{des-cbc-crc} in +the default list. + @node Bug Reports for Kerberos V5, Files, Upgrading Existing Kerberos V5 Installations, Top @chapter Bug Reports for @value{PRODUCT} @@ -1422,8 +1476,8 @@ Here is an example @code{krb5.conf} file: [libdefaults] ticket_lifetime = 600 default_realm = @value{PRIMARYREALM} - default_tkt_enctypes = des-cbc-crc - default_tgs_enctypes = des-cbc-crc + default_tkt_enctypes = des3-hmac-sha1 des-cbc-crc + default_tgs_enctypes = des3-hmac-sha1 des-cbc-crc [realms] @value{PRIMARYREALM} = @{ @@ -1478,17 +1532,14 @@ Here's an example of a kdc.conf file: kadmind_port = 749 max_life = 10h 0m 0s max_renewable_life = 7d 0h 0m 0s - master_key_type = des-cbc-crc - supported_enctypes = des-cbc-crc:normal + master_key_type = des3-hmac-sha1 + supported_enctypes = des3-hmac-sha1:normal des-cbc-crc:normal @} @end group @end smallexample -To add Kerberos V4 support, change the @code{supported_enctypes} line to: - -@smallexample - supported_enctypes = des-cbc-crc:normal des-cbc-crc:v4 -@end smallexample +To add Kerberos V4 support, add @code{des-cbc-crc:v4} to the +@code{supported_enctypes} line. @menu * Encryption Types and Salt Types:: @@ -1514,6 +1565,11 @@ your @value{PRODUCT} keys encounter only if you dump an AFS database into a Kerberos database @end itemize +For best compatibility with Microsoft Kerberos clients, the +@code{normal} salt type should be listed ahead of other salt types for +the same encryption type in the KDC config file and (when specified) on +the @code{kadmin} command line. + Support for additional encryption types is planned in the future. @contents diff --git a/doc/krb425.texinfo b/doc/krb425.texinfo index e78d4e6..12572e5 100644 --- a/doc/krb425.texinfo +++ b/doc/krb425.texinfo @@ -140,6 +140,14 @@ This subsection allows the administrator to configure exceptions to the default_domain mapping rule. It contains V4 instances (tag name) which should be translated to some specific hostname (tag value) as the second component in a Kerberos V5 principal name. + +@itemx v4_realm +This relation allows the administrator to configure a different +realm name to be used when converting V5 principals to V4 +ones. This should only be used when running separate V4 and V5 +realms, with some external means of password sychronization +between the realms. + @end table @node kdc.conf, , krb5.conf, Configuration Files diff --git a/doc/send-pr.texinfo b/doc/send-pr.texinfo index 9209ffd..7cf9b70 100644 --- a/doc/send-pr.texinfo +++ b/doc/send-pr.texinfo @@ -4,7 +4,11 @@ built and installed @value{PRODUCT}, please use the Bug reports that include proposed fixes are especially welcome. If you do include fixes, please send them using either context diffs or unified -diffs (using @samp{diff -c} or @samp{diff -u}, respectively). +diffs (using @samp{diff -c} or @samp{diff -u}, respectively). Please be +careful when using ``cut and paste'' or other such means to copy a patch +into a bug report; depending on the system being used, that can result +in converting TAB characters into spaces, which makes applying the +patches more difficult. The @code{krb5-send-pr} program is installed in the directory @code{@value{ROOTDIR}/sbin}. diff --git a/src/ChangeLog b/src/ChangeLog index 25737d4..36e1646 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,48 @@ +2000-06-08 Tom Yu <tlyu@mit.edu> + + * aclocal.m4 (CC_LINK_STATIC): Fix to use old library search + order; otherwise if there are shared libraries with the same name + elsewhere in the search path, they'll take precedence over the + static ones in the tree. + +2000-05-08 Nalin Dahyabhai <nalin@redhat.com> + + * wconfig.c (main): Warn if copying command-line option string + will overflow internal buffer. + +2000-05-03 Tom Yu <tlyu@mit.edu> + + * aclocal.m4 (AC_KRB5_TCL_TRYOLD): Search by appending stuff to + CPPFLAGS and LDFLAGS to notice if there may be problems with stuff + earlier along in either variable overriding. + +2000-04-18 Ken Raeburn <raeburn@mit.edu> + + * aclocal.m4 (KRB5_AC_ENABLE_DNS): Set RESOLV_LIB, and substitute + it into the Makefile. + (AC_LIBRARY_NET): Set RESOLV_LIB. + +2000-04-18 Danilo Almeida <dalmeida@mit.edu> + + * Makefile.in (clean-windows): Actually clean gss-sample on Windows. + +2000-04-11 Danilo Almeida <dalmeida@mit.edu> + + * Makefile.in (clean-windows): Clean gss-sample on Windows. + +2000-04-04 Ken Raeburn <raeburn@mit.edu> + + * aclocal.m4 (KRB5_AC_ENABLE_DNS): Check for dns, dns-for-kdc, and + dns-for-realm separately. Define KRB5_DNS_LOOKUP if either mode + is enabled. Define KRB5_DNS_LOOKUP_KDC and KRB5_DNS_LOOKUP_REALM + if the appropriate modes are enabled. + * acconfig.h (KRB5_DNS_LOOKUP_KDC, KRB5_DNS_LOOKUP_REALM): Undef. + +2000-03-24 Ken Raeburn <raeburn@mit.edu> + + * aclocal.m4 (KRB5_LIB_PARAMS): Check for alpha*-dec-osf* instead + of alpha-dec-osf*. + 2000-03-15 Ken Raeburn <raeburn@mit.edu> * aclocal.m4 (KRB5_AC_ENABLE_DNS): Fix typo that caused the DNS diff --git a/src/Makefile.in b/src/Makefile.in index 57efe5e..771be6a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -290,7 +290,10 @@ clean-windows:: Makefile-windows @echo Making clean in clients cd ..\clients $(MAKE) -$(MFLAGS) clean - cd .. + @echo Making in appl\gss-sample + cd ..\appl\gss-sample + $(MAKE) -$(MFLAGS) clean + cd ..\.. @echo Making clean in root # diff --git a/src/acconfig.h b/src/acconfig.h index e6f00c7..7ac14f0 100644 --- a/src/acconfig.h +++ b/src/acconfig.h @@ -32,6 +32,8 @@ /* Define if DNS support for finding realms and KDC locations should be compiled in. */ #undef KRB5_DNS_LOOKUP +#undef KRB5_DNS_LOOKUP_KDC +#undef KRB5_DNS_LOOKUP_REALM /* Define to `long' if <sys/types.h> doesn't define. */ #undef time_t diff --git a/src/aclocal.m4 b/src/aclocal.m4 index 3228610..48db9a6 100644 --- a/src/aclocal.m4 +++ b/src/aclocal.m4 @@ -783,8 +783,8 @@ if test "$with_tcl" != no ; then AC_CHECK_LIB(ld, main, DL_LIB=-lld) krb5_save_CPPFLAGS="$CPPFLAGS" krb5_save_LDFLAGS="$LDFLAGS" - CPPFLAGS="$TCL_INCLUDES $CPPFLAGS" - LDFLAGS="$TCL_LIBPATH $LDFLAGS" + CPPFLAGS="$CPPFLAGS $TCL_INCLUDES" + LDFLAGS="$LDFLAGS $TCL_LIBPATH" tcl_header=no AC_CHECK_HEADER(tcl.h,AC_DEFINE(HAVE_TCL_H) tcl_header=yes) if test $tcl_header=no; then @@ -1119,7 +1119,7 @@ CC_LINK_STATIC='$(CC) $(PROG_LIBPATH)' # Set up architecture-specific variables. case $krb5_cv_host in -alpha-dec-osf*) +alpha*-dec-osf*) SHLIBVEXT='.so.$(LIBMAJOR).$(LIBMINOR)' SHLIBSEXT='.so.$(LIBMAJOR)' SHLIBEXT=.so @@ -1129,7 +1129,11 @@ alpha-dec-osf*) SHLIB_EXPFLAGS='-rpath $(SHLIB_RDIRS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)' PROFFLAGS=-pg CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) -Wl,-rpath -Wl,$(PROG_RPATH)' - CC_LINK_STATIC='$(CC) $(PROG_LIBPATH)' + # Need -oldstyle_liblookup to avoid picking up shared libs from + # other builds. OSF/1 / Tru64 ld programs look through the entire + # library path for shared libs prior to looking through the + # entire library path for static libs. + CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) -Wl,-oldstyle_liblookup' # $(PROG_RPATH) is here to handle things like a shared tcl library RUN_ENV='LD_LIBRARY_PATH=`echo $(PROG_LIBPATH) | sed -e "s/-L//g" -e "s/ /:/g"`:$(PROG_RPATH):/usr/shlib:/usr/ccs/lib:/usr/lib/cmplrs/cc:/usr/lib:/usr/local/lib; export LD_LIBRARY_PATH; _RLD_ROOT=/dev/dummy/d; export _RLD_ROOT;' ;; @@ -1396,7 +1400,8 @@ AC_DEFUN(AC_LIBRARY_NET, [ # ugliness is necessary: AC_CHECK_LIB(socket, gethostbyname, LIBS="-lsocket -lnsl $LIBS", - AC_CHECK_LIB(resolv, gethostbyname), + AC_CHECK_LIB(resolv, gethostbyname, + LIBS="-lresolv $LIBS" ; RESOLV_LIB=-lresolv), -lnsl) ) ) @@ -1406,20 +1411,43 @@ AC_DEFUN(AC_LIBRARY_NET, [ KRB5_AC_ENABLE_DNS if test "$enable_dns" = yes ; then AC_CHECK_FUNC(res_search, , AC_CHECK_LIB(resolv, res_search, - LIBS="$LIBS -lresolv", + LIBS="$LIBS -lresolv" ; RESOLV_LIB=-lresolv, AC_ERROR(Cannot find resolver support routine res_search in -lresolv.) )) fi + AC_SUBST(RESOLV_LIB) ]) dnl dnl dnl KRB5_AC_ENABLE_DNS dnl AC_DEFUN(KRB5_AC_ENABLE_DNS, [ + enable_dns_for_kdc=yes + enable_dns_for_realm=no + AC_ARG_ENABLE([dns], -[ --enable-dns enable DNS lookups of Kerberos realm and servers], , +[ --enable-dns enable DNS lookups of Kerberos realm and servers], +[enable_dns_for_kdc="$enable_dns" +enable_dns_for_realm="$enable_dns"], [enable_dns=no]) if test "$enable_dns" = yes; then AC_DEFINE(KRB5_DNS_LOOKUP) fi + + AC_ARG_ENABLE([dns-for-kdc], +[ --enable-dns-for-kdc enable DNS lookups of Kerberos servers only]) + if test "$enable_dns_for_kdc" = yes; then + AC_DEFINE(KRB5_DNS_LOOKUP_KDC) + fi + + AC_ARG_ENABLE([dns-for-realm], +[ --enable-dns-for-realm enable DNS lookups of Kerberos realm names only]) + if test "$enable_dns_for_realm" = yes; then + AC_DEFINE(KRB5_DNS_LOOKUP_REALM) + fi + + if test "$enable_dns_for_kdc" = yes || test "$enable_dns_for_realm" = yes ; then + enable_dns=yes + AC_DEFINE(KRB5_DNS_LOOKUP) + fi ]) diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog index d3314b0..a9e835e 100644 --- a/src/appl/bsd/ChangeLog +++ b/src/appl/bsd/ChangeLog @@ -1,3 +1,128 @@ +2000-06-10 Ken Raeburn <raeburn@mit.edu> + + * krcp.c (main): Fix logic again, this time in the "success" + case. If there's a problem retrieving the new-protocol subkey, + print a message and exit, don't fall back. + * krsh.c (main): Ditto; don't look at enctype to try to guess + protocol version. Delete unused variable "similar". + +2000-06-09 Ken Raeburn <raeburn@mit.edu> + + * krlogin.c (main): Rework fallback logic. Fall back to k4cmd + unless encryption and the new protocol were both requested. + + * krsh.c (main): Rework fallback logic. Fall back to k4cmd if new + protocol wasn't requested. + + * krcp.c (main): Revert setting of AP_OPTS_MUTUAL_REQUIRED + unconditionally, which was added by mistake with last set of + patches. If kcmd fails and the new protocol is requested, don't + fall back to v4. + +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * Makefile.in (kcmd.o, krcp.o, krlogin.o, krlogind.o, krsh.o, + krshd.o): Depend on defines.h. + * krlogind.c: Include defines.h. + * krcp.c: Ditto. + + * defines.h (enum kcmd_proto): New type. + (rcmd_stream_read, rcmd_stream_write, getport, + rcmd_stream_init_krb5): Add prototypes. + + * kcmd.c (use_ivecs): New variable. + (encivec_i, encivec_o): Each is now an array of two elements. + (input, output, twrite, krb5_write_message, krb5_net_read, + krb5_net_write, krb_sendauth): Add prototypes. + (kcmd): New argument PROTONUMP points to enum kcmd_proto. If + value is KCMD_PROTOCOL_COMPAT_HACK, set it to KCMD_NEW_PROTOCOL or + KCMD_OLD_PROTOCOL depending on session key type. Use subkeys for + new protocol. Callers updated. + (normal_read, v5_des_read, v4_des_read, twrite, v5_des_write, + v4_des_write, rcmd_stream_write, rcmd_stream_read): Take + additional argument indicating whether the fd is for the secondary + channel; ignored except in some v5 cases. Callers updated. + (rcmd_stream_init_krb5): New argument, kcmd protocol version. Set + up ivecs for secondary channel in each direction with values 0x2 + ior primary channel value. Callers updated. + (v5_des_read, v5_des_write): For new protocol, plaintext now has + its length prepended but not counted. + + * krcp.c (main): Set kcmd protocol version based on command line, + not on encryption type. Default to COMPAT_HACK. + * krsh.c (main): Ditto. + * krlogin.c (main): Ditto. + + * krlogind.c (recvauth): Use new krb5_compat_recvauth_version + routine. Determine client's kcmd protocol version and initialize + based on it. + * krshd.c (recvauth): Ditto. + +2000-05-19 Nalin Dahyabhai <nalin@redhat.com> + Ken Raeburn <raeburn@mit.edu> + + * krcp.c (sink): bail if the target directory/file name is too long + * krlogind.c (recvauth, krb4 compat): truncate user name if the + principal's root would be too long to be valid + * v4rcp.c (sink): bail if the target directory/file name is too long + +2000-05-18 Tom Yu <tlyu@mit.edu> + + * krshd.c: Shuffle inclusion of defines.h so that some krb5 + structures are declared prior to the kcmd() prototype. + +2000-05-16 Ken Raeburn <raeburn@mit.edu> + + * defines.h (kcmd): Add prototype. + * krcp.c (main): Add extra arg to a kcmd call I missed yesterday. + +2000-05-15 Ken Raeburn <raeburn@mit.edu> + + * krcp.c (main): Fix some conditionalizations to make proper + indentation easier. + + * kcmd.c (encivec_i, encivec_o): New variables replace old single + variable encivec. + (rcmd_stream_init_krb5): New argument am_client, used to + initialize both ivec values. + * krcp.c (main, answer_auth): Pass new argument. + * krlogin.c (main): Ditto. + * krlogind.c (recvauth): Ditto. + * krsh.c (main): Ditto. + * krshd.c (recvauth): Ditto. + + * defines.h (OPTS_FORWARD_CREDS, OPTS_FORWARDABLE_CREDS): Change + numbers so they don't conflict with AP_OPTS_USE_SUBKEY. + * kcmd.c (kcmd): New argument authconp, used to return the auth + context to the caller if desired. + * krlogin.c (auth_context): New variable. + (main): Request a subkey from sendauth. Get the auth context from + kcmd so we can retrieve the subkey. If non-DES session key is + being used, pass the subkey to rcmd_stream_init_krb5 instead of + the session key; fail if no subkey is found and encryption is + required. + * krlogind.c (recvauth): If a non-DES session key is being used, + pass the client-provided subkey to rcmd_stream_init_krb5. + * krcp.c (main): Set up and use subkey as above. + * krsh.c (main): Set up and use subkey as above. + * krshd.c (recvauth): Accept and use subkey as above. + +2000-05-08 Ken Raeburn <raeburn@mit.edu> + + * v4rcp.c (main, case 'k'): Make sure krb_realm is + null-terminated. + +2000-04-27 Nalin Dahyabhai <nalin@redhat.com> + + * krlogin.c (main): Don't overflow buffer "term". + * krshd.c (doit): Don't overflow buffer "cmdbuf". + * login.c (afs_login): Don't overflow buffer "aklog_path". + +2000-03-24 Ken Raeburn <raeburn@mit.edu> + + * configure.in: Check for alpha*-dec-osf* instead of + alpha-dec-osf*. + 2000-03-15 Ken Raeburn <raeburn@mit.edu> Mark D. Roth <roth@uiuc.edu> diff --git a/src/appl/bsd/Makefile.in b/src/appl/bsd/Makefile.in index eee13ca..93a6cba 100644 --- a/src/appl/bsd/Makefile.in +++ b/src/appl/bsd/Makefile.in @@ -90,3 +90,4 @@ install:: getdtablesize.o: $(srcdir)/getdtablesize.c +kcmd.o krcp.o krlogin.o krlogind.o krsh.o krshd.o : defines.h diff --git a/src/appl/bsd/configure.in b/src/appl/bsd/configure.in index 6d31f48..cf65476 100644 --- a/src/appl/bsd/configure.in +++ b/src/appl/bsd/configure.in @@ -25,11 +25,12 @@ dnl Make our operating system-specific security checks and definitions for dnl login. dnl case $krb5_cv_host in -*-*-aix3*) # AIX has streams include files but not streams TTY -# Moreover, strops.h trashes sys/ioctl.h -krb5_cv_has_streams=no -;; -alpha-dec-osf*) +*-*-aix3*) + # AIX has streams include files but not streams TTY + # Moreover, strops.h trashes sys/ioctl.h + krb5_cv_has_streams=no + ;; +alpha*-dec-osf*) AC_CHECK_LIB(security,setluid, AC_DEFINE(HAVE_SETLUID) LOGINLIBS="$LOGINLIBS -lsecurity" diff --git a/src/appl/bsd/defines.h b/src/appl/bsd/defines.h index fd9c3e1..6365d2c 100644 --- a/src/appl/bsd/defines.h +++ b/src/appl/bsd/defines.h @@ -1,3 +1,43 @@ -#define OPTS_FORWARD_CREDS 0x00000002 -#define OPTS_FORWARDABLE_CREDS 0x00000001 +#define OPTS_FORWARD_CREDS 0x00000020 +#define OPTS_FORWARDABLE_CREDS 0x00000010 #define RCMD_BUFSIZ 5120 + +enum kcmd_proto { + /* Old protocol: DES encryption only. No subkeys. No protection + for cleartext length. No ivec supplied. OOB hacks used for + rlogin. Checksum may be omitted at connection startup. */ + KCMD_OLD_PROTOCOL = 1, + /* New protocol: Any encryption scheme. Client-generated subkey + required. Prepend cleartext-length to cleartext data (but don't + include it in count). Starting ivec defined, chained. In-band + signalling. Checksum required. */ + KCMD_NEW_PROTOCOL, + /* Hack: Get credentials, and use the old protocol iff the session + key type is single-DES. */ + KCMD_PROTOCOL_COMPAT_HACK, + /* Using Kerberos version 4. */ + KCMD_V4_PROTOCOL, + /* ??? */ + KCMD_UNKNOWN_PROTOCOL +}; + +extern int kcmd (int *sock, char **ahost, int /* u_short */ rport, + char *locuser, char *remuser, char *cmd, + int *fd2p, char *service, char *realm, + krb5_creds **cred, + krb5_int32 *seqno, krb5_int32 *server_seqno, + struct sockaddr_in *laddr, + struct sockaddr_in *faddr, + krb5_auth_context *authconp, + krb5_flags authopts, + int anyport, int suppress_err, + enum kcmd_proto *protonum /* input and output */ + ); + +extern int rcmd_stream_read (int fd, char *buf, int len, int secondary); +extern int rcmd_stream_write (int fd, char *buf, int len, int secondary); +extern int getport (int *); + +extern void rcmd_stream_init_krb5 (krb5_keyblock *in_keyblock, + int encrypt_flag, int lencheck, + int am_client, enum kcmd_proto protonum); diff --git a/src/appl/bsd/kcmd.c b/src/appl/bsd/kcmd.c index 0e68f88..fd54537 100644 --- a/src/appl/bsd/kcmd.c +++ b/src/appl/bsd/kcmd.c @@ -117,14 +117,18 @@ static char des_inbuf[2*RCMD_BUFSIZ]; /* needs to be > largest read size */ static char des_outpkt[2*RCMD_BUFSIZ+4]; /* needs to be > largest write size */ static krb5_data desinbuf; static krb5_data desoutbuf; -static krb5_data encivec; + +/* XXX Overloaded: use_ivecs!=0 -> new protocol, inband signalling, etc. */ +static int use_ivecs; +static krb5_data encivec_i[2], encivec_o[2]; + static krb5_keyblock *keyblock; /* key for encrypt/decrypt */ -static int (*input)(); -static int (*output)(); +static int (*input)(int, char *, int, int); +static int (*output)(int, char *, int, int); static char storage[2*RCMD_BUFSIZ]; /* storage for the decryption */ static int nstored = 0; static char *store_ptr = storage; -static int twrite(); +static int twrite(int, char *, int, int); static int v5_des_read(), v5_des_write(); #ifdef KRB5_KRB4_COMPAT static int v4_des_read(), v4_des_write(); @@ -133,8 +137,28 @@ static int right_justify; #endif static int do_lencheck; +/* XXX: These should be internal to krb5 library, or declared in krb5.h. */ +extern krb5_error_code krb5_write_message (krb5_context, krb5_pointer, + krb5_data *); +extern int krb5_net_read (krb5_context, int , char *, int); +extern int krb5_net_write (krb5_context, int , const char *, int); +/* XXX: And these should be declared in krb.h, or private. */ +extern int +krb_sendauth(long options, int fd, KTEXT ticket, + char *service, char *inst, char *realm, + unsigned KRB4_32 checksum, + MSG_DAT *msg_data, + CREDENTIALS *cred, + Key_schedule schedule, + struct sockaddr_in *laddr, + struct sockaddr_in *faddr, + char *version); + + +int kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm, - cred, seqno, server_seqno, laddr, faddr, authopts, anyport, suppress_err) + cred, seqno, server_seqno, laddr, faddr, authconp, authopts, anyport, + suppress_err, protonump) int *sock; char **ahost; u_short rport; @@ -142,15 +166,17 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm, int *fd2p; char *service; char *realm; - krb5_creds **cred; + krb5_creds **cred; /* output only */ krb5_int32 *seqno; krb5_int32 *server_seqno; struct sockaddr_in *laddr, *faddr; + krb5_auth_context *authconp; krb5_flags authopts; int anyport; int suppress_err; /* Don't print if authentication fails */ + enum kcmd_proto *protonump; { - int i, s, timo = 1, pid; + int s, pid; #ifdef POSIX_SIGNALS sigset_t oldmask, urgmask; #else @@ -164,7 +190,6 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm, int rc; char *host_save; krb5_error_code status; - krb5_error *err_ret; krb5_ap_rep_enc_part *rep_ret; krb5_error *error = 0; int sin_len; @@ -174,6 +199,8 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm, krb5_auth_context auth_context = NULL; char *cksumbuf; krb5_data cksumdat; + char *kcmd_version; + enum kcmd_proto protonum = *protonump; if ((cksumbuf = malloc(strlen(cmd)+strlen(remuser)+64)) == 0 ) { fprintf(stderr, "Unable to allocate memory for checksum buffer.\n"); @@ -361,12 +388,35 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR)) goto bad2; - /* call Kerberos library routine to obtain an authenticator, + if (protonum == KCMD_PROTOCOL_COMPAT_HACK) { + krb5_boolean is_des; + status = krb5_c_enctype_compare (bsd_context, ENCTYPE_DES_CBC_CRC, + ret_cred->keyblock.enctype, &is_des); + if (status) + goto bad2; + protonum = is_des ? KCMD_OLD_PROTOCOL : KCMD_NEW_PROTOCOL; + } + + switch (protonum) { + case KCMD_NEW_PROTOCOL: + authopts |= AP_OPTS_USE_SUBKEY; + kcmd_version = "KCMDV0.2"; + break; + case KCMD_OLD_PROTOCOL: + kcmd_version = "KCMDV0.1"; + break; + default: + status = EINVAL; + goto bad2; + } + + /* Call Kerberos library routine to obtain an authenticator, pass it over the socket to the server, and obtain mutual - authentication. */ + authentication. */ status = krb5_sendauth(bsd_context, &auth_context, (krb5_pointer) &s, - "KCMDV0.1", ret_cred->client, ret_cred->server, - authopts, &cksumdat, ret_cred, 0, &error, &rep_ret, NULL); + kcmd_version, ret_cred->client, ret_cred->server, + authopts, &cksumdat, ret_cred, 0, + &error, &rep_ret, NULL); free(cksumbuf); if (status) { if (!suppress_err) @@ -440,10 +490,13 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm, sigsetmask(oldmask); #endif /* POSIX_SIGNALS */ *sock = s; + *protonump = protonum; /* pass back credentials if wanted */ if (cred) krb5_copy_creds(bsd_context, ret_cred, cred); krb5_free_creds(bsd_context, ret_cred); + if (authconp) + *authconp = auth_context; return (0); bad2: @@ -464,6 +517,7 @@ kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, service, realm, #ifdef KRB5_KRB4_COMPAT +int k4cmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, ticket, service, realm, cred, schedule, msg_data, laddr, faddr, authopts, anyport) int *sock; @@ -701,7 +755,7 @@ reread: #endif /* KRB5_KRB4_COMPAT */ - +int getport(alport) int *alport; { @@ -733,16 +787,25 @@ getport(alport) return -1; } +static int +normal_read (int fd, char *buf, int len, int secondary) +{ + return read (fd, buf, len); +} + void rcmd_stream_init_normal() { - input = read; + input = normal_read; output = twrite; } -void rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck) +void rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck, am_client, + protonum) krb5_keyblock *in_keyblock; int encrypt_flag; int lencheck; + int am_client; + enum kcmd_proto protonum; { krb5_error_code status; size_t blocksize; @@ -760,33 +823,35 @@ void rcmd_stream_init_krb5(in_keyblock, encrypt_flag, lencheck) input = v5_des_read; output = v5_des_write; - if (status = krb5_c_enctype_compare(bsd_context, ENCTYPE_DES_CBC_CRC, - keyblock->enctype, - &similar)) { - /* XXX what do I do? */ - abort(); - } - - if (similar) { - encivec.length = 0; + if (protonum == KCMD_OLD_PROTOCOL) { + use_ivecs = 0; return; } + use_ivecs = 1; + if (status = krb5_c_block_size(bsd_context, keyblock->enctype, &blocksize)) { /* XXX what do I do? */ abort(); } - encivec.length = blocksize; + encivec_i[0].length = encivec_i[1].length = encivec_o[0].length + = encivec_o[1].length = blocksize; - if ((encivec.data = malloc(encivec.length)) == NULL) { + if ((encivec_i[0].data = malloc(encivec_i[0].length * 4)) == NULL) { /* XXX what do I do? */ abort(); } + encivec_i[1].data = encivec_i[0].data + encivec_i[0].length; + encivec_o[0].data = encivec_i[1].data + encivec_i[0].length; + encivec_o[1].data = encivec_o[0].data + encivec_i[0].length; /* is there a better way to initialize this? */ - memset(encivec.data, '\0', blocksize); + memset(encivec_i[0].data, am_client, blocksize); + memset(encivec_o[0].data, 1 - am_client, blocksize); + memset(encivec_i[1].data, 2 | am_client, blocksize); + memset(encivec_o[1].data, 2 | (1 - am_client), blocksize); } #ifdef KRB5_KRB4_COMPAT @@ -808,35 +873,39 @@ void rcmd_stream_init_krb4(session, encrypt_flag, lencheck, justify) } #endif -int rcmd_stream_read(fd, buf, len) +int rcmd_stream_read(fd, buf, len, sec) int fd; register char *buf; int len; + int sec; { - return (*input)(fd, buf, len); + return (*input)(fd, buf, len, sec); } -int rcmd_stream_write(fd, buf, len) +int rcmd_stream_write(fd, buf, len, sec) int fd; register char *buf; int len; + int sec; { - return (*output)(fd, buf, len); + return (*output)(fd, buf, len, sec); } /* Because of rcp lossage, translate fd 0 to 1 when writing. */ -static int twrite(fd, buf, len) +static int twrite(fd, buf, len, secondary) int fd; char *buf; int len; + int secondary; { return write((fd == 0) ? 1 : fd, buf, len); } -static int v5_des_read(fd, buf, len) +static int v5_des_read(fd, buf, len, secondary) int fd; char *buf; int len; + int secondary; { int nreturned = 0; size_t net_len,rd_len; @@ -879,7 +948,8 @@ static int v5_des_read(fd, buf, len) rd_len = (rd_len << 8) | c; if (ret = krb5_c_encrypt_length(bsd_context, keyblock->enctype, - rd_len, &net_len)) { + use_ivecs ? rd_len + 4 : rd_len, + &net_len)) { errno = ret; return(-1); } @@ -902,8 +972,8 @@ static int v5_des_read(fd, buf, len) plain.data = storage; /* decrypt info */ - if (krb5_c_decrypt(bsd_context, keyblock, KCMD_KEYUSAGE, - encivec.length?&encivec:0, + if (ret = krb5_c_decrypt(bsd_context, keyblock, KCMD_KEYUSAGE, + use_ivecs ? encivec_i + secondary : 0, &cipher, &plain)) { /* probably out of sync */ errno = EIO; @@ -911,6 +981,19 @@ static int v5_des_read(fd, buf, len) } store_ptr = storage; nstored = rd_len; + if (use_ivecs) { + int rd_len2; + rd_len2 = storage[0] & 0xff; + rd_len2 <<= 8; rd_len2 |= storage[1] & 0xff; + rd_len2 <<= 8; rd_len2 |= storage[2] & 0xff; + rd_len2 <<= 8; rd_len2 |= storage[3] & 0xff; + if (rd_len2 != rd_len) { + /* cleartext length trashed? */ + errno = EIO; + return -1; + } + store_ptr += 4; + } if (nstored > len) { memcpy(buf, store_ptr, len); nreturned += len; @@ -927,23 +1010,39 @@ static int v5_des_read(fd, buf, len) -static int v5_des_write(fd, buf, len) +static int v5_des_write(fd, buf, len, secondary) int fd; char *buf; int len; + int secondary; { - unsigned char *len_buf = (unsigned char *) des_outpkt; krb5_data plain; krb5_enc_data cipher; - - plain.data = buf; - plain.length = len; + char tmpbuf[2*RCMD_BUFSIZ+8]; + unsigned char *len_buf = (unsigned char *) tmpbuf; + + if (use_ivecs) { + unsigned char *lenbuf2 = (unsigned char *) tmpbuf; + if (len + 4 > sizeof(tmpbuf)) + abort (); + lenbuf2[0] = (len & 0xff000000) >> 24; + lenbuf2[1] = (len & 0xff0000) >> 16; + lenbuf2[2] = (len & 0xff00) >> 8; + lenbuf2[3] = (len & 0xff); + memcpy (tmpbuf + 4, buf, len); + + plain.data = tmpbuf; + plain.length = len + 4; + } else { + plain.data = buf; + plain.length = len; + } cipher.ciphertext.length = sizeof(des_outpkt)-4; cipher.ciphertext.data = desoutbuf.data; if (krb5_c_encrypt(bsd_context, keyblock, KCMD_KEYUSAGE, - encivec.length?&encivec:0, + use_ivecs ? encivec_o + secondary : 0, &plain, &cipher)) { errno = EIO; return(-1); @@ -951,6 +1050,7 @@ static int v5_des_write(fd, buf, len) desoutbuf.length = cipher.ciphertext.length; + len_buf = (unsigned char *) des_outpkt; len_buf[0] = (len & 0xff000000) >> 24; len_buf[1] = (len & 0xff0000) >> 16; len_buf[2] = (len & 0xff00) >> 8; @@ -1032,11 +1132,11 @@ int len; errno = EIO; return(-1); } - (void) pcbc_encrypt(des_inbuf, - storage, + (void) pcbc_encrypt((des_cblock *) des_inbuf, + (des_cblock *) storage, (net_len < 8) ? 8 : net_len, v4_schedule, - v4_session, + &v4_session, DECRYPT); /* * when the cleartext block is < 8 bytes, it is "right-justified" @@ -1092,11 +1192,11 @@ int len; /* this "right-justifies" the data in the buffer */ (void) memcpy(garbage_buf + 8 - len, buf, len); } - (void) pcbc_encrypt((len < 8) ? garbage_buf : buf, - des_outpkt+4, + (void) pcbc_encrypt((des_cblock *) ((len < 8) ? garbage_buf : buf), + (des_cblock *) (des_outpkt+4), (len < 8) ? 8 : len, v4_schedule, - v4_session, + &v4_session, ENCRYPT); /* tell the other end the real amount, but send an 8-byte padded diff --git a/src/appl/bsd/krcp.c b/src/appl/bsd/krcp.c index 9670145..7292e72 100644 --- a/src/appl/bsd/krcp.c +++ b/src/appl/bsd/krcp.c @@ -71,6 +71,8 @@ char copyright[] = #include <k5-util.h> #include <com_err.h> +#include "defines.h" + #define RCP_BUFSIZ 4096 int sock; @@ -131,7 +133,7 @@ void error KRB5_STDARG_P((char *fmt, ...)); void error KRB5_STDARG_P((char *, va_list)); #endif -#define ga() (void) rcmd_stream_write(rem, "", 1) +#define ga() (void) rcmd_stream_write(rem, "", 1, 0) int main(argc, argv) int argc; @@ -153,6 +155,8 @@ int main(argc, argv) krb5_error_code status; int euid; char **orig_argv = save_argv(argc, argv); + krb5_auth_context auth_context; + enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK; status = krb5_init_context(&bsd_context); if (status) { @@ -224,6 +228,14 @@ int main(argc, argv) } strcpy(krb_config, *argv); goto next_arg; + case 'P': + if (!strcmp (*argv, "O")) + kcmd_proto = KCMD_OLD_PROTOCOL; + else if (!strcmp (*argv, "N")) + kcmd_proto = KCMD_NEW_PROTOCOL; + else + usage (); + goto next_arg; #endif /* KERBEROS */ /* The rest of these are not for users. */ case 'd': @@ -376,20 +388,22 @@ int main(argc, argv) suser = pwd->pw_name; else if (!okname(suser)) continue; + (void) sprintf(buf, #if defined(hpux) || defined(__hpux) - (void) sprintf(buf, "remsh %s -l %s -n %s %s '%s%s%s:%s'", + "remsh %s -l %s -n %s %s '%s%s%s:%s'", #else - (void) sprintf(buf, "rsh %s -l %s -n %s %s '%s%s%s:%s'", + "rsh %s -l %s -n %s %s '%s%s%s:%s'", #endif host, suser, cmd, src, tuser ? tuser : "", tuser ? "@" : "", thost, targ); } else + (void) sprintf(buf, #if defined(hpux) || defined(__hpux) - (void) sprintf(buf, "remsh %s -n %s %s '%s%s%s:%s'", + "remsh %s -n %s %s '%s%s%s:%s'", #else - (void) sprintf(buf, "rsh %s -n %s %s '%s%s%s:%s'", + "rsh %s -n %s %s '%s%s%s:%s'", #endif argv[i], cmd, src, tuser ? tuser : "", @@ -397,7 +411,7 @@ int main(argc, argv) thost, targ); (void) susystem(buf); } else { /* local to remote */ -krb5_creds *cred; + krb5_creds *cred; if (rem == -1) { (void) sprintf(buf, "%s -t %s", cmd, targ); @@ -418,10 +432,14 @@ krb5_creds *cred; 0, /* No server seq # */ &local, &foreign, - authopts, + &auth_context, authopts, 0, /* Not any port # */ - 0); + 0, + &kcmd_proto); if (status) { + if (kcmd_proto == KCMD_NEW_PROTOCOL) + /* Don't fall back to less safe methods. */ + exit (1); #ifdef KRB5_KRB4_COMPAT fprintf(stderr, "Trying krb4 rcp...\n"); if (strncmp(buf, "-x rcp", 6) == 0) @@ -442,8 +460,29 @@ krb5_creds *cred; try_normal(orig_argv); #endif } - else - rcmd_stream_init_krb5(&cred->keyblock, encryptflag, 0); + else { + krb5_boolean similar; + krb5_keyblock *key = &cred->keyblock; + + if (status = krb5_c_enctype_compare(bsd_context, + ENCTYPE_DES_CBC_CRC, + cred->keyblock.enctype, + &similar)) + try_normal(orig_argv); /* doesn't return */ + + if (!similar) { + status = krb5_auth_con_getlocalsubkey (bsd_context, + auth_context, + &key); + if ((status || !key) && encryptflag) + try_normal(orig_argv); + } + if (key == 0) + key = &cred->keyblock; + + rcmd_stream_init_krb5(key, encryptflag, 0, 1, + kcmd_proto); + } rem = sock; #else rem = rcmd(&host, port, pwd->pw_name, @@ -521,10 +560,14 @@ krb5_creds *cred; 0, /* No server seq # */ (struct sockaddr_in *) 0, &foreign, - authopts, + &auth_context, authopts, 0, /* Not any port # */ - 0); + 0, + &kcmd_proto); if (status) { + if (kcmd_proto == KCMD_NEW_PROTOCOL) + /* Don't fall back to less safe methods. */ + exit (1); #ifdef KRB5_KRB4_COMPAT fprintf(stderr, "Trying krb4 rcp...\n"); if (strncmp(buf, "-x rcp", 6) == 0) @@ -543,8 +586,27 @@ krb5_creds *cred; #else try_normal(orig_argv); #endif - } else - rcmd_stream_init_krb5(&cred->keyblock, encryptflag, 0); + } else { + krb5_keyblock *key = &cred->keyblock; + + if (kcmd_proto == KCMD_NEW_PROTOCOL) { + status = krb5_auth_con_getlocalsubkey (bsd_context, + auth_context, + &key); + if (status) { + com_err (argv[0], status, + "determining subkey for session"); + exit (1); + } + if (!key) { + com_err (argv[0], 0, + "no subkey negotiated for connection"); + exit (1); + } + } + + rcmd_stream_init_krb5(key, encryptflag, 0, 1, kcmd_proto); + } rem = sock; euid = geteuid(); @@ -741,7 +803,7 @@ void source(argc, argv) */ (void) sprintf(buf, "T%ld 0 %ld 0\n", stb.st_mtime, stb.st_atime); - (void) rcmd_stream_write(rem, buf, strlen(buf)); + (void) rcmd_stream_write(rem, buf, strlen(buf), 0); if (response() < 0) { (void) close(f); continue; @@ -749,7 +811,7 @@ void source(argc, argv) } (void) sprintf(buf, "C%04o %ld %s\n", (int) stb.st_mode&07777, (long ) stb.st_size, last); - (void) rcmd_stream_write(rem, buf, strlen(buf)); + (void) rcmd_stream_write(rem, buf, strlen(buf), 0); if (response() < 0) { (void) close(f); continue; @@ -765,7 +827,7 @@ void source(argc, argv) amt = stb.st_size - i; if (readerr == 0 && read(f, bp->buf, amt) != amt) readerr = errno; - (void) rcmd_stream_write(rem, bp->buf, amt); + (void) rcmd_stream_write(rem, bp->buf, amt, 0); } (void) close(f); if (readerr == 0) @@ -810,14 +872,14 @@ void rsource(name, statp) if (pflag) { (void) sprintf(buf, "T%ld 0 %ld 0\n", statp->st_mtime, statp->st_atime); - (void) rcmd_stream_write(rem, buf, strlen(buf)); + (void) rcmd_stream_write(rem, buf, strlen(buf), 0); if (response() < 0) { closedir(d); return; } } (void) sprintf(buf, "D%04o %d %s\n", statp->st_mode&07777, 0, last); - (void) rcmd_stream_write(rem, buf, strlen(buf)); + (void) rcmd_stream_write(rem, buf, strlen(buf), 0); if (response() < 0) { closedir(d); return; @@ -836,7 +898,7 @@ void rsource(name, statp) source(1, bufv); } closedir(d); - (void) rcmd_stream_write(rem, "E\n", 2); + (void) rcmd_stream_write(rem, "E\n", 2, 0); (void) response(); } @@ -845,7 +907,7 @@ void rsource(name, statp) int response() { char resp, c, rbuf[RCP_BUFSIZ], *cp = rbuf; - if (rcmd_stream_read(rem, &resp, 1) != 1) + if (rcmd_stream_read(rem, &resp, 1, 0) != 1) lostconn(); switch (resp) { @@ -858,7 +920,7 @@ int response() case 1: /* error, followed by err msg */ case 2: /* fatal error, "" */ do { - if (rcmd_stream_read(rem, &c, 1) != 1) + if (rcmd_stream_read(rem, &c, 1, 0) != 1) lostconn(); *cp++ = c; } while (cp < &rbuf[RCP_BUFSIZ] && c != '\n'); @@ -941,12 +1003,12 @@ void sink(argc, argv) targisdir = 1; for (first = 1; ; first = 0) { cp = cmdbuf; - if (rcmd_stream_read(rem, cp, 1) <= 0) + if (rcmd_stream_read(rem, cp, 1, 0) <= 0) return; if (*cp++ == '\n') SCREWUP("unexpected '\\n'"); do { - if (rcmd_stream_read(rem, cp, 1) != 1) + if (rcmd_stream_read(rem, cp, 1, 0) != 1) SCREWUP("lost connection"); } while (*cp++ != '\n'); *cp = 0; @@ -1012,11 +1074,17 @@ void sink(argc, argv) size = size * 10 + (*cp++ - '0'); if (*cp++ != ' ') SCREWUP("size not delimited"); - if (targisdir) + if (targisdir) { + if(strlen(targ) + strlen(cp) + 2 >= sizeof(nambuf)) + SCREWUP("target name too long"); (void) sprintf(nambuf, "%s%s%s", targ, *targ ? "/" : "", cp); - else - (void) strcpy(nambuf, targ); + } else { + if (strlen(targ) + 1 >= sizeof (nambuf)) + SCREWUP("target name too long"); + (void) strncpy(nambuf, targ, sizeof(nambuf) - 1); + } + nambuf[sizeof(nambuf) - 1] = '\0'; exists = stat(nambuf, &stb) == 0; if (cmdbuf[0] == 'D') { if (exists) { @@ -1064,7 +1132,7 @@ void sink(argc, argv) amt = size - i; count += amt; do { - j = rcmd_stream_read(rem, cp, amt); + j = rcmd_stream_read(rem, cp, amt, 0); if (j <= 0) { if (j == 0) error("rcp: dropped connection"); @@ -1159,7 +1227,7 @@ error(fmt, va_alist) va_end(ap); if (iamremote) - (void) rcmd_stream_write(rem, buf, strlen(buf)); + (void) rcmd_stream_write(rem, buf, strlen(buf), 0); else (void) write(2, buf+1, strlen(buf+1)); } @@ -1170,7 +1238,7 @@ void usage() { #ifdef KERBEROS fprintf(stderr, - "Usage: \trcp [-p] [-x] [-k realm] f1 f2; or:\n\trcp [-r] [-p] [-x] [-k realm] f1 ... fn d2\n"); + "Usage: \trcp [-PN | -PO] [-p] [-x] [-k realm] f1 f2; or:\n\trcp [-PN | -PO] [-r] [-p] [-x] [-k realm] f1 ... fn d2\n"); #else fputs("usage: rcp [-p] f1 f2; or: rcp [-rp] f1 ... fn d2\n", stderr); #endif @@ -1315,7 +1383,8 @@ void exit(1); } - rcmd_stream_init_krb5(&new_creds->keyblock, encryptflag, 0); + rcmd_stream_init_krb5(&new_creds->keyblock, encryptflag, 0, 0, + KCMD_OLD_PROTOCOL); /* cleanup */ krb5_free_cred_contents(bsd_context, &creds); diff --git a/src/appl/bsd/krlogin.c b/src/appl/bsd/krlogin.c index da4a889..0039056 100644 --- a/src/appl/bsd/krlogin.c +++ b/src/appl/bsd/krlogin.c @@ -177,6 +177,7 @@ int fflag = 0, Fflag = 0; krb5_creds *cred; struct sockaddr_in local, foreign; krb5_context bsd_context; +krb5_auth_context auth_context; #ifdef KRB5_KRB4_COMPAT Key_schedule v4_schedule; @@ -377,6 +378,7 @@ main(argc, argv) #endif #endif int port, debug_port = 0; + enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK; memset(&defaultservent, 0, sizeof(struct servent)); if (strrchr(argv[0], '/')) @@ -502,6 +504,16 @@ main(argc, argv) argv++, argc--; goto another; } + if (argc > 0 && !strcmp(*argv, "-PO")) { + kcmd_proto = KCMD_OLD_PROTOCOL; + argv++, argc--; + goto another; + } + if (argc > 0 && !strcmp(*argv, "-PN")) { + kcmd_proto = KCMD_NEW_PROTOCOL; + argv++, argc--; + goto another; + } #endif /* KERBEROS */ if (host == 0) goto usage; @@ -559,7 +571,8 @@ main(argc, argv) if (tcgetattr(0, &ttyb) == 0) { int ospeed = cfgetospeed (&ttyb); - (void) strcat(term, "/"); + term[sizeof(term) - 1] = '\0'; + (void) strncat(term, "/", sizeof(term) - 1 - strlen(term)); if (ospeed >= 50) /* On some systems, ospeed is the baud rate itself, not a table index. */ @@ -567,15 +580,16 @@ main(argc, argv) else if (ospeed >= sizeof(speeds)/sizeof(char*)) /* Past end of table, but not high enough to look like a real speed. */ - (void) strcat (term, speeds[sizeof(speeds)/sizeof(char*) - 1]); + (void) strncat (term, speeds[sizeof(speeds)/sizeof(char*) - 1], sizeof(term) - 1 - strlen(term)); else { - (void) strcat(term, speeds[ospeed]); + (void) strncat(term, speeds[ospeed], sizeof(term) - 1 - strlen(term)); } + term[sizeof (term) - 1] = '\0'; } #else if (ioctl(0, TIOCGETP, &ttyb) == 0) { - (void) strcat(term, "/"); - (void) strcat(term, speeds[ttyb.sg_ospeed]); + (void) strncat(term, "/", sizeof(term) - 1 - strlen(term)); + (void) strncat(term, speeds[ttyb.sg_ospeed], sizeof(term) - 1 - strlen(term)); } #endif (void) get_window_size(0, &winsize); @@ -631,10 +645,14 @@ main(argc, argv) 0, /* No need for sequence number */ 0, /* No need for server seq # */ &local, &foreign, - authopts, + &auth_context, authopts, 0, /* Not any port # */ - 0); + 0, + &kcmd_proto); if (status) { + if (kcmd_proto == KCMD_NEW_PROTOCOL && encrypt_flag) + /* Don't fall back to something less secure. */ + exit (1); #ifdef KRB5_KRB4_COMPAT fprintf(stderr, "Trying krb4 rlogin...\n"); status = k4cmd(&sock, &host, port, @@ -650,19 +668,20 @@ main(argc, argv) try_normal(orig_argv); #endif } else { - krb5_boolean similar; - - rcmd_stream_init_krb5(&cred->keyblock, encrypt_flag, 1); - - if (status = krb5_c_enctype_compare(bsd_context, ENCTYPE_DES_CBC_CRC, - cred->keyblock.enctype, &similar)) - try_normal(orig_argv); /* doesn't return */ + krb5_keyblock *key = 0; - if (!similar) { + if (kcmd_proto == KCMD_NEW_PROTOCOL) { do_inband = 1; - if (debug_port) - fprintf(stderr, "DEBUG: setting do_inband\n"); + + status = krb5_auth_con_getlocalsubkey (bsd_context, auth_context, + &key); + if ((status || !key) && encrypt_flag) + try_normal(orig_argv); } + if (key == 0) + key = &cred->keyblock; + + rcmd_stream_init_krb5(key, encrypt_flag, 1, 1, kcmd_proto); } rem = sock; @@ -1122,9 +1141,9 @@ writer() #endif if (c != cmdchar) - (void) rcmd_stream_write(rem, &cmdchar, 1); + (void) rcmd_stream_write(rem, &cmdchar, 1, 0); } - if (rcmd_stream_write(rem, &c, 1) == 0) { + if (rcmd_stream_write(rem, &c, 1, 0) == 0) { prf("line gone"); break; } @@ -1239,7 +1258,7 @@ sendwindow() wp->ws_col = htons(winsize.ws_col); wp->ws_xpixel = htons(winsize.ws_xpixel); wp->ws_ypixel = htons(winsize.ws_ypixel); - (void) rcmd_stream_write(rem, obuf, sizeof(obuf)); + (void) rcmd_stream_write(rem, obuf, sizeof(obuf), 0); } @@ -1458,7 +1477,7 @@ fd_set readset, excset, writeset; bufp += n; } if (FD_ISSET(rem, &readset)) { - rcvcnt = rcmd_stream_read(rem, rcvbuf, sizeof (rcvbuf)); + rcvcnt = rcmd_stream_read(rem, rcvbuf, sizeof (rcvbuf), 0); if (rcvcnt == 0) return (0); if (rcvcnt < 0) diff --git a/src/appl/bsd/krlogind.c b/src/appl/bsd/krlogind.c index e37b84c..65958e9 100644 --- a/src/appl/bsd/krlogind.c +++ b/src/appl/bsd/krlogind.c @@ -250,6 +250,7 @@ AUTH_DAT *v4_kdata; Key_schedule v4_schedule; #include "com_err.h" +#include "defines.h" #define SECURE_MESSAGE "This rlogin session is using DES encryption for all data transmissions.\r\n" @@ -850,7 +851,7 @@ void doit(f, fromp) #if defined(KERBEROS) if (do_encrypt) { - if (rcmd_stream_write(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE)) < 0){ + if (rcmd_stream_write(f, SECURE_MESSAGE, sizeof(SECURE_MESSAGE), 0) < 0){ sprintf(buferror, "Cannot encrypt-write network."); fatal(p,buferror); } @@ -918,11 +919,11 @@ int sendoob(fd, byte) message[3] = 'o'; message[4] = *byte; - cc = rcmd_stream_write(fd, message, sizeof(message)); + cc = rcmd_stream_write(fd, message, sizeof(message), 0); while (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { /* also shouldn't happen */ sleep(5); - cc = rcmd_stream_write(fd, message, sizeof(message)); + cc = rcmd_stream_write(fd, message, sizeof(message), 0); } } else { send(fd, byte, 1, MSG_OOB); @@ -1033,7 +1034,7 @@ void protocol(f, p) } #define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP)) if (FD_ISSET(f, &ibits)) { - fcc = rcmd_stream_read(f, fibuf, sizeof (fibuf)); + fcc = rcmd_stream_read(f, fibuf, sizeof (fibuf), 0); if (fcc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { fcc = 0; } else { @@ -1121,7 +1122,7 @@ void protocol(f, p) } if (FD_ISSET(f, &obits) && pcc > 0) { - cc = rcmd_stream_write(f, pbp, pcc); + cc = rcmd_stream_write(f, pbp, pcc, 0); if (cc < 0 && ((errno == EWOULDBLOCK) || (errno == EAGAIN))) { /* also shouldn't happen */ sleep(5); @@ -1160,7 +1161,7 @@ void fatal(f, msg) buf[0] = '\01'; /* error indicator */ (void) sprintf(buf + 1, "%s: %s.\r\n",progname, msg); if ((f == netf) && (pid > 0)) - (void) rcmd_stream_write(f, buf, strlen(buf)); + (void) rcmd_stream_write(f, buf, strlen(buf), 0); else (void) write(f, buf, strlen(buf)); syslog(LOG_ERR,"%s\n",msg); @@ -1377,9 +1378,11 @@ recvauth(valid_checksum) int len; krb5_data inbuf; char v4_instance[INST_SZ]; /* V4 Instance */ - char v4_version[9]; + krb5_data version; krb5_authenticator *authenticator; krb5_rcache rcache; + enum kcmd_proto kcmd_proto; + krb5_keyblock *key; *valid_checksum = 0; len = sizeof(laddr); @@ -1423,8 +1426,8 @@ recvauth(valid_checksum) if (status) return status; } - if ((status = krb5_compat_recvauth(bsd_context, &auth_context, &netf, - "KCMDV0.1", + if ((status = krb5_compat_recvauth_version(bsd_context, &auth_context, + &netf, NULL, /* Specify daemon principal */ 0, /* no flags */ keytab, /* normally NULL to use v5srvtab */ @@ -1438,8 +1441,8 @@ recvauth(valid_checksum) &ticket, /* return ticket */ &auth_sys, /* which authentication system*/ - &v4_kdata, v4_schedule, v4_version))) { - + &v4_kdata, v4_schedule, + &version))) { if (auth_sys == KRB5_RECVAUTH_V5) { /* * clean up before exiting @@ -1453,7 +1456,25 @@ recvauth(valid_checksum) getstr(netf, lusername, sizeof (lusername), "locuser"); getstr(netf, term, sizeof(term), "Terminal type"); - if ((auth_sys == KRB5_RECVAUTH_V5) && !checksum_ignored) { + + kcmd_proto = KCMD_UNKNOWN_PROTOCOL; + if (auth_sys == KRB5_RECVAUTH_V5) { + if (version.length != 9) { + fatal (netf, "bad application version length"); + } + if (!memcmp (version.data, "KCMDV0.1", 9)) + kcmd_proto = KCMD_OLD_PROTOCOL; + else if (!memcmp (version.data, "KCMDV0.2", 9)) + kcmd_proto = KCMD_NEW_PROTOCOL; + } +#ifdef KRB5_KRB4_COMPAT + if (auth_sys == KRB5_RECVAUTH_V4) + kcmd_proto = KCMD_V4_PROTOCOL; +#endif + + if ((auth_sys == KRB5_RECVAUTH_V5) + && !(checksum_ignored + && kcmd_proto == KCMD_OLD_PROTOCOL)) { if ((status = krb5_auth_con_getauthenticator(bsd_context, auth_context, &authenticator))) @@ -1500,7 +1521,8 @@ recvauth(valid_checksum) * Assume it to be the same as the first component of the * principal's name. */ - strcpy(rusername, v4_kdata->pname); + strncpy(rusername, v4_kdata->pname, sizeof(rusername) - 1); + rusername[sizeof(rusername) - 1] = '\0'; status = krb5_425_conv_principal(bsd_context, v4_kdata->pname, v4_kdata->pinst, v4_kdata->prealm, @@ -1519,22 +1541,20 @@ recvauth(valid_checksum) &client))) return status; - rcmd_stream_init_krb5(ticket->enc_part2->session, do_encrypt, 1); - - { - krb5_boolean similar; + key = 0; + status = krb5_auth_con_getremotesubkey (bsd_context, auth_context, &key); + if (status) + fatal (netf, "Server can't get session subkey"); + if (!key && do_encrypt && kcmd_proto == KCMD_NEW_PROTOCOL) + fatal (netf, "No session subkey sent"); + if (key && kcmd_proto == KCMD_OLD_PROTOCOL) + fatal (netf, "Session subkey not permitted under old kcmd protocol"); + if (key == 0) + key = ticket->enc_part2->session; - if (status = krb5_c_enctype_compare(bsd_context, ENCTYPE_DES_CBC_CRC, - ticket->enc_part2->session->enctype, - &similar)) - return(status); - - if (!similar) { - do_inband = 1; - syslog(LOG_DEBUG, "setting do_inband"); - } - } + rcmd_stream_init_krb5 (key, do_encrypt, 1, 0, kcmd_proto); + do_inband = (kcmd_proto == KCMD_NEW_PROTOCOL); getstr(netf, rusername, sizeof(rusername), "remuser"); diff --git a/src/appl/bsd/krsh.c b/src/appl/bsd/krsh.c index 9d602b2..c1741d8 100644 --- a/src/appl/bsd/krsh.c +++ b/src/appl/bsd/krsh.c @@ -93,8 +93,6 @@ krb5_sigtype sendsig(); #define UCB_RSH "/usr/ucb/rsh" #endif - - krb5_context bsd_context; krb5_creds *cred; @@ -137,7 +135,7 @@ main(argc, argv0) struct servent *sp; struct servent defaultservent; struct sockaddr_in local, foreign; - int suppress; + int suppress = 0; #ifdef POSIX_SIGNALS sigset_t omask, igmask; @@ -148,6 +146,7 @@ main(argc, argv0) #ifdef KERBEROS krb5_flags authopts; krb5_error_code status; + krb5_auth_context auth_context; int fflag = 0, Fflag = 0; #ifdef KRB5_KRB4_COMPAT KTEXT_ST v4_ticket; @@ -155,6 +154,7 @@ main(argc, argv0) #endif #endif /* KERBEROS */ int debug_port = 0; + enum kcmd_proto kcmd_proto = KCMD_PROTOCOL_COMPAT_HACK; memset(&defaultservent, 0, sizeof(struct servent)); if (strrchr(argv[0], '/')) @@ -239,6 +239,16 @@ main(argc, argv0) argv++, argc--; goto another; } + if (argc > 0 && !strcmp(*argv, "-PO")) { + argv++, argc--; + kcmd_proto = KCMD_OLD_PROTOCOL; + goto another; + } + if (argc > 0 && !strcmp(*argv, "-PN")) { + argv++, argc--; + kcmd_proto = KCMD_NEW_PROTOCOL; + goto another; + } #endif /* KERBEROS */ /* * Ignore the -L, -w, -e and -8 flags to allow aliases with rlogin @@ -367,10 +377,15 @@ main(argc, argv0) 0, /* No need for sequence number */ 0, /* No need for server seq # */ &local, &foreign, - authopts, + &auth_context, authopts, 1, /* Always set anyport, there is no need not to. --proven */ - suppress); + suppress, + &kcmd_proto); if (status) { + /* If new protocol requested, don't fall back to less secure + ones. */ + if (kcmd_proto == KCMD_NEW_PROTOCOL) + exit (1); #ifdef KRB5_KRB4_COMPAT /* No encrypted Kerberos 4 rsh. */ if (encrypt_flag) @@ -391,8 +406,24 @@ main(argc, argv0) #else try_normal(argv0); #endif - } else - rcmd_stream_init_krb5(&cred->keyblock, encrypt_flag, 0); + } else { + krb5_keyblock *key = &cred->keyblock; + + if (kcmd_proto == KCMD_NEW_PROTOCOL) { + status = krb5_auth_con_getlocalsubkey (bsd_context, auth_context, + &key); + if (status) { + com_err (argv[0], status, "determining subkey for session"); + exit (1); + } + if (!key) { + com_err (argv[0], 0, "no subkey negotiated for connection"); + exit (1); + } + } + + rcmd_stream_init_krb5(key, encrypt_flag, 0, 1, kcmd_proto); + } #ifdef HAVE_ISATTY if(encrypt_flag&&isatty(2)) { @@ -489,7 +520,7 @@ main(argc, argv0) } if (FD_ISSET(rem, &rembits) == 0) goto rewrite; - wc = rcmd_stream_write(rem, bp, cc); + wc = rcmd_stream_write(rem, bp, cc, 0); if (wc < 0) { if ((errno == EWOULDBLOCK) || (errno == EAGAIN)) goto rewrite; @@ -524,7 +555,7 @@ main(argc, argv0) } if (FD_ISSET(rfd2, &ready)) { errno = 0; - cc = rcmd_stream_read(rfd2, buf, sizeof buf); + cc = rcmd_stream_read(rfd2, buf, sizeof buf, 1); if (cc <= 0) { if ((errno != EWOULDBLOCK) && (errno != EAGAIN)) FD_CLR(rfd2, &readfrom); @@ -533,7 +564,7 @@ main(argc, argv0) } if (FD_ISSET(rem, &ready)) { errno = 0; - cc = rcmd_stream_read(rem, buf, sizeof buf); + cc = rcmd_stream_read(rem, buf, sizeof buf, 0); if (cc <= 0) { if ((errno != EWOULDBLOCK) && (errno != EAGAIN)) FD_CLR(rem, &readfrom); @@ -546,9 +577,9 @@ main(argc, argv0) exit(0); usage: fprintf(stderr, - "usage: \trsh host [ -l login ] [ -n ] [ -x ] [ -f / -F] command\n"); + "usage: \trsh host [ -PN / -PO ] [ -l login ] [ -n ] [ -x ] [ -f / -F] command\n"); fprintf(stderr, - "OR \trsh [ -l login ] [-n ] [ -x ] [ -f / -F ] host command\n"); + "OR \trsh [ -PN / -PO ] [ -l login ] [-n ] [ -x ] [ -f / -F ] host command\n"); exit(1); } @@ -557,7 +588,7 @@ main(argc, argv0) krb5_sigtype sendsig(signo) char signo; { - (void) rcmd_stream_write(rfd2, &signo, 1); + (void) rcmd_stream_write(rfd2, &signo, 1, 1); } diff --git a/src/appl/bsd/krshd.c b/src/appl/bsd/krshd.c index 3844087..929f736 100644 --- a/src/appl/bsd/krshd.c +++ b/src/appl/bsd/krshd.c @@ -48,8 +48,8 @@ char copyright[] = * or by the name of the daemon. If command-line arguments are present, they * take priority. The options are: * -k means trust krb4 or krb5 -* -5 means trust krb5 -* -4 means trust krb4 (using .klogin) + * -5 means trust krb5 + * -4 means trust krb4 (using .klogin) * */ @@ -73,9 +73,7 @@ char copyright[] = #define SERVE_NON_KRB #define LOG_REMOTE_REALM #define LOG_CMD -#include "defines.h" - #ifdef HAVE_UNISTD_H #include <unistd.h> #endif @@ -162,6 +160,8 @@ char copyright[] = Key_schedule v4_schedule; #endif +#include "defines.h" + #if HAVE_ARPA_NAMESER_H #include <arpa/nameser.h> #endif @@ -1245,7 +1245,7 @@ if(port) shutdown(s, 1+1); FD_CLR(pv[0], &readfrom); } else { - (void) rcmd_stream_write(s, buf, cc); + (void) rcmd_stream_write(s, buf, cc, 1); } } if (FD_ISSET(pw[0], &ready)) { @@ -1256,12 +1256,12 @@ if(port) shutdown(f, 1+1); FD_CLR(pw[0], &readfrom); } else { - (void) rcmd_stream_write(f, buf, cc); + (void) rcmd_stream_write(f, buf, cc, 0); } } if (port&&FD_ISSET(s, &ready)) { /* read from the alternate channel, signal the child */ - if (rcmd_stream_read(s, &sig, 1) <= 0) { + if (rcmd_stream_read(s, &sig, 1, 1) <= 0) { FD_CLR(s, &readfrom); } else { #ifdef POSIX_SIGNALS @@ -1277,7 +1277,7 @@ if(port) if (FD_ISSET(f, &ready)) { /* read from the net, write to child stdin */ errno = 0; - cc = rcmd_stream_read(f, buf, sizeof(buf)); + cc = rcmd_stream_read(f, buf, sizeof(buf), 0); if (cc <= 0) { (void) close(px[1]); FD_CLR(f, &readfrom); @@ -1468,15 +1468,16 @@ if(port) strcpy((char *) cmdbuf + offst, kprogdir); cp = copy + 3 + offst; + cmdbuf[sizeof(cmdbuf) - 1] = '\0'; if (auth_sys == KRB5_RECVAUTH_V4) { - strcat(cmdbuf, "/v4rcp"); + strncat(cmdbuf, "/v4rcp", sizeof(cmdbuf) - 1 - strlen(cmdbuf)); } else { - strcat(cmdbuf, "/rcp"); + strncat(cmdbuf, "/rcp", sizeof(cmdbuf) - 1 - strlen(cmdbuf)); } if (stat((char *)cmdbuf + offst, &s) >= 0) - strcat(cmdbuf, cp); + strncat(cmdbuf, cp, sizeof(cmdbuf) - 1 - strlen(cmdbuf)); else - strcpy(cmdbuf, copy); + strncpy(cmdbuf, copy, sizeof(cmdbuf) - 1 - strlen(cmdbuf)); free(copy); } #endif @@ -1775,7 +1776,6 @@ recvauth(netf, peersin, valid_checksum) krb5_data inbuf; #ifdef KRB5_KRB4_COMPAT char v4_instance[INST_SZ]; /* V4 Instance */ - char v4_version[9]; #endif krb5_authenticator *authenticator; krb5_ticket *ticket; @@ -1783,6 +1783,8 @@ recvauth(netf, peersin, valid_checksum) struct passwd *pwd; uid_t uid; gid_t gid; + enum kcmd_proto kcmd_proto; + krb5_data version; *valid_checksum = 0; len = sizeof(laddr); @@ -1828,8 +1830,7 @@ recvauth(netf, peersin, valid_checksum) } #ifdef KRB5_KRB4_COMPAT - status = krb5_compat_recvauth(bsd_context, &auth_context, &netf, - "KCMDV0.1", + status = krb5_compat_recvauth_version(bsd_context, &auth_context, &netf, NULL, /* Specify daemon principal */ 0, /* no flags */ keytab, /* normally NULL to use v5srvtab */ @@ -1842,14 +1843,14 @@ recvauth(netf, peersin, valid_checksum) &ticket, /* return ticket */ &auth_sys, /* which authentication system*/ - &v4_kdata, 0, v4_version); + &v4_kdata, 0, &version); #else status = krb5_recvauth(bsd_context, &auth_context, &netf, - "KCMDV0.1", NULL, /* daemon principal */ 0, /* no flags */ keytab, /* normally NULL to use v5srvtab */ - &ticket); /* return ticket */ + &ticket, /* return ticket */ + &version); /* application version string */ auth_sys = KRB5_RECVAUTH_V5; #endif @@ -1891,6 +1892,14 @@ recvauth(netf, peersin, valid_checksum) /* Must be V5 */ + kcmd_proto = KCMD_UNKNOWN_PROTOCOL; + if (version.length != 9) + fatal (netf, "bad application version length"); + if (!memcmp (version.data, "KCMDV0.1", 9)) + kcmd_proto = KCMD_OLD_PROTOCOL; + if (!memcmp (version.data, "KCMDV0.2", 9)) + kcmd_proto = KCMD_NEW_PROTOCOL; + getstr(netf, remuser, sizeof(locuser), "remuser"); if ((status = krb5_unparse_name(bsd_context, ticket->enc_part2->client, @@ -1939,7 +1948,21 @@ recvauth(netf, peersin, valid_checksum) if (!strncmp(cmdbuf, "-x ", 3)) do_encrypt = 1; - rcmd_stream_init_krb5(ticket->enc_part2->session, do_encrypt, 0); + + { + krb5_keyblock *key; + status = krb5_auth_con_getremotesubkey (bsd_context, auth_context, + &key); + if (status) + fatal (netf, "Server can't get session subkey"); + if (!key && do_encrypt && kcmd_proto == KCMD_NEW_PROTOCOL) + fatal (netf, "No session subkey sent"); + if (key && kcmd_proto == KCMD_OLD_PROTOCOL) + fatal (netf, "Session subkey not allowed in old kcmd protocol"); + if (key == 0) + key = ticket->enc_part2->session; + rcmd_stream_init_krb5 (key, do_encrypt, 0, 0, kcmd_proto); + } /* Null out the "session" because kcmd.c references the session * key here, and we do not want krb5_free_ticket() to destroy it. */ @@ -1990,7 +2013,7 @@ void fatal(f, msg) buf[0] = '\01'; /* error indicator */ (void) sprintf(buf + 1, "%s: %s.\r\n",progname, msg); if ((f == netf) && (pid > 0)) - (void) rcmd_stream_write(f, buf, strlen(buf)); + (void) rcmd_stream_write(f, buf, strlen(buf), 0); else (void) write(f, buf, strlen(buf)); syslog(LOG_ERR,"%s\n",msg); diff --git a/src/appl/bsd/login.c b/src/appl/bsd/login.c index 40af3ce..1d79064 100644 --- a/src/appl/bsd/login.c +++ b/src/appl/bsd/login.c @@ -913,8 +913,9 @@ afs_login () struct stat st; /* construct the name */ /* get this from profile later */ - strcpy (aklog_path, KPROGDIR); - strcat (aklog_path, "/aklog"); + aklog_path[sizeof(aklog_path) - 1] = '\0'; + strncpy (aklog_path, KPROGDIR, sizeof(aklog_path) - 1); + strncat (aklog_path, "/aklog", sizeof(aklog_path) - 1 - strlen(aklog_path)); /* only run it if we can find it */ if (stat (aklog_path, &st) == 0) { system(aklog_path); diff --git a/src/appl/bsd/v4rcp.c b/src/appl/bsd/v4rcp.c index 36754de..3267783 100644 --- a/src/appl/bsd/v4rcp.c +++ b/src/appl/bsd/v4rcp.c @@ -208,7 +208,7 @@ int kstream_read(krem, buf, len) /* decrypt it */ des_pcbc_encrypt ((des_cblock *)krem->retbuf, (des_cblock *)krem->retbuf, - sz, *krem->sched, *krem->ivec, + sz, *krem->sched, krem->ivec, DECRYPT); /* now retbuf has sz bytes, return len or x of them to the user */ @@ -265,7 +265,7 @@ int kstream_write(krem, buf, len) abort (); /* memset(outbuf+4+4, 0x42, BUFSIZ); */ st = des_pcbc_encrypt ((des_cblock *)buf, (des_cblock *)(krem->outbuf+4+4), outlen, - *krem->sched, *krem->ivec, ENCRYPT); + *krem->sched, krem->ivec, ENCRYPT); if (st) abort(); return write(krem->write_fd, krem->outbuf+4, 4+outlen); @@ -400,6 +400,7 @@ int main(argc, argv) if (argc == 0) usage(); strncpy(krb_realm,*argv,REALM_SZ); + krb_realm[REALM_SZ-1] = 0; sprintf(realmarg, " -k %s", krb_realm); goto next_arg; #endif /* KERBEROS */ @@ -782,11 +783,20 @@ void sink(argc, argv) size = size * 10 + (*cp++ - '0'); if (*cp++ != ' ') SCREWUP("size not delimited"); - if (targisdir) - (void) sprintf(nambuf, "%s%s%s", targ, - *targ ? "/" : "", cp); - else - (void) strcpy(nambuf, targ); + if (targisdir) { + if (strlen(targ) + strlen(cp) + 1 < sizeof(nambuf)) { + (void) sprintf(nambuf, "%s%s%s", targ, + *targ ? "/" : "", cp); + } else { + SCREWUP("target directory name too long"); + } + } else { + if (strlen(targ) + 1 < sizeof(nambuf)) + (void) strncpy(nambuf, targ, sizeof(nambuf)-1); + else + SCREWUP("target pathname too long"); + } + nambuf[sizeof(nambuf)-1] = '\0'; exists = stat(nambuf, &stb) == 0; if (cmdbuf[0] == 'D') { if (exists) { diff --git a/src/appl/gssftp/ChangeLog b/src/appl/gssftp/ChangeLog index 691a2e9..849c962 100644 --- a/src/appl/gssftp/ChangeLog +++ b/src/appl/gssftp/ChangeLog @@ -1,3 +1,8 @@ +2000-03-24 Ken Raeburn <raeburn@mit.edu> + + * configure.in: Check for alpha*-dec-osf* instead of + alpha-dec-osf*. + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/appl/gssftp/configure.in b/src/appl/gssftp/configure.in index f0c2bff..349cc04 100644 --- a/src/appl/gssftp/configure.in +++ b/src/appl/gssftp/configure.in @@ -67,7 +67,7 @@ else FTPD_LIBS="../../../krb524/libkrb524.a" fi case $krb5_cv_host in -alpha-dec-osf*) +alpha*-dec-osf*) AC_CHECK_LIB(security,setluid, AC_DEFINE(HAVE_SETLUID) FTPD_LIBS="$FTPD_LIBS -lsecurity" diff --git a/src/appl/gssftp/ftp/ChangeLog b/src/appl/gssftp/ftp/ChangeLog index 411aff7..b9db358 100644 --- a/src/appl/gssftp/ftp/ChangeLog +++ b/src/appl/gssftp/ftp/ChangeLog @@ -1,3 +1,20 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * domacro.c (domacro): Don't overflow "line2" + * ftp.c (getreply, krb4 compat): Bail if message data too big for buffer + (getreply, gssapi): Ditto. + (pswitch): Don't overflow "ntin", "ntout", "mapin", "mapout". + (do_auth, krb4 compat): Don't overflow "realm". + +2000-04-27 Nalin Dahyabhai <nalin@redhat.com> + + * cmds.c (remglob): Don't overflow buffer "temp". + (shell): Don't overflow buffer "shellnam". + (quote1): "buf" + * glob.c (ftpglob): Fix boundary in buffer "agpath". + (expand): Don't overflow buffer pointed to by "gpath". + (execbrc): Don't overflow buffer "restbuf". + 2000-02-18 Ken Raeburn <raeburn@mit.edu> * cmds.c (mls): Declare some variables volatile to protect against diff --git a/src/appl/gssftp/ftp/cmds.c b/src/appl/gssftp/ftp/cmds.c index 2a8e775..0006e4f 100644 --- a/src/appl/gssftp/ftp/cmds.c +++ b/src/appl/gssftp/ftp/cmds.c @@ -1049,7 +1049,8 @@ remglob(argv,doswitch) return (cp); } if (ftemp == NULL) { - (void) strcpy(temp, _PATH_TMP); + (void) strncpy(temp, _PATH_TMP, sizeof(temp) - 1); + temp[sizeof(temp) - 1] = '\0'; (void) mktemp(temp); oldverbose = verbose, verbose = 0; oldhash = hash, hash = 0; @@ -1510,7 +1511,8 @@ shell(argc, argv) if (namep == NULL) namep = shell; (void) strcpy(shellnam,"-"); - (void) strcat(shellnam, ++namep); + (void) strncat(shellnam, ++namep, sizeof(shellnam) - 1 - strlen(shellnam)); + shellnam[sizeof(shellnam) - 1] = '\0'; if (strcmp(namep, "sh") != 0) shellnam[0] = '+'; if (debug) { @@ -1702,13 +1704,14 @@ quote1(initial, argc, argv) register int i, len; char buf[FTP_BUFSIZ]; /* must be >= sizeof(line) */ - (void) strcpy(buf, initial); + (void) strncpy(buf, initial, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; if (argc > 1) { len = strlen(buf); - len += strlen(strcpy(&buf[len], argv[1])); + len += strlen(strncpy(&buf[len], argv[1], sizeof(buf) - 1 - len)); for (i = 2; i < argc; i++) { buf[len++] = ' '; - len += strlen(strcpy(&buf[len], argv[i])); + len += strlen(strncpy(&buf[len], argv[i], sizeof(buf) - 1 - len)); } } if (command(buf) == PRELIM) { diff --git a/src/appl/gssftp/ftp/domacro.c b/src/appl/gssftp/ftp/domacro.c index 9bc277b..ecfe9b4 100644 --- a/src/appl/gssftp/ftp/domacro.c +++ b/src/appl/gssftp/ftp/domacro.c @@ -71,7 +71,8 @@ domacro(argc, argv) code = -1; return; } - (void) strcpy(line2, line); + (void) strncpy(line2, line, sizeof(line2) - 1); + line2[sizeof(line2) - 1] = '\0'; TOP: cp1 = macros[i].mac_start; while (cp1 != macros[i].mac_end) { @@ -92,7 +93,11 @@ TOP: } cp1--; if (argc - 2 >= j) { - (void) strcpy(cp2, argv[j+1]); + if(cp2 + strlen(argv[j+1]) - line < sizeof(line)) + (void) strncpy(cp2, argv[j+1], + sizeof(line) - 1 - + (cp2 - line)); + line[sizeof(line) - 1] = '\0'; cp2 += strlen(argv[j+1]); } break; @@ -101,7 +106,11 @@ TOP: loopflg = 1; cp1++; if (count < argc) { - (void) strcpy(cp2, argv[count]); + if(cp2 + strlen(argv[j+1]) - line < sizeof(line)) + (void) strncpy(cp2, argv[count], + sizeof(line) - 1 - + (cp2 - line)); + line[sizeof(line) - 1] = '\0'; cp2 += strlen(argv[count]); } break; @@ -138,7 +147,8 @@ TOP: if (bell && c->c_bell) { (void) putchar('\007'); } - (void) strcpy(line, line2); + (void) strncpy(line, line2, sizeof(line) - 1); + line[sizeof(line) - 1] = '\0'; makeargv(); argc = margc; argv = margv; diff --git a/src/appl/gssftp/ftp/ftp.c b/src/appl/gssftp/ftp/ftp.c index 11f583a..a00850d 100644 --- a/src/appl/gssftp/ftp/ftp.c +++ b/src/appl/gssftp/ftp/ftp.c @@ -680,9 +680,13 @@ getreply(expecteof) n = '5'; } else { if (debug) printf("%c:", safe ? 'S' : 'P'); - memcpy(ibuf, msg_data.app_data, - msg_data.app_length); - strcpy(&ibuf[msg_data.app_length], "\r\n"); + if(msg_data.app_length < sizeof(ibuf) - 2) { + memcpy(ibuf, msg_data.app_data, + msg_data.app_length); + strcpy(&ibuf[msg_data.app_length], "\r\n"); + } else { + printf("Message too long!"); + } continue; } #endif @@ -703,9 +707,14 @@ getreply(expecteof) "failed unsealing reply"); n = '5'; } else { - memcpy(ibuf, msg_buf.value, - msg_buf.length); - strcpy(&ibuf[msg_buf.length], "\r\n"); + if(msg_buf.length < sizeof(ibuf) - 2 - 1) { + memcpy(ibuf, msg_buf.value, + msg_buf.length); + strcpy(&ibuf[msg_buf.length], "\r\n"); + } else { + user_gss_error(maj_stat, min_stat, + "reply was too long"); + } gss_release_buffer(&min_stat,&msg_buf); continue; } @@ -1636,20 +1645,24 @@ pswitch(flag) mcase = op->mcse; ip->ntflg = ntflag; ntflag = op->ntflg; - (void) strncpy(ip->nti, ntin, 16); + (void) strncpy(ip->nti, ntin, sizeof(ip->nti) - 1); (ip->nti)[strlen(ip->nti)] = '\0'; - (void) strcpy(ntin, op->nti); - (void) strncpy(ip->nto, ntout, 16); + (void) strncpy(ntin, op->nti, sizeof(ntin) - 1); + ntin[sizeof(ntin) - 1] = '\0'; + (void) strncpy(ip->nto, ntout, sizeof(ip->nto) - 1); (ip->nto)[strlen(ip->nto)] = '\0'; - (void) strcpy(ntout, op->nto); + (void) strncpy(ntout, op->nto, sizeof(ntout) - 1); + ntout[sizeof(ntout) - 1] = '\0'; ip->mapflg = mapflag; mapflag = op->mapflg; (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1); (ip->mi)[strlen(ip->mi)] = '\0'; - (void) strcpy(mapin, op->mi); + (void) strncpy(mapin, op->mi, sizeof(mapin) - 1); + mapin[sizeof(mapin) - 1] = '\0'; (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1); (ip->mo)[strlen(ip->mo)] = '\0'; - (void) strcpy(mapout, op->mo); + (void) strncpy(mapout, op->mo, sizeof(mapout) - 1); + mapout[sizeof(mapout) - 1] = '\0'; ip->authtype = auth_type; auth_type = op->authtype; ip->clvl = clevel; @@ -1846,7 +1859,8 @@ gunique(local) fprintf(stderr, "local: %s: %s\n", local, strerror(errno)); return((char *) 0); } - (void) strcpy(new, local); + (void) strncpy(new, local, sizeof(new) - 3); + new[sizeof(new) - 1] = '\0'; cp = new + strlen(new); *cp++ = '.'; while (!d) { @@ -2054,9 +2068,11 @@ do_auth() if (verbose) printf("%s accepted as authentication type\n", "KERBEROS_V4"); - strcpy(inst, (char *) krb_get_phost(hostname)); + strncpy(inst, (char *) krb_get_phost(hostname), sizeof(inst) - 1); + inst[sizeof(inst) - 1] = '\0'; if (realm[0] == '\0') - strcpy(realm, (char *) krb_realmofhost(hostname)); + strncpy(realm, (char *) krb_realmofhost(hostname), sizeof(realm) - 1); + realm[sizeof(realm) - 1] = '\0'; if ((kerror = krb_mk_req(&ticket, service = "ftp", inst, realm, checksum)) && (kerror != KDC_PR_UNKNOWN || diff --git a/src/appl/gssftp/ftp/glob.c b/src/appl/gssftp/ftp/glob.c index f92ee5e..a5a6bf7 100644 --- a/src/appl/gssftp/ftp/glob.c +++ b/src/appl/gssftp/ftp/glob.c @@ -118,7 +118,7 @@ ftpglob(v) globerr = 0; gpath = agpath; gpathp = gpath; *gpathp = 0; - lastgpathp = &gpath[sizeof agpath - 2]; + lastgpathp = &gpath[sizeof(agpath) - 1]; ginit(agargv); globcnt = 0; collect(v); if (globcnt == 0 && (gflag&1)) { @@ -198,7 +198,8 @@ expand(as) globerr = "Unknown user name after ~"; (void) strcpy(gpath, gpath + 1); } else - (void) strcpy(gpath, home); + (void) strncpy(gpath, home, FTP_BUFSIZ - 1); + gpath[FTP_BUFSIZ - 1] = '\0'; gpathp = strend(gpath); } } @@ -324,8 +325,9 @@ pend: doit: savec = *pm; *pm = 0; - (void) strcpy(lm, pl); - (void) strcat(restbuf, pe + 1); + (void) strncpy(lm, pl, sizeof(restbuf) - 1 - (lm - restbuf)); + restbuf[sizeof(restbuf) - 1] = '\0'; + (void) strncat(restbuf, pe + 1, sizeof(restbuf) - 1 - strlen(restbuf)); *pm = savec; if (s == 0) { sgpathp = gpathp; @@ -700,7 +702,7 @@ gethdir(home) { register struct passwd *pp = getpwnam(home); - if (!pp || home + strlen(pp->pw_dir) >= lastgpathp) + if (!pp || ((home + strlen(pp->pw_dir)) >= lastgpathp)) return (1); (void) strcpy(home, pp->pw_dir); return (0); diff --git a/src/appl/gssftp/ftp/main.c b/src/appl/gssftp/ftp/main.c index 9c1e43a..6c7e1e9 100644 --- a/src/appl/gssftp/ftp/main.c +++ b/src/appl/gssftp/ftp/main.c @@ -193,7 +193,8 @@ main(argc, argv) pw = getpwuid(getuid()); if (pw != NULL) { home = homedir; - (void) strcpy(home, pw->pw_dir); + (void) strncpy(home, pw->pw_dir, sizeof(homedir) - 1); + homedir[sizeof(homedir) - 1] = '\0'; } if (argc > 0) { if (setjmp(toplevel)) diff --git a/src/appl/gssftp/ftp/secure.c b/src/appl/gssftp/ftp/secure.c index 48f57f9..e1f69b0 100644 --- a/src/appl/gssftp/ftp/secure.c +++ b/src/appl/gssftp/ftp/secure.c @@ -52,6 +52,11 @@ extern struct sockaddr_in myaddr; extern int dlevel; extern char *auth_type; +/* Some libc's (GNU libc, at least) define MAX as a macro. Forget that. */ +#ifdef MAX +#undef MAX +#endif + #define MAX maxbuf extern unsigned int maxbuf; /* maximum output buffer size */ extern unsigned char *ucbuf; /* cleartext buffer */ diff --git a/src/appl/gssftp/ftpd/ChangeLog b/src/appl/gssftp/ftpd/ChangeLog index a459d30..637e6be 100644 --- a/src/appl/gssftp/ftpd/ChangeLog +++ b/src/appl/gssftp/ftpd/ChangeLog @@ -1,3 +1,7 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * ftpd.c (gunique): Make sure that path stored in "new" isn't too long. + 2000-02-18 Ken Raeburn <raeburn@mit.edu> * ftpd.c (reply, lreply): Declare with format attribute under diff --git a/src/appl/gssftp/ftpd/ftpd.c b/src/appl/gssftp/ftpd/ftpd.c index c7dfc8a..047be35 100644 --- a/src/appl/gssftp/ftpd/ftpd.c +++ b/src/appl/gssftp/ftpd/ftpd.c @@ -2123,7 +2123,8 @@ gunique(local) } if (cp) *cp = '/'; - (void) strcpy(new, local); + (void) strncpy(new, local, sizeof(new) - 1); + new[sizeof(new) - 1] = '\0'; cp = new + strlen(new); *cp++ = '.'; for (count = 1; count < 100; count++) { @@ -2287,7 +2288,8 @@ char *data; syslog(LOG_ERR, "Couldn't canonicalize local hostname"); return 0; } - strcpy(localname, hp->h_name); + strncpy(localname, hp->h_name, sizeof(localname) - 1); + localname[sizeof(localname) - 1] = '\0'; for (service = gss_services; *service; service++) { sprintf(service_name, "%s@%s", *service, localname); diff --git a/src/appl/telnet/libtelnet/ChangeLog b/src/appl/telnet/libtelnet/ChangeLog index 67877b1..1abc88d 100644 --- a/src/appl/telnet/libtelnet/ChangeLog +++ b/src/appl/telnet/libtelnet/ChangeLog @@ -1,3 +1,22 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * gettytab.c (nchktc): Don't overflow tcname if tty type name is too + long + * kerberos.c (kerberos4_status): Make sure "UserNameRequested" is + always properly terminated. + * kerberos5.c (kerberos5_is): If bad principal name is too long to fit + in "errbuf", don't print it. + (kerberos5_status): Make sure "UserNameRequested" is always properly + terminated. + * spx.c (spx_status): Ditto. + +2000-04-28 Nalin Dahyabhai <nalin@redhat.com> + + * kerberos5.c (kerberos5_is): Don't overflow buffer "errbuf". + * spx.c (spx_init, spx_send, spx_is): Don't overflow buffer + "targ_printable". + (spx_status): Don't overflow buffer "acl_file". + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/appl/telnet/libtelnet/gettytab.c b/src/appl/telnet/libtelnet/gettytab.c index f6ffb7c..aaad43a 100644 --- a/src/appl/telnet/libtelnet/gettytab.c +++ b/src/appl/telnet/libtelnet/gettytab.c @@ -98,9 +98,10 @@ nchktc() /* p now points to beginning of last field */ if (p[0] != 't' || p[1] != 'c') return(1); - strcpy(tcname,p+3); + strncpy(tcname, p + 3, sizeof(tcname) - 1); + tcname[sizeof(tcname) - 1] = '\0'; q = tcname; - while (q && *q != ':') + while (*q && *q != ':') q++; *q = 0; if (++hopcount > MAXHOP) { diff --git a/src/appl/telnet/libtelnet/kerberos.c b/src/appl/telnet/libtelnet/kerberos.c index 734466e..eb657ae 100644 --- a/src/appl/telnet/libtelnet/kerberos.c +++ b/src/appl/telnet/libtelnet/kerberos.c @@ -602,7 +602,9 @@ kerberos4_status(ap, name, level) return(level); if (UserNameRequested && !kuserok(&adat, UserNameRequested)) { - strcpy(name, UserNameRequested); + /* the name buffer comes from telnetd/telnetd{-ktd}.c */ + strncpy(name, UserNameRequested, 255); + name[255] = '\0'; return(AUTH_VALID); } else return(AUTH_USER); diff --git a/src/appl/telnet/libtelnet/kerberos5.c b/src/appl/telnet/libtelnet/kerberos5.c index 6a62f36..b4c7398 100644 --- a/src/appl/telnet/libtelnet/kerberos5.c +++ b/src/appl/telnet/libtelnet/kerberos5.c @@ -423,7 +423,8 @@ kerberos5_is(ap, data, cnt) NULL, keytabid, NULL, &ticket); if (r) { (void) strcpy(errbuf, "krb5_rd_req failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); goto errout; } @@ -440,8 +441,12 @@ kerberos5_is(ap, data, cnt) princ[krb5_princ_component(telnet_context, ticket->server,0)->length] = '\0'; if (strcmp("host", princ)) { - (void) sprintf(errbuf, "incorrect service name: \"%s\" != \"%s\"", - princ, "host"); + if(strlen(princ) < sizeof(errbuf) - 39) { + (void) sprintf(errbuf, "incorrect service name: \"%s\" != \"host\"", + princ); + } else { + (void) sprintf(errbuf, "incorrect service name: principal != \"host\""); + } goto errout; } } else { @@ -455,7 +460,8 @@ kerberos5_is(ap, data, cnt) if (r) { (void) strcpy(errbuf, "krb5_auth_con_getauthenticator failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); goto errout; } if ((ap->way & AUTH_ENCRYPT_MASK) == AUTH_ENCRYPT_ON && @@ -476,7 +482,8 @@ kerberos5_is(ap, data, cnt) &key); if (r) { (void) strcpy(errbuf, "krb5_auth_con_getkey failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); goto errout; } r = krb5_verify_checksum(telnet_context, @@ -495,7 +502,8 @@ kerberos5_is(ap, data, cnt) if (r) { (void) strcpy(errbuf, "checksum verification failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); goto errout; } krb5_free_keyblock(telnet_context, key); @@ -506,7 +514,8 @@ kerberos5_is(ap, data, cnt) if ((r = krb5_mk_rep(telnet_context, auth_context, &outbuf))) { (void) strcpy(errbuf, "Make reply failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); goto errout; } @@ -560,7 +569,8 @@ kerberos5_is(ap, data, cnt) char errbuf[128]; (void) strcpy(errbuf, "Read forwarded creds failed: "); - (void) strcat(errbuf, error_message(r)); + errbuf[sizeof(errbuf) - 1] = '\0'; + (void) strncat(errbuf, error_message(r), sizeof(errbuf) - 1 - strlen(errbuf)); Data(ap, KRB_FORWARD_REJECT, errbuf, -1); if (auth_debug_mode) printf( @@ -586,7 +596,8 @@ kerberos5_is(ap, data, cnt) char eerrbuf[329]; strcpy(eerrbuf, "telnetd: "); - strcat(eerrbuf, errbuf); + eerrbuf[sizeof(eerrbuf) - 1] = '\0'; + strncat(eerrbuf, errbuf, sizeof(eerrbuf) - 1 - strlen(eerrbuf)); Data(ap, KRB_REJECT, eerrbuf, -1); } if (auth_debug_mode) @@ -706,7 +717,9 @@ kerberos5_status(ap, name, level) krb5_kuserok(telnet_context, ticket->enc_part2->client, UserNameRequested)) { - strcpy(name, UserNameRequested); + /* the name buffer comes from telnetd/telnetd{-ktd}.c */ + strncpy(name, UserNameRequested, 255); + name[255] = '\0'; return(AUTH_VALID); } else return(AUTH_USER); diff --git a/src/appl/telnet/libtelnet/spx.c b/src/appl/telnet/libtelnet/spx.c index f23490f..7285d0d 100644 --- a/src/appl/telnet/libtelnet/spx.c +++ b/src/appl/telnet/libtelnet/spx.c @@ -173,7 +173,8 @@ spx_init(ap, server) str_data[3] = TELQUAL_REPLY; gethostname(lhostname, sizeof(lhostname)); strcpy(targ_printable, "SERVICE:rcmd@"); - strcat(targ_printable, lhostname); + strncat(targ_printable, lhostname, sizeof(targ_printable) - 1 - 13); + targ_printable[sizeof(targ_printable) - 1] = '\0'; input_name_buffer.length = strlen(targ_printable); input_name_buffer.value = targ_printable; major_status = gss_import_name(&status, @@ -216,7 +217,8 @@ spx_send(ap) printf("[ Trying SPX ... ]\n"); strcpy(targ_printable, "SERVICE:rcmd@"); - strcat(targ_printable, RemoteHostName); + strncat(targ_printable, RemoteHostName, sizeof(targ_printable) - 1 - 13); + targ_printable[sizeof(targ_printable) - 1] = '\0'; input_name_buffer.length = strlen(targ_printable); input_name_buffer.value = targ_printable; @@ -324,7 +326,8 @@ spx_is(ap, data, cnt) gethostname(lhostname, sizeof(lhostname)); strcpy(targ_printable, "SERVICE:rcmd@"); - strcat(targ_printable, lhostname); + strncat(targ_printable, lhostname, sizeof(targ_printable) - 1 - 13); + targ_printable[sizeof(targ_printable) - 1] = '\0'; input_name_buffer.length = strlen(targ_printable); input_name_buffer.value = targ_printable; @@ -479,7 +482,7 @@ spx_status(ap, name, level) gss_buffer_desc fullname_buffer, acl_file_buffer; gss_OID fullname_type; - char acl_file[160], fullname[160]; + char acl_file[MAXPATHLEN], fullname[160]; int major_status, status = 0; struct passwd *pwd; @@ -494,8 +497,9 @@ spx_status(ap, name, level) return(AUTH_USER); /* not authenticated */ } - strcpy(acl_file, pwd->pw_dir); - strcat(acl_file, "/.sphinx"); + acl_file[sizeof(acl_file) - 1] = '\0'; + strncpy(acl_file, pwd->pw_dir, sizeof(acl_file) - 1); + strncat(acl_file, "/.sphinx", sizeof(acl_file) - 1 - strlen(acl_file)); acl_file_buffer.value = acl_file; acl_file_buffer.length = strlen(acl_file); @@ -511,7 +515,9 @@ spx_status(ap, name, level) &acl_file_buffer); if (major_status == GSS_S_COMPLETE) { - strcpy(name, UserNameRequested); + /* the name buffer comes from telnetd/telnetd{-ktd}.c */ + strncpy(name, UserNameRequested, 255); + name[255] = '\0'; return(AUTH_VALID); } else { return(AUTH_USER); diff --git a/src/appl/telnet/telnet/ChangeLog b/src/appl/telnet/telnet/ChangeLog index e3cfb63..fb7cc9394 100644 --- a/src/appl/telnet/telnet/ChangeLog +++ b/src/appl/telnet/telnet/ChangeLog @@ -1,3 +1,18 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * commands.c (makeargv): Don't overflow buffer "saveline". + (tn): Don't overflow buffer "_hostname". + (cmdrc): Don't overflow buffer "m1save". + * externs.h: Include the size of "tline", so that we can check for + overflows elsewhere. + * main.c(main, tn370): Don't overflow buffer "tline". + * utilities.c (SetNetTrace): Don't overflow buffer "NetTraceFile". + +2000-04-28 Nalin Dahyabhai <nalin@redhat.com> + + * commands.c (cmdrc): Don't overflow buffer "rcbuf". + * tn3270.c (settranscom): Don't overflow buffer "transcom". + 2000-02-24 Ezra Peisach <epeisach@mit.edu> * configure.in: Remove dependency on libdes425 when krb4 support diff --git a/src/appl/telnet/telnet/commands.c b/src/appl/telnet/telnet/commands.c index 2c80b0b..8ffba2e 100644 --- a/src/appl/telnet/telnet/commands.c +++ b/src/appl/telnet/telnet/commands.c @@ -138,7 +138,9 @@ makeargv() margc = 0; cp = line; if (*cp == '!') { /* Special case shell escape */ - strcpy(saveline, line); /* save for shell command */ + strncpy(saveline, line, sizeof(saveline) - 1); + /* save for shell command */ + saveline[sizeof(saveline) - 1] = '\0'; *argp++ = "!"; /* No room in string to get this */ margc++; cp++; @@ -2450,7 +2452,8 @@ tn(argc, argv) if (temp & 0xffffffff != INADDR_NONE) { sin.sin_addr.s_addr = temp; sin.sin_family = AF_INET; - (void) strcpy(_hostname, hostp); + (void) strncpy(_hostname, hostp, sizeof(_hostname) - 1); + _hostname[sizeof(_hostname) - 1] = '\0'; hostname = _hostname; } else { host = gethostbyname(hostp); @@ -2855,16 +2858,18 @@ cmdrc(m1, m2) if (skiprc) return; - strcpy(m1save, m1); + strncpy(m1save, m1, sizeof(m1save) - 1); + m1save[sizeof(m1save) - 1] = '\0'; m1 = m1save; if (rcname == 0) { rcname = getenv("HOME"); if (rcname) - strcpy(rcbuf, rcname); + strncpy(rcbuf, rcname, sizeof(rcbuf) - 1); else rcbuf[0] = '\0'; - strcat(rcbuf, "/.telnetrc"); + rcbuf[sizeof(rcbuf) - 1] = '\0'; + strncat(rcbuf, "/.telnetrc", sizeof(rcbuf) - 1 - strlen(rcbuf)); rcname = rcbuf; } diff --git a/src/appl/telnet/telnet/externs.h b/src/appl/telnet/telnet/externs.h index e993986..f35cded 100644 --- a/src/appl/telnet/telnet/externs.h +++ b/src/appl/telnet/telnet/externs.h @@ -486,7 +486,7 @@ extern char *Ibackp, /* Oldest byte of 3270 data */ Ibuf[], /* 3270 buffer */ *Ifrontp, /* Where next 3270 byte goes */ - tline[], + tline[200], *transcom; /* Transparent command */ extern int diff --git a/src/appl/telnet/telnet/main.c b/src/appl/telnet/telnet/main.c index da98ae6..7696857 100644 --- a/src/appl/telnet/telnet/main.c +++ b/src/appl/telnet/telnet/main.c @@ -274,7 +274,8 @@ main(argc, argv) case 't': #if defined(TN3270) && defined(unix) transcom = tline; - (void)strcpy(transcom, optarg); + (void)strncpy(transcom, optarg, sizeof(tline) - 1); + tline[sizeof(tline) - 1] = '\0'; #else fprintf(stderr, "%s: Warning: -t ignored, no TN3270 support.\n", diff --git a/src/appl/telnet/telnet/tn3270.c b/src/appl/telnet/telnet/tn3270.c index 77aedaf..c46ae7e 100644 --- a/src/appl/telnet/telnet/tn3270.c +++ b/src/appl/telnet/telnet/tn3270.c @@ -397,10 +397,11 @@ settranscom(argc, argv) return 1; } transcom = tline; - (void) strcpy(transcom, argv[1]); + (void) strncpy(transcom, argv[1], sizeof(tline) - 1); + tline[sizeof(tline) - 1] = '\0'; for (i = 2; i < argc; ++i) { - (void) strcat(transcom, " "); - (void) strcat(transcom, argv[i]); + (void) strncat(transcom, " ", sizeof(tline) - 1 - (transcom - tline)); + (void) strncat(transcom, argv[i], sizeof(tline) - 1 - (transcom - tline)); } return 1; } diff --git a/src/appl/telnet/telnet/utilities.c b/src/appl/telnet/telnet/utilities.c index 19f503b..82ad841 100644 --- a/src/appl/telnet/telnet/utilities.c +++ b/src/appl/telnet/telnet/utilities.c @@ -113,13 +113,15 @@ SetNetTrace(file) if (file && (strcmp(file, "-") != 0)) { NetTrace = fopen(file, "w"); if (NetTrace) { - strcpy((char *)NetTraceFile, file); + strncpy((char *)NetTraceFile, file, sizeof(NetTraceFile) - 1); + NetTraceFile[sizeof(NetTraceFile) - 1] = '\0'; return; } fprintf(stderr, "Cannot open %s.\n", file); } NetTrace = stdout; - strcpy((char *)NetTraceFile, "(standard output)"); + strncpy((char *)NetTraceFile, "(standard output)", sizeof(NetTraceFile) - 1); + NetTraceFile[sizeof(NetTraceFile) - 1] = '\0'; } void diff --git a/src/appl/telnet/telnetd/ChangeLog b/src/appl/telnet/telnetd/ChangeLog index 040a9af..6dc0fd8 100644 --- a/src/appl/telnet/telnetd/ChangeLog +++ b/src/appl/telnet/telnetd/ChangeLog @@ -1,3 +1,17 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * sys_term.c (start_login, Solaris): forcefully terminate "termbuf" + in case the "TERM" environment variable isn't. + * telnet-ktd.c (getterminaltype): Don't overflow buffers "first" and + "netobuf". + (recv_ayt): Forcibly terminate buffer "netobuf". + +2000-03-20 Ken Raeburn <raeburn@mit.edu> + Jeffrey Altman <jaltman@watsun.cc.columbia.edu> + + * state.c (telrcv): Fix off-by-one error dealing with full + buffer. + 2000-02-24 Ezra Peisach <epeisach@mit.edu> * configure.in: Remove dependency on libdes425 when krb4 support diff --git a/src/appl/telnet/telnetd/state.c b/src/appl/telnet/telnetd/state.c index 0f3b161..83e1840 100644 --- a/src/appl/telnet/telnetd/state.c +++ b/src/appl/telnet/telnetd/state.c @@ -102,7 +102,7 @@ telrcv() #endif while (ncc > 0) { - if ((&ptyobuf[BUFSIZ] - pfrontp) < 2) + if ((&ptyobuf[BUFSIZ] - pfrontp) < 1) break; c = *netip++ & 0377, ncc--; #ifdef ENCRYPTION diff --git a/src/appl/telnet/telnetd/sys_term.c b/src/appl/telnet/telnetd/sys_term.c index ee8d53d..b79209d 100644 --- a/src/appl/telnet/telnetd/sys_term.c +++ b/src/appl/telnet/telnetd/sys_term.c @@ -1257,6 +1257,7 @@ start_login(host, autologin, name) } else { strcpy(termbuf, "TERM="); strncat(termbuf, term, sizeof(termbuf) - 6); + termbuf[sizeof(termbuf) - 1] = '\0'; term = termbuf; } argv = addarg(argv, term); diff --git a/src/appl/telnet/telnetd/telnetd-ktd.c b/src/appl/telnet/telnetd/telnetd-ktd.c index 9ec608f..5936e3b 100644 --- a/src/appl/telnet/telnetd/telnetd-ktd.c +++ b/src/appl/telnet/telnetd/telnetd-ktd.c @@ -360,7 +360,7 @@ main(argc, argv) } (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); - if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) { + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { perror("bind"); exit(1); } @@ -368,7 +368,7 @@ main(argc, argv) perror("listen"); exit(1); } - foo = sizeof sin; + foo = sizeof(sin); ns = accept(s, (struct sockaddr *)&sin, &foo); if (ns < 0) { perror("accept"); @@ -548,25 +548,33 @@ getterminaltype(name) if (his_state_is_will(TELOPT_TSPEED)) { static char sbbuf[] = { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; - memcpy(nfrontp, sbbuf, sizeof sbbuf); - nfrontp += sizeof sbbuf; + if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) { + memcpy(nfrontp, sbbuf, sizeof(sbbuf)); + nfrontp += sizeof(sbbuf); + } } if (his_state_is_will(TELOPT_XDISPLOC)) { static char sbbuf[] = { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE }; - memcpy(nfrontp, sbbuf, sizeof sbbuf); - nfrontp += sizeof sbbuf; + if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) { + memcpy(nfrontp, sbbuf, sizeof(sbbuf)); + nfrontp += sizeof(sbbuf); + } } if (his_state_is_will(TELOPT_ENVIRON)) { static char sbbuf[] = { IAC, SB, TELOPT_ENVIRON, TELQUAL_SEND, IAC, SE }; - memcpy(nfrontp, sbbuf, sizeof sbbuf); - nfrontp += sizeof sbbuf; + if(nfrontp - netobuf + sizeof(sbbuf) < sizeof(netobuf)) { + memcpy(nfrontp, sbbuf, sizeof(sbbuf)); + nfrontp += sizeof(sbbuf); + } } if (his_state_is_will(TELOPT_TTYPE)) { - memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); - nfrontp += sizeof ttytype_sbbuf; + if(nfrontp - netobuf + sizeof(ttytype_sbbuf) < sizeof(netobuf)) { + memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf)); + nfrontp += sizeof(ttytype_sbbuf); + } } if (his_state_is_will(TELOPT_TSPEED)) { while (sequenceIs(tspeedsubopt, baseline)) @@ -591,12 +599,14 @@ getterminaltype(name) * we have to just go with what we (might) have already gotten. */ if (his_state_is_will(TELOPT_TTYPE) && !terminaltypeok(terminaltype)) { - (void) strncpy(first, terminaltype, sizeof(first)); + (void) strncpy(first, terminaltype, sizeof(first) - 1); + first[sizeof(first) - 1] = '\0'; for(;;) { /* * Save the unknown name, and request the next name. */ - (void) strncpy(last, terminaltype, sizeof(last)); + (void) strncpy(last, terminaltype, sizeof(last) - 1); + last[sizeof(last) - 1] = '\0'; _gettermname(); if (terminaltypeok(terminaltype)) break; @@ -615,7 +625,8 @@ getterminaltype(name) */ _gettermname(); if (strncmp(first, terminaltype, sizeof(first)) != 0) - (void) strncpy(terminaltype, first, sizeof(first)); + (void) strncpy(terminaltype, first, sizeof(terminaltype) - 1); + terminaltype[sizeof(terminaltype) - 1] = '\0'; break; } } @@ -635,8 +646,8 @@ _gettermname() if (his_state_is_wont(TELOPT_TTYPE)) return; settimer(baseline); - memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); - nfrontp += sizeof ttytype_sbbuf; + memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf)); + nfrontp += sizeof(ttytype_sbbuf); while (sequenceIs(ttypesubopt, baseline)) ttloop(); } @@ -922,7 +933,7 @@ telnet(f, p, host) #if defined(SO_OOBINLINE) (void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE, - (char *)&on, sizeof on); + (char *)&on, sizeof(on)); #endif /* defined(SO_OOBINLINE) */ #ifdef SIGTSTP @@ -989,8 +1000,10 @@ telnet(f, p, host) HE = getstr("he", &cp); HN = getstr("hn", &cp); IM = getstr("im", &cp); - if (HN && *HN) - (void) strcpy(host_name, HN); + if (HN && *HN) { + (void) strncpy(host_name, HN, sizeof(host_name) - 1); + host_name[sizeof(host_name) - 1] = '\0'; + } if (IM == 0) IM = ""; } else { @@ -1426,8 +1439,10 @@ recv_ayt() return; } #endif - (void) strcpy(nfrontp, "\r\n[Yes]\r\n"); + (void) strncpy(nfrontp, "\r\n[Yes]\r\n", + sizeof(netobuf) - 1 - (nfrontp - netobuf)); nfrontp += 9; + *nfrontp = '\0'; } void diff --git a/src/appl/telnet/telnetd/telnetd.c b/src/appl/telnet/telnetd/telnetd.c index 7267469..083b0de 100644 --- a/src/appl/telnet/telnetd/telnetd.c +++ b/src/appl/telnet/telnetd/telnetd.c @@ -522,7 +522,7 @@ main(argc, argv) } (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); - if (bind(s, (struct sockaddr *)&sin, sizeof sin) < 0) { + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { perror("bind"); exit(1); } @@ -530,7 +530,7 @@ main(argc, argv) perror("listen"); exit(1); } - foo = sizeof sin; + foo = sizeof(sin); ns = accept(s, (struct sockaddr *)&sin, &foo); if (ns < 0) { perror("accept"); @@ -781,34 +781,49 @@ getterminaltype(name) static unsigned char sb[] = { IAC, SB, TELOPT_TSPEED, TELQUAL_SEND, IAC, SE }; - memcpy(nfrontp, sb, sizeof sb); - nfrontp += sizeof sb; + if(nfrontp - netobuf + sizeof(sb) < sizeof(netobuf)) { + memcpy(nfrontp, sb, sizeof(sb)); + nfrontp += sizeof(sb); + *nfrontp = '\0'; + } } if (his_state_is_will(TELOPT_XDISPLOC)) { static unsigned char sb[] = { IAC, SB, TELOPT_XDISPLOC, TELQUAL_SEND, IAC, SE }; - memcpy(nfrontp, sb, sizeof sb); - nfrontp += sizeof sb; + if(nfrontp - netobuf + sizeof(sb) < sizeof(netobuf)) { + memcpy(nfrontp, sb, sizeof(sb)); + nfrontp += sizeof(sb); + *nfrontp = '\0'; + } } if (his_state_is_will(TELOPT_NEW_ENVIRON)) { static unsigned char sb[] = { IAC, SB, TELOPT_NEW_ENVIRON, TELQUAL_SEND, IAC, SE }; - memcpy(nfrontp, sb, sizeof sb); - nfrontp += sizeof sb; + if(nfrontp - netobuf + sizeof(sb) < sizeof(netobuf)) { + memcpy(nfrontp, sb, sizeof(sb)); + nfrontp += sizeof(sb); + *nfrontp = '\0'; + } } else if (his_state_is_will(TELOPT_OLD_ENVIRON)) { static unsigned char sb[] = { IAC, SB, TELOPT_OLD_ENVIRON, TELQUAL_SEND, IAC, SE }; - memcpy(nfrontp, sb, sizeof sb); - nfrontp += sizeof sb; + if(nfrontp - netobuf + sizeof(sb) < sizeof(netobuf)) { + memcpy(nfrontp, sb, sizeof(sb)); + nfrontp += sizeof(sb); + *nfrontp = '\0'; + } } if (his_state_is_will(TELOPT_TTYPE)) { - memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); - nfrontp += sizeof ttytype_sbbuf; + if(nfrontp - netobuf + sizeof(ttytype_sbbuf) < sizeof(netobuf)) { + memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf)); + nfrontp += sizeof(ttytype_sbbuf); + *nfrontp = '\0'; + } } if (his_state_is_will(TELOPT_TSPEED)) { while (sequenceIs(tspeedsubopt, baseline)) @@ -886,8 +901,11 @@ _gettermname() if (his_state_is_wont(TELOPT_TTYPE)) return; settimer(baseline); - memcpy(nfrontp, ttytype_sbbuf, sizeof ttytype_sbbuf); - nfrontp += sizeof ttytype_sbbuf; + if(nfrontp - netobuf + sizeof(ttytype_sbbuf)) { + memcpy(nfrontp, ttytype_sbbuf, sizeof(ttytype_sbbuf)); + nfrontp += sizeof(ttytype_sbbuf); + *nfrontp = '\0'; + } while (sequenceIs(ttypesubopt, baseline)) ttloop(); } @@ -1205,7 +1223,7 @@ telnet(f, p, host) #if defined(SO_OOBINLINE) (void) setsockopt(net, SOL_SOCKET, SO_OOBINLINE, - (char *)&on, sizeof on); + (char *)&on, sizeof(on)); #endif /* defined(SO_OOBINLINE) */ #ifdef SIGTSTP @@ -1266,7 +1284,8 @@ telnet(f, p, host) HN = getstr("hn", &cp); IM = getstr("im", &cp); if (HN && *HN) - (void) strcpy(host_name, HN); + (void) strncpy(host_name, HN, sizeof(host_name) - 1); + host_name[sizeof(host_name) - 1] = '\0'; if (IM == 0) IM = ""; } else { @@ -1688,8 +1707,10 @@ recv_ayt() return; } #endif - (void) strcpy(nfrontp, "\r\n[Yes]\r\n"); + (void) strncpy(nfrontp, "\r\n[Yes]\r\n", + sizeof(netobuf) - 1 - (nfrontp - netobuf)); nfrontp += 9; + *nfrontp = '\0'; } void diff --git a/src/clients/ChangeLog b/src/clients/ChangeLog index 2ab67bd..b70201b 100644 --- a/src/clients/ChangeLog +++ b/src/clients/ChangeLog @@ -1,3 +1,8 @@ +2000-03-24 Ken Raeburn <raeburn@mit.edu> + + * configure.in: Check for alpha*-dec-osf* instead of + alpha-dec-osf*. + 2000-02-24 Ezra Peisach <epeisach@mit.edu> * configure.in: Test for <arpa/inet.h> include file for inet_ntop diff --git a/src/clients/configure.in b/src/clients/configure.in index bd2046d..a2de914 100644 --- a/src/clients/configure.in +++ b/src/clients/configure.in @@ -12,7 +12,7 @@ fi AC_SUBST(SETENVOBJ) AC_CHECK_HEADERS(unistd.h pwd.h arpa/inet.h) case $krb5_cv_host in -alpha-dec-osf*) +alpha*-dec-osf*) AC_CHECK_LIB(security,setluid, AC_DEFINE(HAVE_SETLUID) KSU_LIBS="$KSU_LIBS -lsecurity" diff --git a/src/clients/klist/ChangeLog b/src/clients/klist/ChangeLog index 86686bb..31afc38 100644 --- a/src/clients/klist/ChangeLog +++ b/src/clients/klist/ChangeLog @@ -1,3 +1,10 @@ +2000-04-19 Danilo Almeida <dalmeida@mit.edu> + + * Makefile.in: Link in getopt library on Windows. + + * klist.c: Use getopt so that we can parse combined options (e.g., + -an or -45). + 2000-03-07 Danilo Almeida <dalmeida@mit.edu> * klist.M: Get man page up-to-date. diff --git a/src/clients/klist/Makefile.in b/src/clients/klist/Makefile.in index c33a4d0..4e067ea 100644 --- a/src/clients/klist/Makefile.in +++ b/src/clients/klist/Makefile.in @@ -14,7 +14,7 @@ all-mac:: klist: klist.o $(KRB4COMPAT_DEPLIBS) $(CC_LINK) -o $@ klist.o $(KRB4COMPAT_LIBS) -$(OUTPRE)klist.exe: $(OUTPRE)klist.obj $(KLIB) $(CLIB) +$(OUTPRE)klist.exe: $(OUTPRE)klist.obj $(BUILDTOP)\util\windows\$(OUTPRE)getopt.lib $(KLIB) $(CLIB) link $(EXE_LINKOPTS) -out:$@ $** wsock32.lib clean-unix:: diff --git a/src/clients/klist/klist.c b/src/clients/klist/klist.c index de435c4..ecf0be6 100644 --- a/src/clients/klist/klist.c +++ b/src/clients/klist/klist.c @@ -53,6 +53,8 @@ #include <netdb.h> #endif +extern int optind; + int show_flags = 0, show_time = 0, status_only = 0, show_keys = 0; int show_etype = 0, show_addresses = 0, no_resolve = 0; char *defname; @@ -130,6 +132,7 @@ main(argc, argv) int argc; char **argv; { + int c; char *name; int mode; int use_k5 = 0, use_k4 = 0; @@ -141,14 +144,10 @@ main(argc, argv) progname = GET_PROGNAME(argv[0]); - argv++; name = NULL; mode = DEFAULT; - while (*argv) { - if ((*argv)[0] != '-') { - if (name) usage(); - name = *argv; - } else switch ((*argv)[1]) { + while ((c = getopt(argc, argv, "fetKsnack45")) != -1) { + switch (c) { case 'f': show_flags = 1; break; @@ -202,7 +201,6 @@ main(argc, argv) usage(); break; } - argv++; } if (no_resolve && !show_addresses) { @@ -217,6 +215,14 @@ main(argc, argv) usage(); } + if (argc - optind > 1) { + fprintf(stderr, "Extra arguments (starting with \"%s\").\n", + argv[optind+1]); + usage(); + } + + name = (optind == argc-1) ? argv[optind] : 0; + if (!use_k5 && !use_k4) { use_k5 = default_k5; diff --git a/src/clients/ksu/ChangeLog b/src/clients/ksu/ChangeLog index f486004..088f320 100644 --- a/src/clients/ksu/ChangeLog +++ b/src/clients/ksu/ChangeLog @@ -1,3 +1,31 @@ +2000-05-22 Tom Yu <tlyu@mit.edu> + + * Makefile.in (OBJS): Put @SETENVOBJ@ on same line as xmalloc.o to + avoid trailing backslash on the end of the variable. + +2000-05-15 Ken Raeburn <raeburn@mit.edu> + + * ccache.c (krb5_ccache_copy): Modify conditionalized code block + slightly to make automatic indentation work better. + + * main.c (main): Complain and quit if prog_name is longer than 50 + characters. + +2000-04-26 Ken Raeburn <raeburn@mit.edu> + Nalin Dahyabhai <nalin@redhat.com> + + * main.c (DEBUG): Don't define. + (usage): Remove -C option from description. + (sweep_up): Deleted second argument; all callers changed. + (main): Support -D option only if DEBUG is defined. Initialize + ruid on entry. Set effective uid to ruid before processing + argument list. Removed -C option from -z/-Z conflict messages. + Report errors trying to stat source ccache using com_err. Verify + that getpwuid's returned data for source user has correct uid. + Eliminate use_source_cache variable. + + * ksu.M: Updates for removal of -C option. + 2000-01-27 Ken Raeburn <raeburn@mit.edu> * main.c (print_status): Now static. Add format attribute if diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in index c96de37..915d4b2 100644 --- a/src/clients/ksu/Makefile.in +++ b/src/clients/ksu/Makefile.in @@ -23,8 +23,7 @@ OBJS = \ authorization.o \ main.o \ heuristic.o \ - xmalloc.o \ - @SETENVOBJ@ + xmalloc.o @SETENVOBJ@ all:: ksu diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c index be77456..97a2084 100644 --- a/src/clients/ksu/ccache.c +++ b/src/clients/ksu/ccache.c @@ -75,7 +75,6 @@ struct stat st_temp; cc_def_name = krb5_cc_get_name(context, cc_def); cc_other_name = krb5_cc_get_name(context, *cc_other); - if ( ! stat(cc_def_name, &st_temp)){ if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){ return retval; @@ -86,12 +85,11 @@ struct stat st_temp; primary_principal); #ifdef HAVE_LSTAT - if (!lstat( cc_other_name, &st_temp)) { + if (!lstat( cc_other_name, &st_temp)) #else /*HAVE_LSTAT*/ - if (!stat( cc_other_name, &st_temp)) { + if (!stat( cc_other_name, &st_temp)) #endif return EINVAL; - } if (krb5_seteuid(0)||krb5_seteuid(target_uid)) { return errno; diff --git a/src/clients/ksu/ksu.M b/src/clients/ksu/ksu.M index 2eea2a0..325d2e8 100644 --- a/src/clients/ksu/ksu.M +++ b/src/clients/ksu/ksu.M @@ -37,9 +37,6 @@ ksu \- Kerberized super-user .B \-c .I source_cache_name ] [ -.B \-C -.I target_cache_name -] [ .B \-k ] [ .B \-D @@ -169,10 +166,8 @@ The real and effective user ID are changed to that of the target user. The target user's shell is then invoked (the shell name is specified in the password file). Upon termination of the shell, ksu deletes the target cache (unless -ksu is invoked with -.B \-k - or ' -.B \-C .' options). +ksu is invoked with the +.B \-k option). This is implemented by first doing a fork and then an exec, instead of just exec, as done by su. .br @@ -287,19 +282,7 @@ option is not used then the name is obtained from KRB5CCNAME environment variable. If KRB5CCNAME is not defined the source cache name is set to krb5cc_<source uid>. -.TP 10 -\fB\-C \fItarget_cache_name -Specify the target cache name (e.g. -.B \-C -FILE:/tmp/target_cache). -If '.' is specified (e.g. ksu -\-C .) ksu uses the source -cache and does not create a new target cache. Note: -this case requires both source and target user -to have read and write permissions for the source cache. -If -.B \-C -option is not used, the default target cache name is +The target cache name is automatically set to krb5cc_<target uid>.(gen_sym()), where gen_sym generates a new number such that the resulting cache does not already exist. @@ -313,8 +296,7 @@ target shell or a command ( command). Without .B \-k, -ksu deletes the target cache -(unless ksu was invoked with '-C .' option). +ksu deletes the target cache. .TP 10 \fB\-D turn on debug mode. @@ -359,7 +341,7 @@ if you want the tickets for other then the default principal. Note that the .B \-z option is mutually -exclusive with '-C .' and -Z options. +exclusive with the -Z option. .TP 10 \fB\-Z Don't copy any tickets from the source cache to the @@ -368,7 +350,7 @@ where the default principal name of the cache is initialized to the target principal name. Note that .B \-Z option is mutually -exclusive with '-C .' and -z options. +exclusive with the -z option. .TP 10 \fB\-q suppress the printing of status messages. diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c index 77a4996..58d3031 100644 --- a/src/clients/ksu/main.c +++ b/src/clients/ksu/main.c @@ -42,7 +42,7 @@ int quiet = 0; #define _DEF_CSH "/bin/csh" static int set_env_var PROTOTYPE((char *, char *)); -static void sweep_up PROTOTYPE((krb5_context, int, krb5_ccache)); +static void sweep_up PROTOTYPE((krb5_context, krb5_ccache)); static char * ontty PROTOTYPE((void)); #ifdef HAVE_STDARG_H static void print_status( const char *fmt, ...) @@ -61,7 +61,6 @@ char * get_dir_of_file(); void usage (){ fprintf(stderr, "Usage: %s [target user] [-n principal] [-c source cachename] [-C target cachename] [-k] [-D] [-r time] [-pf] [-l lifetime] [-zZ] [-q] [-e command [args... ] ] [-a [args... ] ]\n", prog_name); - } /* for Ultrix and friends ... */ @@ -69,8 +68,6 @@ void usage (){ #define MAXHOSTNAMELEN 64 #endif -#define DEBUG - /* These are file static so sweep_up can get to them*/ static uid_t source_uid, target_uid; @@ -86,7 +83,6 @@ char *localhostname = NULL; opt_info options; int option=0; int statusp=0; -int use_source_cache = 0; krb5_error_code retval = 0; krb5_principal client = NULL; krb5_ccache cc_target = NULL; @@ -106,7 +102,7 @@ krb5_boolean auth_val; krb5_boolean authorization_val = FALSE; int path_passwd = 0; int done =0,i,j; -uid_t ruid; +uid_t ruid = getuid (); struct passwd *pwd=NULL, *target_pwd ; char * shell; char ** params; @@ -142,6 +138,11 @@ char * dir_of_cc_source; if (strrchr(argv[0], '/')) argv[0] = strrchr(argv[0], '/')+1; prog_name = argv[0]; + if (strlen (prog_name) > 50) { + /* this many chars *after* last / ?? */ + com_err(prog_name, 0, "program name too long - quitting to avoid triggering system logging bugs"); + exit (1); + } #ifndef LOG_NDELAY @@ -176,7 +177,10 @@ char * dir_of_cc_source; } } - + if (krb5_seteuid (ruid)) { + com_err (prog_name, errno, "while setting euid to source user"); + exit (1); + } while(!done && ((option = getopt(pargc, pargv,"n:c:r:a:zZDfpkql:e:")) != -1)){ switch (option) { case 'r': @@ -232,22 +236,24 @@ char * dir_of_cc_source; options.princ = 1; break; +#ifdef DEBUG case 'D': auth_debug = 1; - break; + break; +#endif case 'z': some_rest_copy = 1; - if(all_rest_copy || use_source_cache){ + if(all_rest_copy) { fprintf(stderr, - "-z option is mutually exclusive with -Z and -C .\n"); + "-z option is mutually exclusive with -Z.\n"); errflg++; } break; case 'Z': all_rest_copy = 1; - if(some_rest_copy || use_source_cache){ + if(some_rest_copy) { fprintf(stderr, - "-Z option is mutually exclusive with -z and -C .\n"); + "-Z option is mutually exclusive with -z.\n"); errflg++; } break; @@ -258,10 +264,10 @@ char * dir_of_cc_source; cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1; if( stat( cc_source_tag_tmp, &st_temp)){ - fprintf(stderr,"File %s does not exist\n", - cc_source_tag_tmp); - errflg++; - + com_err (prog_name, errno, + "while looking for credentials file %s", + cc_source_tag_tmp); + exit (1); } } else { @@ -313,10 +319,9 @@ char * dir_of_cc_source; } /***********************************/ - ruid = getuid(); source_user = getlogin(); /*checks for the the login name in /etc/utmp*/ - /* verify that that the user exists and get his passwd structure */ + /* verify that that the user exists and get his passwd structure */ if (source_user == NULL ||(pwd = getpwnam(source_user)) == NULL || pwd->pw_uid != ruid){ @@ -327,6 +332,12 @@ char * dir_of_cc_source; fprintf(stderr, "ksu: who are you?\n"); exit(1); } + if (pwd->pw_uid != ruid) { + fprintf (stderr, "Your uid doesn't match your passwd entry?!\n"); + exit (1); + } + /* Okay, now we have *some* passwd entry that matches the + current real uid. */ /* allocate space and copy the usernamane there */ source_user = xstrdup(pwd->pw_name); @@ -357,23 +368,17 @@ char * dir_of_cc_source; else cc_source_tag_tmp++; } - if (krb5_seteuid(source_uid)) { - com_err ( prog_name, errno, "while setting euid to source user"); - exit(1); - } - + /* get a handle for the cache */ if ((retval = krb5_cc_resolve(ksu_context, cc_source_tag, &cc_source))){ com_err(prog_name, retval,"while getting source cache"); exit(1); } - if(!use_source_cache) { - if (((retval = krb5_cc_set_flags(ksu_context, cc_source, 0x0)) != 0) - && (retval != KRB5_FCC_NOFILE)) { + if (((retval = krb5_cc_set_flags(ksu_context, cc_source, 0x0)) != 0) + && (retval != KRB5_FCC_NOFILE)) { com_err(prog_name, retval, "while opening ccache"); exit(1); - } } if ((retval = get_best_princ_for_target(ksu_context, source_uid, target_uid, source_user, target_user, cc_source, @@ -409,29 +414,6 @@ char * dir_of_cc_source; exit(1); } - if (stat(cc_source_tag_tmp, &st_temp)){ - if (use_source_cache){ - - dir_of_cc_source = get_dir_of_file(cc_source_tag_tmp); - - - if (access(dir_of_cc_source, R_OK | W_OK )){ - fprintf(stderr, - "%s does not have correct permissions for %s\n", - source_user, cc_source_tag); - exit(1); - } - - if ((retval = krb5_cc_initialize(ksu_context, cc_source, - client))){ - com_err(prog_name, retval, - "while initializing source cache"); - exit(1); - } - } - } - - if (cc_target_tag == NULL) { cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE ,sizeof(char)); @@ -450,8 +432,7 @@ char * dir_of_cc_source; } - dir_of_cc_target = get_dir_of_file( use_source_cache ? - cc_source_tag_tmp: cc_target_tag_tmp); + dir_of_cc_target = get_dir_of_file(cc_target_tag_tmp); if (access(dir_of_cc_target, R_OK | W_OK )){ fprintf(stderr, @@ -475,48 +456,33 @@ char * dir_of_cc_source; The cache is owned by the target user.*/ - if (! use_source_cache){ - - /* if root ksu's to a regular user, then - then only the credentials for that particular user - should be copied */ + /* if root ksu's to a regular user, then + then only the credentials for that particular user + should be copied */ - if ((source_uid == 0) && (target_uid != 0)) { + if ((source_uid == 0) && (target_uid != 0)) { - if ((retval = krb5_ccache_copy_restricted(ksu_context, cc_source, - cc_target_tag, client, &cc_target, &stored, target_uid))){ - com_err (prog_name, retval, - "while copying cache %s to %s", - krb5_cc_get_name(ksu_context, cc_source),cc_target_tag); - exit(1); - } - - } else{ - if ((retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag, - client,&cc_target, &stored, target_uid))){ - com_err (prog_name, retval, - "while copying cache %s to %s", - krb5_cc_get_name(ksu_context, cc_source), - cc_target_tag); - exit(1); - } - - } - - } - else{ - cc_target = cc_source; - cc_target_tag = (char *) cc_source_tag; - cc_target_tag_tmp = (char *) cc_source_tag_tmp; - - if ((retval=krb5_find_princ_in_cache(ksu_context, cc_target,client, &stored))){ - com_err (prog_name, retval, - "while searching for client in source ccache"); - exit(1); - } + if ((retval = krb5_ccache_copy_restricted(ksu_context, cc_source, + cc_target_tag, client, &cc_target, &stored, target_uid))){ + com_err (prog_name, retval, + "while copying cache %s to %s", + krb5_cc_get_name(ksu_context, cc_source),cc_target_tag); + exit(1); + } + } else { + if ((retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag, + client,&cc_target, &stored, target_uid))) { + com_err (prog_name, retval, + "while copying cache %s to %s", + krb5_cc_get_name(ksu_context, cc_source), + cc_target_tag); + exit(1); + } + } - /* Become root for authentication*/ + + /* Become root for authentication*/ if (krb5_seteuid(0)) { com_err(prog_name, errno, "while reclaiming root uid"); @@ -532,7 +498,7 @@ char * dir_of_cc_source; &kdc_server))){ com_err(prog_name, retval, "while creating tgt for local realm"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -544,8 +510,7 @@ char * dir_of_cc_source; if (zero_password == FALSE){ fprintf(stderr,"Goodbye\n"); - sweep_up(ksu_context, use_source_cache, - cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -574,7 +539,7 @@ char * dir_of_cc_source; syslog(LOG_WARNING, "'%s %s' authentication failed for %s%s", prog_name,target_user,source_user,ontty()); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -585,7 +550,7 @@ char * dir_of_cc_source; to properly handle races in chown if this code is ever re-enabled. */ /* cache the tickets if possible in the source cache */ - if (!path_passwd && !use_source_cache){ + if (!path_passwd){ if ((retval = krb5_ccache_overwrite(ksu_context, cc_target, cc_source, client))){ @@ -593,7 +558,7 @@ char * dir_of_cc_source; "while copying cache %s to %s", krb5_cc_get_name(ksu_context, cc_target), krb5_cc_get_name(ksu_context, cc_source)); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } if (chown(cc_source_tag_tmp, source_uid, source_gid)){ @@ -607,7 +572,7 @@ char * dir_of_cc_source; if ((retval = krb5_unparse_name(ksu_context, client, &client_name))) { com_err (prog_name, retval, "When unparsing name"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -619,7 +584,7 @@ char * dir_of_cc_source; /* Run authorization as target.*/ if (krb5_seteuid(target_uid)) { com_err(prog_name, errno, "while switching to target for authorization check"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -627,13 +592,13 @@ char * dir_of_cc_source; cmd, &authorization_val, &exec_cmd))){ com_err(prog_name,retval,"while checking authorization"); krb5_seteuid(0); /*So we have some chance of sweeping up*/ - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } if (krb5_seteuid(0)) { com_err(prog_name, errno, "while switching back from target after authorization check"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } if (authorization_val == TRUE){ @@ -678,7 +643,7 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ } - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } } @@ -686,7 +651,7 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ if( some_rest_copy){ if ((retval = krb5_ccache_filter(ksu_context, cc_target, client))){ com_err(prog_name,retval,"while calling cc_filter"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } } @@ -715,7 +680,7 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ if (!standard_shell(target_pwd->pw_shell) && source_uid) { fprintf(stderr, "ksu: permission denied (shell).\n"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } #endif /* HAVE_GETUSERSHELL */ @@ -724,20 +689,20 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ if(set_env_var("USER", target_pwd->pw_name)){ fprintf(stderr,"ksu: couldn't set environment variable USER\n"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } } if(set_env_var( "HOME", target_pwd->pw_dir)){ fprintf(stderr,"ksu: couldn't set environment variable USER\n"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } if(set_env_var( "SHELL", shell)){ fprintf(stderr,"ksu: couldn't set environment variable USER\n"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -746,26 +711,21 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ if(set_env_var( KRB5_ENV_CCNAME, cc_target_tag)){ fprintf(stderr,"ksu: couldn't set environment variable %s\n", KRB5_ENV_CCNAME); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } - - if (!use_source_cache){ - - } - /* set permissions */ if (setgid(target_pwd->pw_gid) < 0) { perror("ksu: setgid"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } if (initgroups(target_user, target_pwd->pw_gid)) { fprintf(stderr, "ksu: initgroups failed.\n"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -785,14 +745,14 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ */ if (setluid((uid_t) pwd->pw_uid) < 0) { perror("setluid"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } #endif /* HAVE_SETLUID */ if (setuid(target_pwd->pw_uid) < 0) { perror("ksu: setuid"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -827,11 +787,11 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ fprintf(stderr, "program to be execed %s\n",params[0]); } - if( keep_target_cache || use_source_cache ) { + if( keep_target_cache ) { execv(params[0], params); com_err(prog_name, errno, "while trying to execv %s", params[0]); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); }else{ statusp = 1; @@ -858,11 +818,11 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ if (ret_pid == -1) { com_err(prog_name, errno, "while calling waitpid"); } - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit (statusp); case -1: com_err(prog_name, errno, "while trying to fork."); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit (1); case 0: execv(params[0], params); @@ -920,27 +880,24 @@ char * env_var_buf; } -static void sweep_up(context, use_source_cache, cc) +static void sweep_up(context, cc) krb5_context context; - int use_source_cache; krb5_ccache cc; { -krb5_error_code retval; -char * cc_name; -struct stat st_temp; + krb5_error_code retval; + char * cc_name; + struct stat st_temp; -krb5_seteuid(0); -krb5_seteuid(target_uid); + krb5_seteuid(0); + krb5_seteuid(target_uid); -if (! use_source_cache){ - cc_name = krb5_cc_get_name(context, cc); - if ( ! stat(cc_name, &st_temp)){ - if ((retval = krb5_cc_destroy(context, cc))){ - com_err(prog_name, retval, - "while destroying cache"); - } - } + cc_name = krb5_cc_get_name(context, cc); + if ( ! stat(cc_name, &st_temp)){ + if ((retval = krb5_cc_destroy(context, cc))){ + com_err(prog_name, retval, + "while destroying cache"); } + } } /***************************************************************** get_params is to be called for the -a option or -e option to diff --git a/src/config-files/ChangeLog b/src/config-files/ChangeLog index 198614d..7a3f1e0 100644 --- a/src/config-files/ChangeLog +++ b/src/config-files/ChangeLog @@ -1,3 +1,8 @@ +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * krb5.conf.M: Added description of v4_realm from Booker + C. Bense. + 2000-01-21 Ken Raeburn <raeburn@mit.edu> * krb5.conf: Put primary KDC for Cygnus first. Add GNU.ORG diff --git a/src/config-files/krb5.conf.M b/src/config-files/krb5.conf.M index 143601e..1b48e57 100644 --- a/src/config-files/krb5.conf.M +++ b/src/config-files/krb5.conf.M @@ -179,6 +179,7 @@ subsection define the properties of that particular realm. For example: mit = mit.edu lithium = lithium.lcs.mit.edu } + v4_realm = LCS.MIT.EDU } .in -1i .fi @@ -208,6 +209,13 @@ default_domain mapping rule. It contains V4 instances (the tag name) which should be translated to some specific hostname (the tag value) as the second component in a Kerberos V5 principal name. +.IP v4_realm +This relation is used by the krb524 library routines when converting +a V5 principal name to a V4 principal name. It is used when V4 realm +name and the V5 realm are not the same, but still share the same +principal names and passwords. The tag value is the Kerberos V4 realm +name. + .SH DOMAIN_REALM SECTION The [domain_realm] section provides a translation from a hostname to the @@ -397,8 +405,6 @@ would look like this: NERSC.GOV = ANL.GOV NERSC.GOV = ES.NET } - - } .in -1i .fi .sp diff --git a/src/config/ChangeLog b/src/config/ChangeLog index 97bce15..73c7ff9 100644 --- a/src/config/ChangeLog +++ b/src/config/ChangeLog @@ -1,3 +1,14 @@ +2000-06-08 Tom Yu <tlyu@mit.edu> + + * config.guess: Update to 2000-05-30 from FSF. + + * config.sub: Update to 2000-05-30 from FSF. + +2000-05-03 Tom Yu <tlyu@mit.edu> + + * libobj.in, pre.in: Put $(LOCALINCLUDES) after $(CPPFLAGS) since + $(CPPFLAGS) should have its includes show up first. + 2000-03-01 Tom Yu <tlyu@mit.edu> * pre.in (INSTALL_SHLIB): New variable. diff --git a/src/config/config.guess b/src/config/config.guess index 98fea7b..b4faaed 100644 --- a/src/config/config.guess +++ b/src/config/config.guess @@ -1,7 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. -# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +version='2000-05-30' + # 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 @@ -22,7 +25,7 @@ # 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. +# Please send patches to <config-patches@gnu.org>. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and @@ -35,6 +38,60 @@ # (but try to keep the structure clean). # +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of this system. + +Operation modes: + -h, --help print this help, then exit + -V, --version print version number, then exit" + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case "$1" in + --version | --vers* | -V ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + exec >&2 + echo "$me: invalid option $1" + echo "$help" + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +# Use $HOST_CC if defined. $CC may point to a cross-compiler +if test x"$CC_FOR_BUILD" = x; then + if test x"$HOST_CC" != x; then + CC_FOR_BUILD="$HOST_CC" + else + if test x"$CC" != x; then + CC_FOR_BUILD="$CC" + else + CC_FOR_BUILD=cc + fi + fi +fi + + # 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 @@ -46,11 +103,49 @@ 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 -trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 +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 + *:NetBSD:*:*) + # Netbsd (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-cbm ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format. + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; alpha:OSF1:*:*) if test $UNAME_RELEASE = "V4.0"; then UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` @@ -59,46 +154,62 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # 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 + cat <<EOF >$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text .globl main + .align 4 .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 + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit .end main EOF - ${CC-cc} dummy.s -o dummy 2>/dev/null + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then - ./dummy - case "$?" in - 7) + case `./$dummy` in + 0-0) UNAME_MACHINE="alpha" ;; - 15) + 1-0) UNAME_MACHINE="alphaev5" ;; - 14) + 1-1) UNAME_MACHINE="alphaev56" ;; - 10) + 1-101) UNAME_MACHINE="alphapca56" ;; - 16) + 2-303) UNAME_MACHINE="alphaev6" ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; esac fi - rm -f dummy.s dummy - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]` + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix exit 0 ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 @@ -106,9 +217,6 @@ EOF 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 ;; @@ -133,16 +241,16 @@ EOF wgrisc:OpenBSD:*:*) echo mipsel-unknown-openbsd${UNAME_RELEASE} exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + 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*:*:*) + 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 @@ -150,7 +258,7 @@ EOF echo pyramid-pyramid-bsd fi exit 0 ;; - NILE:*:*:dcosx) + NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit 0 ;; sun4H:SunOS:5.*:*) @@ -195,21 +303,38 @@ EOF 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} + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${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 ;; @@ -222,9 +347,6 @@ EOF 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 ;; @@ -234,12 +356,17 @@ EOF VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit 0 ;; - 2020:CLIX:*:*) + 2020:CLIX:*:* | 2430: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; { + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); @@ -254,10 +381,10 @@ EOF 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 + $CC_FOR_BUILD $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:*:*) @@ -275,15 +402,18 @@ EOF 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 + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then echo m88k-dg-dgux${UNAME_RELEASE} - else + else echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} fi - else echo i586-dg-dgux${UNAME_RELEASE} - fi exit 0 ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 @@ -309,7 +439,7 @@ EOF exit 0 ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - sed 's/^ //' << EOF >dummy.c + sed 's/^ //' << EOF >$dummy.c #include <sys/systemcfg.h> main() @@ -320,8 +450,8 @@ EOF exit(0); } EOF - ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $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 @@ -349,7 +479,7 @@ EOF ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit 0 ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) @@ -368,25 +498,27 @@ EOF 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 + 9000/[678][0-9][0-9]) + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE #include <stdlib.h> #include <unistd.h> - + int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); - #endif + #endif long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) + + 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: + case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) - switch (bits) + switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; @@ -394,20 +526,20 @@ EOF } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; - #endif + #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 + (CCOPTS= $CC_FOR_BUILD $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 + sed 's/^ //' << EOF >$dummy.c #include <unistd.h> int main () @@ -432,8 +564,8 @@ EOF exit (0); } EOF - ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 - rm -f dummy.c dummy + $CC_FOR_BUILD $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:*:* ) @@ -442,6 +574,9 @@ EOF 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit 0 ;; @@ -458,6 +593,9 @@ EOF parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit 0 ;; @@ -488,37 +626,40 @@ EOF -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ exit 0 ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 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_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | 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 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit 0 ;; - i?86:BSD/386:*:* | *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + *: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 ;; @@ -528,6 +669,15 @@ EOF i*:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit 0 ;; @@ -538,15 +688,11 @@ EOF 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` + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_help_string=`cd /; ld --help 2>&1` ld_supported_emulations=`echo $ld_help_string \ | sed -ne '/supported emulations:/!d s/[ ][ ]*/ /g @@ -554,68 +700,146 @@ EOF 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 ;; + *ia64) + echo "${UNAME_MACHINE}-unknown-linux" + exit 0 + ;; + i?86linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 + ;; + elf_i?86) + echo "${UNAME_MACHINE}-pc-linux" + 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 + ;; + elf32arm*) + echo "${UNAME_MACHINE}-unknown-linux-gnuoldld" + exit 0 + ;; + armelf_linux*) + echo "${UNAME_MACHINE}-unknown-linux-gnu" + exit 0 + ;; + m68klinux) + echo "${UNAME_MACHINE}-unknown-linux-gnuaout" + exit 0 + ;; + elf32ppc | elf32ppclinux) + # Determine Lib Version + cat >$dummy.c <<EOF +#include <features.h> +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unkown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} + exit 0 + ;; + shelf_linux) + echo "${UNAME_MACHINE}-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 + cat <<EOF >$dummy.s + .data + \$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main + main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main EOF LIBC="" - ${CC-cc} dummy.s -o dummy 2>/dev/null + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null if test "$?" = 0 ; then - ./dummy - case "$?" in - 7) + case `./$dummy` in + 0-0) UNAME_MACHINE="alpha" ;; - 15) + 1-0) UNAME_MACHINE="alphaev5" ;; - 14) + 1-1) UNAME_MACHINE="alphaev56" ;; - 10) + 1-101) UNAME_MACHINE="alphapca56" ;; - 16) + 2-303) UNAME_MACHINE="alphaev6" ;; - esac + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac - objdump --private-headers dummy | \ + objdump --private-headers $dummy | \ grep ld.so.1 > /dev/null if test "$?" = 0 ; then LIBC="libc1" fi - fi - rm -f dummy.s dummy + 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[]; -{ + cat >$dummy.c <<EOF +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif #ifdef __MIPSEB__ printf ("%s-unknown-linux-gnu\n", argv[1]); #endif @@ -625,8 +849,10 @@ main(argc, argv) 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 + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + elif test "${UNAME_MACHINE}" = "s390"; then + echo s390-ibm-linux && exit 0 else # Either a pre-BFD a.out linker (linux-gnuoldld) # or one that does not give us useful --help. @@ -645,12 +871,14 @@ EOF ;; esac # Determine whether the default compiler is a.out or elf - cat >dummy.c <<EOF + cat >$dummy.c <<EOF #include <features.h> -main(argc, argv) - int argc; - char *argv[]; -{ +#ifdef __cplusplus +#include <stdio.h> /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif #ifdef __ELF__ # ifdef __GLIBC__ # if __GLIBC__ >= 2 @@ -667,8 +895,8 @@ main(argc, argv) 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 + $CC_FOR_BUILD $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. @@ -684,10 +912,20 @@ EOF echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit 0 ;; i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i?86:*:5:7*) + # Fixed at (any) Pentium or better + UNAME_MACHINE=i586 + if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then + echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} fi exit 0 ;; i?86:*:3.2:*) @@ -699,19 +937,20 @@ EOF (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 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} + i?86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp exit 0 ;; pc:*:*:*) + # Left here for compatibility: # 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 @@ -752,7 +991,7 @@ EOF mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit 0 ;; - i?86:LynxOS:2.*:*) + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit 0 ;; TSUNAMI:LynxOS:2.*:*) @@ -764,6 +1003,9 @@ EOF SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit 0 ;; @@ -794,7 +1036,7 @@ EOF news*:NEWS-OS:*:6*) echo mips-sony-newsos6 exit 0 ;; - R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*) + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else @@ -810,28 +1052,45 @@ EOF BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit 0 ;; -# MIT addition - Power\ Macintosh:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; -# MIT addition - powerpc:Rhapsody:*:*) - echo powerpc-unknown-rhapsody${UNAME_RELEASE} - exit 0 ;; -# MIT addition - i?86:Rhapsody:*:*) - echo i386-unknown-rhapsody${UNAME_RELEASE} - exit 0 ;; -# MIT addition - Power\ Macintosh:Mac\ OS:*:*) - echo powerpc-apple-macos${UNAME_RELEASE} + 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 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-W:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${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 +cat >$dummy.c <<EOF #ifdef _SEQUENT_ # include <sys/types.h> # include <sys/utsname.h> @@ -869,7 +1128,10 @@ main () #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif @@ -929,8 +1191,8 @@ main () } EOF -${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 -rm -f dummy.c dummy +$CC_FOR_BUILD $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. @@ -962,6 +1224,47 @@ then esac fi -#echo '(Unable to guess system type)' 1>&2 +cat >&2 <<EOF +$0: unable to guess system type + +The $version version of this script cannot recognize your system type. +Please download the most up to date version of the config scripts: + + ftp://ftp.gnu.org/pub/gnu/config/ + +If the version you run ($0) is already up to date, please +send the following data and any information you think might be +pertinent to <config-patches@gnu.org> in order to provide the needed +information to handle your system. + +config.guess version = $version + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "version='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/config/config.sub b/src/config/config.sub index 9952634..cb86fe1 100644 --- a/src/config/config.sub +++ b/src/config/config.sub @@ -1,6 +1,10 @@ #! /bin/sh # Configuration validation subroutine script, version 1.1. -# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# Free Software Foundation, Inc. + +version='2000-05-31' + # 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. @@ -25,6 +29,9 @@ # 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>. +# Please send patches to <config-patches@gnu.org>. +# # 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. @@ -45,30 +52,61 @@ # 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 +me=`echo "$0" | sed -e 's,.*/,,'` -# First pass through any local machine types. -case $1 in - *local*) - echo $1 - exit 0 - ;; - *) - ;; +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -V, --version print version number, then exit" + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case "$1" in + --version | --vers* | -V ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + exec >&2 + echo "$me: invalid option $1" + echo "$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; 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*) + nto-qnx* | linux-gnu*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -98,11 +136,21 @@ case $os in os= basic_machine=$1 ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; -hiux*) os=-hiuxwe2 ;; -sco5) - os=sco3.2v5 + os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) @@ -121,6 +169,9 @@ case $os in os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -143,22 +194,36 @@ case $os in -psos*) os=-psos ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; 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 \ + tahoe | i860 | ia64 | 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) + | 580 | i960 | h8300 \ + | x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | hppa64 \ + | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ + | alphaev6[78] \ + | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el | mcore \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v | fr30 | avr) basic_machine=$basic_machine-unknown ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) + ;; + # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. @@ -171,27 +236,49 @@ case $basic_machine in exit 1 ;; # Recognize the basic CPU types with company name. - vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \ + # FIXME: clean up the formatting here. + vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | 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-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ + | hppa2.0n-* | hppa64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ + | alphaev6[78]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ - | sparc64-* | mips64-* | mipsel-* \ - | mips64el-* | mips64orion-* | mips64orionel-* \ - | mipstx39-* | mipstx39el-* \ - | f301-*) + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* | mcore-* \ + | f301-* | armv*-* | s390-* | sv1-* | t3e-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \ + | bs2000-*) ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; alliant | fx80) basic_machine=fx80-alliant ;; @@ -221,6 +308,10 @@ case $basic_machine in basic_machine=m68k-apollo os=-sysv ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; aux) basic_machine=m68k-apple os=-aux @@ -297,6 +388,10 @@ case $basic_machine in encore | umax | mmax) basic_machine=ns32k-encore ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; fx2800) basic_machine=i860-alliant ;; @@ -315,6 +410,14 @@ case $basic_machine in basic_machine=h8300-hitachi os=-hms ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; harris) basic_machine=m88k-harris os=-sysv3 @@ -330,13 +433,30 @@ case $basic_machine in basic_machine=m68k-hp os=-hpux ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; 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) + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) @@ -345,9 +465,16 @@ case $basic_machine in hppa-next) os=-nextstep3 ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; i370-ibm* | ibm*) basic_machine=i370-ibm - os=-mvs ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i[34567]86v32) @@ -366,6 +493,22 @@ case $basic_machine in basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + i386-go32 | go32) + basic_machine=i386-unknown + os=-go32 + ;; + i386-mingw32 | mingw32) + basic_machine=i386-unknown + os=-mingw32 + ;; iris | iris4d) basic_machine=mips-sgi case $os in @@ -394,6 +537,10 @@ case $basic_machine in miniframe) basic_machine=m68000-convergent ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; mipsel*-linux*) basic_machine=mipsel-unknown os=-linux-gnu @@ -408,10 +555,34 @@ case $basic_machine in mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-unknown + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos @@ -424,6 +595,10 @@ case $basic_machine in basic_machine=mips-sony os=-newsos ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; next | m*-next ) basic_machine=m68k-next case $os in @@ -449,9 +624,28 @@ case $basic_machine in basic_machine=i960-intel os=-nindy ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; np1) basic_machine=np1-gould ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 @@ -469,19 +663,19 @@ case $basic_machine in pc532 | pc532-*) basic_machine=ns32k-pc532 ;; - pentium | p5 | k5 | nexen) + pentium | p5 | k5 | k6 | nexen) basic_machine=i586-pc ;; - pentiumpro | p6 | k6 | 6x86) + pentiumpro | p6 | 6x86 | athlon) basic_machine=i686-pc ;; pentiumii | pentium2) basic_machine=i786-pc ;; - pentium-* | p5-* | k5-* | nexen-*) + pentium-* | p5-* | k5-* | k6-* | nexen-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; - pentiumpro-* | p6-* | k6-* | 6x86-*) + pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-*) @@ -505,12 +699,20 @@ case $basic_machine in ps2) basic_machine=i386-ibm ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; sequent) basic_machine=i386-sequent ;; @@ -518,6 +720,10 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; sps7) basic_machine=m68k-bull os=-sysv2 @@ -525,6 +731,13 @@ case $basic_machine in spur) basic_machine=spur-unknown ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; sun2) basic_machine=m68000-sun ;; @@ -565,10 +778,18 @@ case $basic_machine in sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; symmetry) basic_machine=i386-sequent os=-dynix ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; tx39) basic_machine=mipstx39-unknown ;; @@ -586,6 +807,10 @@ case $basic_machine in basic_machine=a29k-nyu os=-sym1 ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; vaxv) basic_machine=vax-dec os=-sysv @@ -609,6 +834,14 @@ case $basic_machine in basic_machine=a29k-wrs os=-vxworks ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; xmp) basic_machine=xmp-cray os=-unicos @@ -616,6 +849,10 @@ case $basic_machine in xps | xps100) basic_machine=xps100-honeywell ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; none) basic_machine=none-none os=-none @@ -623,6 +860,15 @@ case $basic_machine in # 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. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; mips) if [ x$os = x-linux-gnu ]; then basic_machine=mips-unknown @@ -645,7 +891,7 @@ case $basic_machine in we32k) basic_machine=we32k-att ;; - sparc) + sparc | sparcv9) basic_machine=sparc-sun ;; cydra) @@ -657,6 +903,16 @@ case $basic_machine in orion105) basic_machine=clipper-highlevel ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 @@ -710,13 +966,34 @@ case $os in | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -macos* | -rhapsody*) + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit*) # Remember, each alternative MUST END IN *, to match a version number. ;; + -qnx*) + case $basic_machine in + x86-* | i[34567]86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; @@ -726,6 +1003,12 @@ case $os in -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; -osfrose*) os=-osfrose ;; @@ -741,12 +1024,18 @@ case $os in -acis*) os=-aos ;; + -386bsd) + os=-bsd + ;; -ctix* | -uts*) os=-sysv ;; -ns2 ) os=-nextstep2 ;; + -nsk) + os=-nsk + ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` @@ -772,9 +1061,18 @@ case $os in # This must come after -sysvr4. -sysv*) ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; -xenix) os=-xenix ;; + -*mint | -*MiNT) + os=-mint + ;; -none) ;; *) @@ -800,6 +1098,9 @@ case $basic_machine in *-acorn) os=-riscix1.2 ;; + arm*-rebel) + os=-linux + ;; arm*-semi) os=-aout ;; @@ -821,6 +1122,15 @@ case $basic_machine in # default. # os=-sunos4 ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; @@ -833,6 +1143,15 @@ case $basic_machine in *-ibm) os=-aix ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; *-hp) os=-hpux ;; @@ -896,6 +1215,18 @@ case $basic_machine in f301-fujitsu) os=-uxpv ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; *) os=-none ;; @@ -917,9 +1248,15 @@ case $basic_machine in -aix*) vendor=ibm ;; + -beos*) + vendor=be + ;; -hpux*) vendor=hp ;; + -mpeix*) + vendor=hp + ;; -hiux*) vendor=hitachi ;; @@ -935,7 +1272,7 @@ case $basic_machine in -genix*) vendor=ns ;; - -mvs*) + -mvs* | -opened*) vendor=ibm ;; -ptx*) @@ -947,9 +1284,26 @@ case $basic_machine in -aux*) vendor=apple ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -*MiNT) + vendor=atari + ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "version='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/src/config/libobj.in b/src/config/libobj.in index 5e2a2c1..0c85a59 100644 --- a/src/config/libobj.in +++ b/src/config/libobj.in @@ -29,10 +29,10 @@ PICFLAGS=@PICFLAGS@ PROFFLAGS=@PROFFLAGS@ .SUFFIXES: .c .so .po .c.so: - $(CC) $(DEFS) $(DEFINES) $(LOCALINCLUDES) $(PICFLAGS) $(CPPFLAGS) $(CFLAGS) -c $< -o $*.so.o && \ + $(CC) $(DEFS) $(DEFINES) $(PICFLAGS) $(CPPFLAGS) $(LOCALINCLUDES) $(CFLAGS) -c $< -o $*.so.o && \ $(MV) $*.so.o $*.so .c.po: - $(CC) $(DEFS) $(DEFINES) $(LOCALINCLUDES) $(PROFFLAGS) $(CPPFLAGS) $(CFLAGS) -c $< -o $*.po.o && \ + $(CC) $(DEFS) $(DEFINES) $(PROFFLAGS) $(CPPFLAGS) $(LOCALINCLUDES) $(CFLAGS) -c $< -o $*.po.o && \ $(MV) $*.po.o $*.po # rules to generate object file lists diff --git a/src/config/pre.in b/src/config/pre.in index abc3dff..cb97a47 100644 --- a/src/config/pre.in +++ b/src/config/pre.in @@ -70,7 +70,7 @@ SRCTOP = @srcdir@/$(BUILDTOP) VPATH = @srcdir@ CONFIG_RELTOPDIR = @CONFIG_RELTOPDIR@ -ALL_CFLAGS = $(DEFS) $(DEFINES) $(LOCALINCLUDES) $(CPPFLAGS) $(CFLAGS) +ALL_CFLAGS = $(DEFS) $(DEFINES) $(CPPFLAGS) $(LOCALINCLUDES) $(CFLAGS) CFLAGS = @CCOPTS@ CPPFLAGS = @CPPFLAGS@ DEFS = @DEFS@ diff --git a/src/include/ChangeLog b/src/include/ChangeLog index 928ecb1..da66ee6 100644 --- a/src/include/ChangeLog +++ b/src/include/ChangeLog @@ -1,3 +1,50 @@ +2000-06-02 Danilo Almeida <dalmeida@mit.edu> + + * krb5.hin (krb5_get_tgs_ktypes, krb5_free_ktypes): Fix linkage to + be KRB5_CALLCONV. + + * k5-int.h (krb5int_cc_default): Fix linkage to be consistent with + code. (Note: We should dump KRB5_DLLIMP.) + +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * krb5.hin (krb5_recvauth_version): Declare. + +2000-5-19 Alexandra Ellwood <lxs@mit.edu> + + * krb5-int.h: Added krb5int_cc_default. This function supports the + Kerberos Login Library and pops up a dialog if the cache does not + contain valid tickets. This is used to automatically get a tgt before + obtaining service tickets. Note that this should be an internal function + because callers don't expect krb5_cc_default to pop up a dialog! + (We found this out the hard way :-) + +2000-05-15 Jeffrey Altman <jaltman@columbia.edu> + + * krb5.hin -- Added prototypes for new public functions + + krb5_appdefault_string + krb5_appdefault_boolean + +2000-04-18 Ken Raeburn <raeburn@mit.edu> + + * krb5.hin: Declare krb5_free_ktypes. + +2000-4-13 Alexandra Ellwood <lxs@mit.edu> + + * krb5-int.h: Added support to store a krb5_principal in the os_context + along with the default ccache name (if known, this principal is the same + as the last time we looked at the ccache. + * win-mac.h: Set up the macintosh build to use KerberosLogin. + +2000-03-25 Miro Jurisic <meeroh@mit.edu> + + * k5-int.h: Fixed protos for krb5_locate_srv_* (naddrs is int*) + +2000-03-20 Miro Jurisic <meeroh@mit.edu> + + * krb5.hin: Add krb5_free_default_realm + 2000-03-15 Danilo Almeida <dalmeida@mit.edu> * krb5.hin: Add krb5_get_prompt_types() and related defs.. diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 1c48809..e8bffc6 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -511,7 +511,7 @@ krb5_error_code krb5_sendto_kdc const krb5_data *, const krb5_data *, krb5_data *, - int *)); + int)); krb5_error_code krb5_get_krbhst KRB5_PROTOTYPE((krb5_context, const krb5_data *, @@ -555,9 +555,8 @@ krb5_error_code krb5_locate_srv_conf const krb5_data *, const char *, struct sockaddr **, - int *, - int *, - int *)); + int*, + int)); /* no context? */ krb5_error_code krb5_locate_srv_dns @@ -565,7 +564,7 @@ krb5_error_code krb5_locate_srv_dns const char *, const char *, struct sockaddr **, - int *)); + int*)); #endif /* KRB5_LIBOS_PROTO__ */ @@ -788,11 +787,12 @@ KRB5_PROTOTYPE((krb5_context context, krb5_const krb5_keyblock *key, #define KRB5_LIBOS__ typedef struct _krb5_os_context { - krb5_magic magic; - krb5_int32 time_offset; - krb5_int32 usec_offset; - krb5_int32 os_flags; - char * default_ccname; + krb5_magic magic; + krb5_int32 time_offset; + krb5_int32 usec_offset; + krb5_int32 os_flags; + char * default_ccname; + krb5_principal default_ccprincipal; } *krb5_os_context; /* @@ -965,7 +965,7 @@ KRB5_PROTOTYPE((krb5_context context, krb5_get_init_creds_opt *options, krb5_gic_get_as_key_fct gak, void *gak_data, - int *master, + int master, krb5_kdc_rep **as_reply)); @@ -1506,6 +1506,8 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_ser_unpack_bytes krb5_octet FAR * FAR *, size_t FAR *)); +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5int_cc_default + KRB5_PROTOTYPE((krb5_context, krb5_ccache FAR *)); krb5_error_code KRB5_CALLCONV krb5_cc_retrieve_cred_default KRB5_PROTOTYPE((krb5_context, krb5_ccache, krb5_flags, diff --git a/src/include/kerberosIV/ChangeLog b/src/include/kerberosIV/ChangeLog index 767d835..9954dca 100644 --- a/src/include/kerberosIV/ChangeLog +++ b/src/include/kerberosIV/ChangeLog @@ -1,3 +1,18 @@ +2000-06-02 Ken Raeburn <raeburn@mit.edu> + + * krb.h (krb4_swab16): Mask upper byte of input after shifting, in + case the input value is a signed short. + +2000-05-18 Ken Raeburn <raeburn@mit.edu> + + * krb.h (krb4_swab32): Mask high byte of input value after + shifting, to avoid "time out of bounds" error when byte orders are + different and low byte of timestamp has its high bit set and the + timestamp is stored as a signed value. + + * krb.h (krb_get_err_text): Don't use "errno" as an argument + name. + Mon Mar 15 15:58:34 1999 Tom Yu <tlyu@mit.edu> * des.h: Fix GSS_DLLIMP. diff --git a/src/include/kerberosIV/krb.h b/src/include/kerberosIV/krb.h index fe8830b..4e2b675 100644 --- a/src/include/kerberosIV/krb.h +++ b/src/include/kerberosIV/krb.h @@ -340,8 +340,8 @@ typedef struct msg_dat MSG_DAT; /* * New byte swapping routines, much cleaner */ -#define krb4_swab16(val) (((val) >> 8) | ((val) << 8)) -#define krb4_swab32(val) (((val)>>24) | (((val)>>8)&0xFF00) | \ +#define krb4_swab16(val) ((((val) >> 8)&0xFF) | ((val) << 8)) +#define krb4_swab32(val) ((((val)>>24)&0xFF) | (((val)>>8)&0xFF00) | \ (((val)<<8)&0xFF0000) | ((val)<<24)) /* Kerberos ticket flag field bit definitions */ @@ -466,7 +466,7 @@ KRB5_DLLIMP int KRB5_CALLCONV dest_tkt PROTOTYPE((void)); /* err_txt.c */ KRB5_DLLIMP const char FAR * KRB5_CALLCONV krb_get_err_text - PROTOTYPE((int errno)); + PROTOTYPE((int errnum)); /* g_ad_tkt.c */ int get_ad_tkt PROTOTYPE((char *service, char *sinst, char *realm, int lifetime)); diff --git a/src/include/krb5.hin b/src/include/krb5.hin index ea8f93e..37cf1c6 100644 --- a/src/include/krb5.hin +++ b/src/include/krb5.hin @@ -1394,13 +1394,15 @@ krb5_error_code krb5_get_default_in_tkt_ktypes krb5_error_code krb5_set_default_tgs_ktypes KRB5_PROTOTYPE((krb5_context, krb5_const krb5_enctype *)); -krb5_error_code krb5_get_tgs_ktypes +krb5_error_code KRB5_CALLCONV krb5_get_tgs_ktypes KRB5_PROTOTYPE((krb5_context, krb5_const_principal, krb5_enctype **)); krb5_error_code krb5_get_permitted_enctypes KRB5_PROTOTYPE((krb5_context, krb5_enctype **)); +void KRB5_CALLCONV krb5_free_ktypes + KRB5_PROTOTYPE ((krb5_context, krb5_enctype *)); krb5_boolean krb5_is_permitted_enctype KRB5_PROTOTYPE((krb5_context, krb5_enctype)); @@ -1799,6 +1801,9 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_default_realm KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_set_default_realm KRB5_PROTOTYPE((krb5_context, krb5_const char FAR * )); +KRB5_DLLIMP void KRB5_CALLCONV krb5_free_default_realm + KRB5_PROTOTYPE((krb5_context, + char FAR * )); KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_sname_to_principal KRB5_PROTOTYPE((krb5_context, krb5_const char FAR *, @@ -1976,6 +1981,15 @@ KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_recvauth krb5_int32, krb5_keytab, krb5_ticket FAR * FAR *)); +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_recvauth_version + KRB5_PROTOTYPE((krb5_context, + krb5_auth_context FAR *, + krb5_pointer, + krb5_principal, + krb5_int32, + krb5_keytab, + krb5_ticket FAR * FAR *, + krb5_data FAR *)); krb5_error_code krb5_walk_realm_tree KRB5_PROTOTYPE((krb5_context, @@ -2384,6 +2398,24 @@ krb5_decode_ticket KRB5_PROTOTYPE((const krb5_data *code, krb5_ticket **rep)); +KRB5_DLLIMP void KRB5_CALLCONV +krb5_appdefault_string +KRB5_PROTOTYPE((krb5_context context, + const char *appname, + const krb5_data *realm, + const char *option, + const char *default_value, + char ** ret_value)); + +KRB5_DLLIMP void KRB5_CALLCONV +krb5_appdefault_boolean +KRB5_PROTOTYPE((krb5_context context, + const char *appname, + const krb5_data *realm, + const char *option, + int default_value, + int *ret_value)); + /* * The realm iterator functions */ diff --git a/src/include/krb5/ChangeLog b/src/include/krb5/ChangeLog index 6fc5cc3..609a171 100644 --- a/src/include/krb5/ChangeLog +++ b/src/include/krb5/ChangeLog @@ -1,3 +1,13 @@ +2000-5-18 Alexandra Ellwood <lxs@mit.edu> + + * macsock.h: local_addr_fallback_kludge defined to 0 again... fixed gethostname + +2000-5-9 Alexandra Ellwood <lxs@mit.edu> + + * macsock.h: local_addr_fallback_kludge now defined to magic gethostaddr function + in the Sockets Library, which does exactly what we want if the search domain is not + specified. + 1998-11-22 Miro Jurisic <meeroh@.mit.edu> * macsock.h: MacOS: only #define MACHOSTNAMELEN when not diff --git a/src/include/krb5/macsock.h b/src/include/krb5/macsock.h index 06b103a..6dc8c32 100644 --- a/src/include/krb5/macsock.h +++ b/src/include/krb5/macsock.h @@ -93,7 +93,7 @@ typedef int SOCKET; #define SOCKET_ERRNO (GetMITLibError()) #define SOCKET_SET_ERRNO(x) (SetMITLibError(x)) -#define local_addr_fallback_kludge() (0) +#define local_addr_fallback_kludge() 0 #endif /* macsock_h */ diff --git a/src/include/win-mac.h b/src/include/win-mac.h index e2d37e0..ffd3f63 100644 --- a/src/include/win-mac.h +++ b/src/include/win-mac.h @@ -226,6 +226,8 @@ HINSTANCE get_lib_instance(void); #ifdef macintosh +#define USE_LOGIN_LIBRARY + #define KRB5_CALLCONV #define KRB5_CALLCONV_C #define KRB5_DLLIMP diff --git a/src/kadmin/cli/ChangeLog b/src/kadmin/cli/ChangeLog index aa19760..665e60c 100644 --- a/src/kadmin/cli/ChangeLog +++ b/src/kadmin/cli/ChangeLog @@ -1,3 +1,17 @@ +2000-06-09 Tom Yu <tlyu@mit.edu> + + * kadmin.M: Update to reflect new -e and -keepold flags. + +2000-06-06 Ken Raeburn <raeburn@mit.edu> + + * kadmin.c (kadmin_startup): Don't pass keytab_name to printf if + it's NULL. + +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * strftime.c: Replace with a copy of the one from libkrb5, which + isn't under GPL. + 2000-03-01 Tom Yu <tlyu@mit.edu> * kadmin.c (kadmin_cpw): Initialize ks_tuple to NULL. diff --git a/src/kadmin/cli/kadmin.M b/src/kadmin/cli/kadmin.M index a74874f..5acd48b 100644 --- a/src/kadmin/cli/kadmin.M +++ b/src/kadmin/cli/kadmin.M @@ -320,6 +320,12 @@ sets the key of the principal to a random value sets the key of the principal to the specified string and does not prompt for a password. Note: using this option in a shell script can be dangerous if unauthorized users gain read access to the script. +.TP +\fB\-e\fP \fI"enc:salt ..."\fP +uses the specified list of enctype\-salttype pairs for setting the key +of the principal. The quotes are necessary if there are multiple +enctype\-salttype pairs. This will not function against kadmin +daemons earlier than krb5\-1.2. .nf .TP EXAMPLE: @@ -372,8 +378,8 @@ KADM5_UNK_PRINC (principal does not exist) modifies the specified principal, changing the fields as specified. The options are as above for .BR add_principal , -except that password changing is forbidden by this command. In -addition, the option +except that password changing and flags related to password changing +are forbidden by this command. In addition, the option .B \-clearpolicy will clear the current policy of a principal. This command requires the .I modify @@ -447,6 +453,18 @@ sets the key of the principal to a random value .TP \fB\-pw\fP \fIpassword\fP set the password to the specified string. Not recommended. +.TP +\fB\-e\fP \fI"enc:salt ..."\fP +uses the specified list of enctype\-salttype pairs for setting the key +of the principal. The quotes are necessary if there are multiple +enctype\-salttype pairs. This will not function against kadmin +daemons earlier than krb5\-1.2. +.TP +\fB\-keepold \fP +Keeps the previous kvno's keys around. There is no +easy way to delete the old keys, and this flag is usually not +necessary except perhaps for TGS keys. Don't use this flag unless you +know what you're doing. .nf .TP EXAMPLE: @@ -664,7 +682,10 @@ kadmin: .RE .fi .TP -\fBktadd\fP [\fB\-k\fP \fIkeytab\fP] [\fB\-q\fP] [\fIprincipal\fP | \fB\-glob\fP \fIprinc-exp\fP] [\fI...\fP] +\fBktadd\fP [\fB\-k\fP \fIkeytab\fP] [\fB\-q\fP] [\fB\-e\fP \fIkeysaltlist\fP] +.br +[\fIprincipal\fP | \fB\-glob\fP \fIprinc-exp\fP] [\fI...\fP] +.br Adds a principal or all principals matching .I princ-exp to a keytab, randomizing each principal's key in the process. Requires the @@ -772,3 +793,9 @@ OpenVision Kerberos administration program. .SH BUGS .PP Command output needs to be cleaned up. + +There is no way to delete a key kept around from a "\-keepold" option +to a password-changing command, other than to do a password change +without the "\-keepold" option, which will of course cause problems if +the key is a TGS key. There will be more powerful key-manipulation +commands in the future. diff --git a/src/kadmin/cli/kadmin.c b/src/kadmin/cli/kadmin.c index 8038532..2b1d8ac 100644 --- a/src/kadmin/cli/kadmin.c +++ b/src/kadmin/cli/kadmin.c @@ -392,8 +392,12 @@ char *kadmin_startup(argc, argv) KADM5_API_VERSION_2, &handle); } else if (use_keytab) { - printf("Authenticating as principal %s with keytab %s.\n", - princstr, keytab_name); + if (keytab_name) + printf("Authenticating as principal %s with keytab %s.\n", + princstr, keytab_name); + else + printf("Authenticating as principal %s with default keytab.\n", + princstr); retval = kadm5_init_with_skey(princstr, keytab_name, KADM5_ADMIN_SERVICE, ¶ms, diff --git a/src/kadmin/cli/strftime.c b/src/kadmin/cli/strftime.c index 484852a..6fb621e 100644 --- a/src/kadmin/cli/strftime.c +++ b/src/kadmin/cli/strftime.c @@ -1,469 +1,464 @@ -/* strftime - custom formatting of date and/or time - Copyright (C) 1989, 1991, 1992 Free Software Foundation, Inc. - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Note: this version of strftime lacks locale support, - but it is standalone. - - Performs `%' substitutions similar to those in printf. Except - where noted, substituted fields have a fixed size; numeric fields are - padded if necessary. Padding is with zeros by default; for fields - that display a single number, padding can be changed or inhibited by - following the `%' with one of the modifiers described below. Unknown - field specifiers are copied as normal characters. All other - characters are copied to the output without change. - - Supports a superset of the ANSI C field specifiers. - - Literal character fields: - % % - n newline - t tab - - Numeric modifiers (a nonstandard extension): - - do not pad the field - _ pad the field with spaces - - Time fields: - %H hour (00..23) - %I hour (01..12) - %k hour ( 0..23) - %l hour ( 1..12) - %M minute (00..59) - %p locale's AM or PM - %r time, 12-hour (hh:mm:ss [AP]M) - %R time, 24-hour (hh:mm) - %s time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension) - %S second (00..61) - %T time, 24-hour (hh:mm:ss) - %X locale's time representation (%H:%M:%S) - %Z time zone (EDT), or nothing if no time zone is determinable - - Date fields: - %a locale's abbreviated weekday name (Sun..Sat) - %A locale's full weekday name, variable length (Sunday..Saturday) - %b locale's abbreviated month name (Jan..Dec) - %B locale's full month name, variable length (January..December) - %c locale's date and time (Sat Nov 04 12:02:33 EST 1989) - %C century (00..99) - %d day of month (01..31) - %e day of month ( 1..31) - %D date (mm/dd/yy) - %h same as %b - %j day of year (001..366) - %m month (01..12) - %U week number of year with Sunday as first day of week (00..53) - %w day of week (0..6) - %W week number of year with Monday as first day of week (00..53) - %x locale's date representation (mm/dd/yy) - %y last two digits of year (00..99) - %Y year (1970...) - - David MacKenzie <djm@gnu.ai.mit.edu> */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <sys/types.h> -#if defined(TM_IN_SYS_TIME) || (!defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME)) -#include <sys/time.h> +/* $NetBSD: strftime.c,v 1.8 1999/02/07 17:33:30 augustss Exp $ */ + +/* + * Copyright (c) 1989 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) +#if 0 +static char *sccsid = "@(#)strftime.c 5.11 (Berkeley) 2/24/91"; #else -#include <time.h> -#endif - -#ifndef STDC_HEADERS -time_t mktime (); +__RCSID("$NetBSD: strftime.c,v 1.8 1999/02/07 17:33:30 augustss Exp $"); #endif +#endif /* LIBC_SCCS and not lint */ -#if defined(HAVE_TZNAME) -extern char *tzname[2]; -#endif - -/* Types of padding for numbers in date and time. */ -enum padding -{ - none, blank, zero -}; +#include <string.h> +#include <time.h> -static char const* const days[] = -{ - "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" +/* begin krb5 hack - replace stuff that would come from netbsd libc */ +#undef _CurrentTimeLocale +#define _CurrentTimeLocale (&dummy_locale_info) + +struct dummy_locale_info_t { + char d_t_fmt[15]; + char t_fmt_ampm[12]; + char t_fmt[9]; + char d_fmt[9]; + char day[7][10]; + char abday[7][4]; + char mon[12][10]; + char abmon[12][4]; + char am_pm[2][3]; }; - -static char const * const months[] = -{ - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" +static const struct dummy_locale_info_t dummy_locale_info = { + "%a %b %d %X %Y", /* %c */ + "%I:%M:%S %p", /* %r */ + "%H:%M:%S", /* %X */ + "%m/%d/%y", /* %x */ + { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", + "Saturday" }, + { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }, + { "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" }, + { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }, + { "AM", "PM" }, }; +#undef TM_YEAR_BASE +#define TM_YEAR_BASE 1900 + +#undef DAYSPERLYEAR +#define DAYSPERLYEAR 366 +#undef DAYSPERNYEAR +#define DAYSPERNYEAR 365 +#undef DAYSPERWEEK +#define DAYSPERWEEK 7 +#undef isleap +#define isleap(N) ((N % 4) == 0 && (N % 100 != 0 || N % 400 == 0)) +#undef tzname +#define tzname my_tzname +static const char *const tzname[2] = { 0, 0 }; +#undef tzset +#define tzset() +#undef __P +#define __P(X) X /* we already require ansi c in this tree */ +/* end krb5 hack */ + +static int _add __P((const char *, char **, const char *)); +static int _conv __P((int, int, int, char **, const char *)); +static int _secs __P((const struct tm *, char **, const char *)); +static size_t _fmt __P((const char *, const struct tm *, char **, + const char *)); -/* Add character C to STRING and increment LENGTH, - unless LENGTH would exceed MAX. */ - -#define add_char(c) \ - do \ - { \ - if (length + 1 <= max) \ - string[length++] = (c); \ - } \ - while (0) - -/* Add a 2 digit number to STRING, padding if specified. - Return the number of characters added, up to MAX. */ - -static int -add_num2 (string, num, max, pad) - char *string; - int num; - int max; - enum padding pad; -{ - int top = num / 10; - int length = 0; - - if (top == 0 && pad == blank) - add_char (' '); - else if (top != 0 || pad == zero) - add_char (top + '0'); - add_char (num % 10 + '0'); - return length; -} - -/* Add a 3 digit number to STRING, padding if specified. - Return the number of characters added, up to MAX. */ - -static int -add_num3 (string, num, max, pad) - char *string; - int num; - int max; - enum padding pad; +size_t +strftime(s, maxsize, format, t) + char *s; + size_t maxsize; + const char *format; + const struct tm *t; { - int top = num / 100; - int mid = (num - top * 100) / 10; - int length = 0; - - if (top == 0 && pad == blank) - add_char (' '); - else if (top != 0 || pad == zero) - add_char (top + '0'); - if (mid == 0 && top == 0 && pad == blank) - add_char (' '); - else if (mid != 0 || top != 0 || pad == zero) - add_char (mid + '0'); - add_char (num % 10 + '0'); - return length; + char *pt; + + tzset(); + if (maxsize < 1) + return (0); + + pt = s; + if (_fmt(format, t, &pt, s + maxsize)) { + *pt = '\0'; + return (pt - s); + } else + return (0); } -/* Like strncpy except return the number of characters copied. */ - -static int -add_str (to, from, max) - char *to; - const char *from; - int max; +#define SUN_WEEK(t) (((t)->tm_yday + 7 - \ + ((t)->tm_wday)) / 7) +#define MON_WEEK(t) (((t)->tm_yday + 7 - \ + ((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7) + +static size_t +_fmt(format, t, pt, ptlim) + const char *format; + const struct tm *t; + char **pt; + const char * const ptlim; { - int i; - - for (i = 0; from[i] && i <= max; ++i) - to[i] = from[i]; - return i; + for (; *format; ++format) { + if (*format == '%') { + ++format; + if (*format == 'E') { + /* Alternate Era */ + ++format; + } else if (*format == 'O') { + /* Alternate numeric symbols */ + ++format; + } + switch (*format) { + case '\0': + --format; + break; + case 'A': + if (t->tm_wday < 0 || t->tm_wday > 6) + return (0); + if (!_add(_CurrentTimeLocale->day[t->tm_wday], + pt, ptlim)) + return (0); + continue; + + case 'a': + if (t->tm_wday < 0 || t->tm_wday > 6) + return (0); + if (!_add(_CurrentTimeLocale->abday[t->tm_wday], + pt, ptlim)) + return (0); + continue; + case 'B': + if (t->tm_mon < 0 || t->tm_mon > 11) + return (0); + if (!_add(_CurrentTimeLocale->mon[t->tm_mon], + pt, ptlim)) + return (0); + continue; + case 'b': + case 'h': + if (t->tm_mon < 0 || t->tm_mon > 11) + return (0); + if (!_add(_CurrentTimeLocale->abmon[t->tm_mon], + pt, ptlim)) + return (0); + continue; + case 'C': + if (!_conv((t->tm_year + TM_YEAR_BASE) / 100, + 2, '0', pt, ptlim)) + return (0); + continue; + case 'c': + if (!_fmt(_CurrentTimeLocale->d_t_fmt, t, pt, + ptlim)) + return (0); + continue; + case 'D': + if (!_fmt("%m/%d/%y", t, pt, ptlim)) + return (0); + continue; + case 'd': + if (!_conv(t->tm_mday, 2, '0', pt, ptlim)) + return (0); + continue; + case 'e': + if (!_conv(t->tm_mday, 2, ' ', pt, ptlim)) + return (0); + continue; + case 'H': + if (!_conv(t->tm_hour, 2, '0', pt, ptlim)) + return (0); + continue; + case 'I': + if (!_conv(t->tm_hour % 12 ? + t->tm_hour % 12 : 12, 2, '0', pt, ptlim)) + return (0); + continue; + case 'j': + if (!_conv(t->tm_yday + 1, 3, '0', pt, ptlim)) + return (0); + continue; + case 'k': + if (!_conv(t->tm_hour, 2, ' ', pt, ptlim)) + return (0); + continue; + case 'l': + if (!_conv(t->tm_hour % 12 ? + t->tm_hour % 12: 12, 2, ' ', pt, ptlim)) + return (0); + continue; + case 'M': + if (!_conv(t->tm_min, 2, '0', pt, ptlim)) + return (0); + continue; + case 'm': + if (!_conv(t->tm_mon + 1, 2, '0', pt, ptlim)) + return (0); + continue; + case 'n': + if (!_add("\n", pt, ptlim)) + return (0); + continue; + case 'p': + if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour + >= 12], pt, ptlim)) + return (0); + continue; + case 'R': + if (!_fmt("%H:%M", t, pt, ptlim)) + return (0); + continue; + case 'r': + if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t, pt, + ptlim)) + return (0); + continue; + case 'S': + if (!_conv(t->tm_sec, 2, '0', pt, ptlim)) + return (0); + continue; + case 's': + if (!_secs(t, pt, ptlim)) + return (0); + continue; + case 'T': + if (!_fmt("%H:%M:%S", t, pt, ptlim)) + return (0); + continue; + case 't': + if (!_add("\t", pt, ptlim)) + return (0); + continue; + case 'U': + if (!_conv(SUN_WEEK(t), 2, '0', pt, ptlim)) + return (0); + continue; + case 'u': + if (!_conv(t->tm_wday ? t->tm_wday : 7, 1, '0', + pt, ptlim)) + return (0); + continue; + case 'V': /* ISO 8601 week number */ + case 'G': /* ISO 8601 year (four digits) */ + case 'g': /* ISO 8601 year (two digits) */ +/* +** From Arnold Robbins' strftime version 3.0: "the week number of the +** year (the first Monday as the first day of week 1) as a decimal number +** (01-53)." +** (ado, 1993-05-24) +** +** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn: +** "Week 01 of a year is per definition the first week which has the +** Thursday in this year, which is equivalent to the week which contains +** the fourth day of January. In other words, the first week of a new year +** is the week which has the majority of its days in the new year. Week 01 +** might also contain days from the previous year and the week before week +** 01 of a year is the last week (52 or 53) of the previous year even if +** it contains days from the new year. A week starts with Monday (day 1) +** and ends with Sunday (day 7). For example, the first week of the year +** 1997 lasts from 1996-12-30 to 1997-01-05..." +** (ado, 1996-01-02) +*/ + { + int year; + int yday; + int wday; + int w; + + year = t->tm_year + TM_YEAR_BASE; + yday = t->tm_yday; + wday = t->tm_wday; + for ( ; ; ) { + int len; + int bot; + int top; + + len = isleap(year) ? + DAYSPERLYEAR : + DAYSPERNYEAR; + /* + ** What yday (-3 ... 3) does + ** the ISO year begin on? + */ + bot = ((yday + 11 - wday) % + DAYSPERWEEK) - 3; + /* + ** What yday does the NEXT + ** ISO year begin on? + */ + top = bot - + (len % DAYSPERWEEK); + if (top < -3) + top += DAYSPERWEEK; + top += len; + if (yday >= top) { + ++year; + w = 1; + break; + } + if (yday >= bot) { + w = 1 + ((yday - bot) / + DAYSPERWEEK); + break; + } + --year; + yday += isleap(year) ? + DAYSPERLYEAR : + DAYSPERNYEAR; + } +#ifdef XPG4_1994_04_09 + if ((w == 52 + && t->tm_mon == TM_JANUARY) + || (w == 1 + && t->tm_mon == TM_DECEMBER)) + w = 53; +#endif /* defined XPG4_1994_04_09 */ + if (*format == 'V') { + if (!_conv(w, 2, '0', + pt, ptlim)) + return (0); + } else if (*format == 'g') { + if (!_conv(year % 100, 2, '0', + pt, ptlim)) + return (0); + } else if (!_conv(year, 4, '0', + pt, ptlim)) + return (0); + } + continue; + case 'W': + if (!_conv(MON_WEEK(t), 2, '0', pt, ptlim)) + return (0); + continue; + case 'w': + if (!_conv(t->tm_wday, 1, '0', pt, ptlim)) + return (0); + continue; + case 'x': + if (!_fmt(_CurrentTimeLocale->d_fmt, t, pt, + ptlim)) + return (0); + continue; + case 'X': + if (!_fmt(_CurrentTimeLocale->t_fmt, t, pt, + ptlim)) + return (0); + continue; + case 'y': + if (!_conv((t->tm_year + TM_YEAR_BASE) % 100, + 2, '0', pt, ptlim)) + return (0); + continue; + case 'Y': + if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0', + pt, ptlim)) + return (0); + continue; + case 'Z': + if (tzname[t->tm_isdst ? 1 : 0] && + !_add(tzname[t->tm_isdst ? 1 : 0], pt, + ptlim)) + return (0); + continue; + case '%': + /* + * X311J/88-090 (4.12.3.5): if conversion char is + * undefined, behavior is undefined. Print out the + * character itself as printf(3) does. + */ + default: + break; + } + } + if (*pt == ptlim) + return (0); + *(*pt)++ = *format; + } + return (ptlim - *pt); } static int -add_num_time_t (string, max, num) - char *string; - int max; - time_t num; +_secs(t, pt, ptlim) + const struct tm *t; + char **pt; + const char * const ptlim; { - /* This buffer is large enough to hold the character representation - (including the trailing NUL) of any unsigned decimal quantity - whose binary representation fits in 128 bits. */ - char buf[40]; - int length; - - if (sizeof (num) > 16) - abort (); - sprintf (buf, "%lu", (unsigned long) num); - length = add_str (string, buf, max); - return length; + char buf[15]; + time_t s; + char *p; + struct tm tmp; + + buf[sizeof (buf) - 1] = '\0'; + /* Make a copy, mktime(3) modifies the tm struct. */ + tmp = *t; + s = mktime(&tmp); + for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10) + *p-- = (char)(s % 10 + '0'); + return (_add(++p, pt, ptlim)); } -/* Return the week in the year of the time in TM, with the weeks - starting on Sundays. */ - static int -sun_week (tm) - struct tm *tm; +_conv(n, digits, pad, pt, ptlim) + int n, digits; + int pad; + char **pt; + const char * const ptlim; { - int dl; - - /* Set `dl' to the day in the year of the last day of the week previous - to the one containing the day specified in TM. If the day specified - in TM is in the first week of the year, `dl' will be negative or 0. - Otherwise, calculate the number of complete weeks before our week - (dl / 7) and add any partial week at the start of the year (dl % 7). */ - dl = tm->tm_yday - tm->tm_wday; - return dl <= 0 ? 0 : dl / 7 + (dl % 7 != 0); + char buf[10]; + char *p; + + buf[sizeof (buf) - 1] = '\0'; + for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits) + *p-- = n % 10 + '0'; + while (p > buf && digits-- > 0) + *p-- = pad; + return (_add(++p, pt, ptlim)); } -/* Return the week in the year of the time in TM, with the weeks - starting on Mondays. */ - static int -mon_week (tm) - struct tm *tm; -{ - int dl, wday; - - if (tm->tm_wday == 0) - wday = 6; - else - wday = tm->tm_wday - 1; - dl = tm->tm_yday - wday; - return dl <= 0 ? 0 : dl / 7 + (dl % 7 != 0); -} - -#if !defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME) -char * -zone_name (tp) - struct tm *tp; +_add(str, pt, ptlim) + const char *str; + char **pt; + const char * const ptlim; { - char *timezone (); - struct timeval tv; - struct timezone tz; - - gettimeofday (&tv, &tz); - return timezone (tz.tz_minuteswest, tp->tm_isdst); -} -#endif - -/* Format the time given in TM according to FORMAT, and put the - results in STRING. - Return the number of characters (not including terminating null) - that were put into STRING, or 0 if the length would have - exceeded MAX. */ - -size_t -strftime (string, max, format, tm) - char *string; - size_t max; - const char *format; - const struct tm *tm; -{ - enum padding pad; /* Type of padding to apply. */ - size_t length = 0; /* Characters put in STRING so far. */ - - for (; *format && length < max; ++format) - { - if (*format != '%') - add_char (*format); - else - { - ++format; - /* Modifiers: */ - if (*format == '-') - { - pad = none; - ++format; - } - else if (*format == '_') - { - pad = blank; - ++format; - } - else - pad = zero; - - switch (*format) - { - /* Literal character fields: */ - case 0: - case '%': - add_char ('%'); - break; - case 'n': - add_char ('\n'); - break; - case 't': - add_char ('\t'); - break; - default: - add_char (*format); - break; - - /* Time fields: */ - case 'H': - case 'k': - length += - add_num2 (&string[length], tm->tm_hour, max - length, - *format == 'H' ? pad : blank); - break; - case 'I': - case 'l': - { - int hour12; - - if (tm->tm_hour == 0) - hour12 = 12; - else if (tm->tm_hour > 12) - hour12 = tm->tm_hour - 12; - else - hour12 = tm->tm_hour; - length += - add_num2 (&string[length], hour12, max - length, - *format == 'I' ? pad : blank); - } - break; - case 'M': - length += - add_num2 (&string[length], tm->tm_min, max - length, pad); - break; - case 'p': - if (tm->tm_hour < 12) - add_char ('A'); - else - add_char ('P'); - add_char ('M'); - break; - case 'r': - length += - strftime (&string[length], max - length, "%I:%M:%S %p", tm); - break; - case 'R': - length += - strftime (&string[length], max - length, "%H:%M", tm); - break; - - case 's': - { - struct tm writable_tm; - writable_tm = *tm; - length += add_num_time_t (&string[length], max - length, - mktime (&writable_tm)); - } - break; - - case 'S': - length += - add_num2 (&string[length], tm->tm_sec, max - length, pad); - break; - case 'T': - length += - strftime (&string[length], max - length, "%H:%M:%S", tm); - break; - case 'X': - length += - strftime (&string[length], max - length, "%H:%M:%S", tm); - break; - case 'Z': -#ifdef HAVE_TM_ZONE - length += add_str (&string[length], tm->tm_zone, max - length); -#else -#ifdef HAVE_TZNAME - if (tm->tm_isdst && tzname[1] && *tzname[1]) - length += add_str (&string[length], tzname[1], max - length); - else - length += add_str (&string[length], tzname[0], max - length); -#else - length += add_str (&string[length], zone_name (tm), max - length); -#endif -#endif - break; - /* Date fields: */ - case 'a': - add_char (days[tm->tm_wday][0]); - add_char (days[tm->tm_wday][1]); - add_char (days[tm->tm_wday][2]); - break; - case 'A': - length += - add_str (&string[length], days[tm->tm_wday], max - length); - break; - case 'b': - case 'h': - add_char (months[tm->tm_mon][0]); - add_char (months[tm->tm_mon][1]); - add_char (months[tm->tm_mon][2]); - break; - case 'B': - length += - add_str (&string[length], months[tm->tm_mon], max - length); - break; - case 'c': - length += - strftime (&string[length], max - length, - "%a %b %d %H:%M:%S %Z %Y", tm); - break; - case 'C': - length += - add_num2 (&string[length], (tm->tm_year + 1900) / 100, - max - length, pad); - break; - case 'd': - length += - add_num2 (&string[length], tm->tm_mday, max - length, pad); - break; - case 'e': - length += - add_num2 (&string[length], tm->tm_mday, max - length, blank); - break; - case 'D': - length += - strftime (&string[length], max - length, "%m/%d/%y", tm); - break; - case 'j': - length += - add_num3 (&string[length], tm->tm_yday + 1, max - length, pad); - break; - case 'm': - length += - add_num2 (&string[length], tm->tm_mon + 1, max - length, pad); - break; - case 'U': - length += - add_num2 (&string[length], sun_week (tm), max - length, pad); - break; - case 'w': - add_char (tm->tm_wday + '0'); - break; - case 'W': - length += - add_num2 (&string[length], mon_week (tm), max - length, pad); - break; - case 'x': - length += - strftime (&string[length], max - length, "%m/%d/%y", tm); - break; - case 'y': - length += - add_num2 (&string[length], tm->tm_year % 100, - max - length, pad); - break; - case 'Y': - add_char ((tm->tm_year + 1900) / 1000 + '0'); - length += - add_num3 (&string[length], - (1900 + tm->tm_year) % 1000, max - length, zero); - break; - } + for (;; ++(*pt)) { + if (*pt == ptlim) + return (0); + if ((**pt = *str++) == '\0') + return (1); } - } - add_char (0); - return length - 1; } diff --git a/src/kadmin/ktutil/ChangeLog b/src/kadmin/ktutil/ChangeLog index fbd4611..8218363 100644 --- a/src/kadmin/ktutil/ChangeLog +++ b/src/kadmin/ktutil/ChangeLog @@ -1,3 +1,8 @@ +2000-05-19 Ken Raeburn <raeburn@mit.edu> + + * ktutil_funcs.c (ktutil_write_keytab): Reject a filename that's + too long. + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/kadmin/ktutil/ktutil_funcs.c b/src/kadmin/ktutil/ktutil_funcs.c index d4c0ce9..c39173f 100644 --- a/src/kadmin/ktutil/ktutil_funcs.c +++ b/src/kadmin/ktutil/ktutil_funcs.c @@ -317,7 +317,9 @@ krb5_error_code ktutil_write_keytab(context, list, name) krb5_error_code retval = 0; strcpy(ktname, "WRFILE:"); - strncat(ktname, name, MAXPATHLEN); + if (strlen (name) >= MAXPATHLEN) + return ENAMETOOLONG; + strncat (ktname, name, MAXPATHLEN); retval = krb5_kt_resolve(context, ktname, &kt); if (retval) return retval; diff --git a/src/kadmin/passwd/ChangeLog b/src/kadmin/passwd/ChangeLog index 3833b63..e7ce2d6 100644 --- a/src/kadmin/passwd/ChangeLog +++ b/src/kadmin/passwd/ChangeLog @@ -1,3 +1,7 @@ +2000-05-08 Nalin Dahyabhai <nalin@redhat.com> + + * xm_kpasswd.c (motif_com_err): Don't overflow buffer "buf". + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/kadmin/passwd/xm_kpasswd.c b/src/kadmin/passwd/xm_kpasswd.c index 0db1111..4232e3b 100644 --- a/src/kadmin/passwd/xm_kpasswd.c +++ b/src/kadmin/passwd/xm_kpasswd.c @@ -111,13 +111,15 @@ motif_com_err (whoami, code, fmt, args) if (whoami) { - strcpy(buf, whoami); - strcat(buf, ": "); + strncpy(buf, whoami, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + strncat(buf, ": ", sizeof(buf) - 1 - strlen(buf)); } if (code) { - strcat(buf, error_message(code)); - strcat(buf, " "); + buf[sizeof(buf) - 1] = '\0'; + strncat(buf, error_message(code), sizeof(buf) - 1 - strlen(buf)); + strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); } if (fmt) { diff --git a/src/kadmin/server/ChangeLog b/src/kadmin/server/ChangeLog index d5f932e..2727b96 100644 --- a/src/kadmin/server/ChangeLog +++ b/src/kadmin/server/ChangeLog @@ -1,3 +1,8 @@ +2000-05-23 Tom Yu <tlyu@mit.edu> + + * schpw.c (process_chpw_request): Add new argument to call to + chpass_principal_util() + 2000-03-16 Ken Raeburn <raeburn@mit.edu> Matt Crawford <crawdad@fnal.gov> diff --git a/src/kadmin/server/schpw.c b/src/kadmin/server/schpw.c index f246571..9de8116 100644 --- a/src/kadmin/server/schpw.c +++ b/src/kadmin/server/schpw.c @@ -229,7 +229,7 @@ process_chpw_request(context, server_handle, realm, s, keytab, sin, req, rep) ptr[clear.length] = '\0'; ret = kadm5_chpass_principal_util(server_handle, ticket->enc_part2->client, - ptr, NULL, strresult); + ptr, NULL, strresult, sizeof(strresult)); /* zap the password */ memset(clear.data, 0, clear.length); diff --git a/src/kadmin/testing/proto/ChangeLog b/src/kadmin/testing/proto/ChangeLog index e1fedaf..a69cf30 100644 --- a/src/kadmin/testing/proto/ChangeLog +++ b/src/kadmin/testing/proto/ChangeLog @@ -1,3 +1,13 @@ +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * kdc.conf.proto: Use des3 master key. + +2000-05-09 Ken Raeburn <raeburn@mit.edu> + + * krb5.conf.proto: Set dns_fallback=no. + + * kdc.conf.proto: Add des3 to supported_enctypes. + Wed Jan 21 12:44:25 1998 Ezra Peisach <epeisach@kangaroo.mit.edu> * kdc.conf.proto: Add kpasswd_port line so kadmind can start as diff --git a/src/kadmin/testing/proto/kdc.conf.proto b/src/kadmin/testing/proto/kdc.conf.proto index 69d6041..6f9edeb 100644 --- a/src/kadmin/testing/proto/kdc.conf.proto +++ b/src/kadmin/testing/proto/kdc.conf.proto @@ -11,7 +11,6 @@ dict_file = __K5ROOT__/ovsec_adm.dict kadmind_port = 1751 kpasswd_port = 1752 - master_key_type = des-cbc-crc - supported_enctypes = des-cbc-crc:normal des-cbc-crc:v4 des-cbc-md5:normal des-cbc-raw:normal + master_key_type = des3-hmac-sha1 + supported_enctypes = des3-hmac-sha1:normal des-cbc-crc:normal des-cbc-crc:v4 des-cbc-md5:normal des-cbc-raw:normal } - diff --git a/src/kadmin/testing/proto/krb5.conf.proto b/src/kadmin/testing/proto/krb5.conf.proto index a063815..5521267 100644 --- a/src/kadmin/testing/proto/krb5.conf.proto +++ b/src/kadmin/testing/proto/krb5.conf.proto @@ -1,6 +1,7 @@ [libdefaults] default_realm = __REALM__ default_keytab_name = FILE:__K5ROOT__/v5srvtab + dns_fallback = no [realms] __REALM__ = { diff --git a/src/kadmin/testing/util/ChangeLog b/src/kadmin/testing/util/ChangeLog index e3d88d1..08f1d23 100644 --- a/src/kadmin/testing/util/ChangeLog +++ b/src/kadmin/testing/util/ChangeLog @@ -1,3 +1,8 @@ +2000-05-23 Tom Yu <tlyu@mit.edu> + + * tcl_kadm5.c (tcl_kadm5_chpass_principal_util): Add new argument + to call to chpass_principal_util(). + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/kadmin/testing/util/tcl_kadm5.c b/src/kadmin/testing/util/tcl_kadm5.c index c334850..5d0a62b 100644 --- a/src/kadmin/testing/util/tcl_kadm5.c +++ b/src/kadmin/testing/util/tcl_kadm5.c @@ -1965,7 +1965,8 @@ int tcl_kadm5_chpass_principal_util(ClientData clientData, override_qual, #endif pw_ret_var ? &pw_ret : 0, - msg_ret_var ? msg_ret : 0); + msg_ret_var ? msg_ret : 0, + msg_ret_var ? sizeof(msg_ret) : 0); if (ret == KADM5_OK) { if (pw_ret_var && diff --git a/src/kadmin/v4server/ChangeLog b/src/kadmin/v4server/ChangeLog index c036eb8..fd06738 100644 --- a/src/kadmin/v4server/ChangeLog +++ b/src/kadmin/v4server/ChangeLog @@ -1,3 +1,30 @@ +2000-05-23 Ken Raeburn <raeburn@mit.edu> + + * admin_server.c (main, case 'r'): Reject realm name that's too + long. + + * acl_files.c (acl_load): Return error if name too long. + + * kadm_err.et (KADM_REALM_TOO_LONG): New error code. + * kadm_ser_wrap.c (kadm_ser_init): Return it instead of truncating + a too-long realm name. + +2000-05-23 Nalin Dahyabhai <nalin@redhat.com> + + * acl_files.c (acl_canonicalize_principal): If the principal name + would be too long, return a zero-length string to mark it as invalid. + (acl_load): Don't add the principal to the hash if it's invalid. + (acl_add): Don't check the principal if it's invalid. + (acl_delete): Don't try to delete the principal if it's invalid. + + * kadm_ser_wrap.c (kadm_ser_init): Truncate "server_parm.krbrlm" + if "realm" is too long. + +2000-05-23 Tom Yu <tlyu@mit.edu> + + * kadm_server.c (kadm_ser_cpw): Add new arg to call to + chpass_principal_util(). + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/kadmin/v4server/acl_files.c b/src/kadmin/v4server/acl_files.c index 22a0007..3e3bbe6 100644 --- a/src/kadmin/v4server/acl_files.c +++ b/src/kadmin/v4server/acl_files.c @@ -69,7 +69,8 @@ void acl_canonicalize_principal(principal, canon) char *principal; char *canon; { - char *dot, *atsign, *end; + char *dot, *atsign, *end, *canon_save = canon; + char realm[REALM_SZ]; int len; dot = strchr(principal, INST_SEP); @@ -94,18 +95,33 @@ char *canon; /* Get the principal name */ len = MIN(ANAME_SZ, COR(dot, COR(atsign, end)) - principal); - strncpy(canon, principal, len); - canon += len; + if(canon + len < canon_save + MAX_PRINCIPAL_SIZE) { + strncpy(canon, principal, len); + canon += len; + } else { + strcpy(canon, ""); + return; + } /* Add INST_SEP */ - *canon++ = INST_SEP; + if(canon + 1 < canon_save + MAX_PRINCIPAL_SIZE) { + *canon++ = INST_SEP; + } else { + strcpy(canon, ""); + return; + } /* Get the instance, if it exists */ if(dot != NULL) { ++dot; len = MIN(INST_SZ, COR(atsign, end) - dot); - strncpy(canon, dot, len); - canon += len; + if(canon + len < canon_save + MAX_PRINCIPAL_SIZE) { + strncpy(canon, dot, len); + canon += len; + } else { + strcpy(canon, ""); + return; + } } /* Add REALM_SEP */ @@ -116,11 +132,21 @@ char *canon; if(atsign != NULL) { ++atsign; len = MIN(REALM_SZ, end - atsign); - strncpy(canon, atsign, len); - canon += len; - *canon++ = '\0'; - } else if(krb_get_lrealm(canon, 1) != KSUCCESS) { - strcpy(canon, KRB_REALM); + if(canon + len + 1 < canon_save + MAX_PRINCIPAL_SIZE) { + strncpy(canon, atsign, len); + canon += len; + *canon++ = '\0'; + } else { + strcpy(canon, ""); + return; + } + } else if(krb_get_lrealm(realm, 1) != KSUCCESS) { + if(canon + strlen(realm) < canon_save + MAX_PRINCIPAL_SIZE) { + strcpy(canon, KRB_REALM); + } else { + strcpy(canon, ""); + return; + } } } @@ -399,7 +425,11 @@ char *name; } /* Set up the acl */ - strcpy(acl_cache[i].filename, name); + if (strlen (name) >= sizeof (acl_cache[i].filename) - 1) { + return -1; + } + strncpy(acl_cache[i].filename, name, sizeof(acl_cache[i].filename) - 1); + acl_cache[i].filename[sizeof(acl_cache[i].filename) - 1] = '\0'; if((acl_cache[i].fd = open(name, O_RDONLY, 0)) < 0) return(-1); /* Force reload */ acl_cache[i].acl = (struct hashtbl *) 0; @@ -426,7 +456,9 @@ char *name; while(fgets(buf, sizeof(buf), f) != NULL) { nuke_whitespace(buf); acl_canonicalize_principal(buf, canon); - add_hash(acl_cache[i].acl, canon); + if(strlen(canon) > 0) { + add_hash(acl_cache[i].acl, canon); + } } fclose(f); acl_cache[i].status = s; @@ -459,6 +491,9 @@ char *principal; acl_canonicalize_principal(principal, canon); + /* Is it an invalid principal name? */ + if(strlen(canon) == 0) return(0); + /* Is it there? */ if(acl_exact_match(acl, canon)) return(1); @@ -489,6 +524,9 @@ char *principal; acl_canonicalize_principal(principal, canon); + /* Is it an invalid principal name? */ + if(strlen(canon) == 0) return(-1); + if((new = acl_lock_file(acl)) == NULL) return(-1); if((acl_exact_match(acl, canon)) || (idx = acl_load(acl)) < 0) { @@ -523,6 +561,9 @@ char *principal; acl_canonicalize_principal(principal, canon); + /* Is it an invalid principal name? */ + if(strlen(canon) == 0) return(-1); + if((new = acl_lock_file(acl)) == NULL) return(-1); if((!acl_exact_match(acl, canon)) || (idx = acl_load(acl)) < 0) { diff --git a/src/kadmin/v4server/admin_server.c b/src/kadmin/v4server/admin_server.c index 90bf087..cd8742d 100644 --- a/src/kadmin/v4server/admin_server.c +++ b/src/kadmin/v4server/admin_server.c @@ -149,6 +149,10 @@ char *argv[]; fascist_cpw = 0; break; case 'r': + if (strlen (optarg) + 1 > REALM_SZ) { + com_err(argv[0], 0, "realm name `%s' too long", optarg); + exit(1); + } (void) strncpy(krbrlm, optarg, sizeof(krbrlm) - 1); break; case 'k': diff --git a/src/kadmin/v4server/kadm_err.et b/src/kadmin/v4server/kadm_err.et index a192730..07ab9da 100644 --- a/src/kadmin/v4server/kadm_err.et +++ b/src/kadmin/v4server/kadm_err.et @@ -54,4 +54,5 @@ ec KADM_INSECURE_PW, "Insecure password rejected" ec KADM_PW_MISMATCH, "Cleartext password and DES key did not match" ec KADM_NOT_SERV_PRINC, "Invalid principal for change srvtab request" +ec KADM_REALM_TOO_LONG, "Realm name too long" end diff --git a/src/kadmin/v4server/kadm_ser_wrap.c b/src/kadmin/v4server/kadm_ser_wrap.c index bca814d..42d27aa 100644 --- a/src/kadmin/v4server/kadm_ser_wrap.c +++ b/src/kadmin/v4server/kadm_ser_wrap.c @@ -47,7 +47,7 @@ kadm_ser_init(inter, realm, params) kadm_ser_init(inter, realm) int inter; /* interactive or from file */ char realm[]; -#endif +#endif { struct servent *sep; struct hostent *hp; @@ -64,7 +64,11 @@ kadm_ser_init(inter, realm) (void) strcpy(server_parm.sname, PWSERV_NAME); (void) strcpy(server_parm.sinst, KRB_MASTER); - (void) strcpy(server_parm.krbrlm, realm); + if (strlen (realm) > REALM_SZ) + return KADM_REALM_TOO_LONG; + (void) strncpy(server_parm.krbrlm, realm, sizeof(server_parm.krbrlm)-1); + server_parm.krbrlm[sizeof(server_parm.krbrlm) - 1] = '\0'; + if (krb5_425_conv_principal(kadm_context, server_parm.sname, server_parm.sinst, server_parm.krbrlm, &server_parm.sprinc)) diff --git a/src/kadmin/v4server/kadm_server.c b/src/kadmin/v4server/kadm_server.c index 687259b..886620f 100644 --- a/src/kadmin/v4server/kadm_server.c +++ b/src/kadmin/v4server/kadm_server.c @@ -309,7 +309,8 @@ int *outlen; *msg_ret = '\0'; } else { retval = kadm5_chpass_principal_util(kadm5_handle, user_princ, - pword, NULL, msg_ret); + pword, NULL, msg_ret, + sizeof(msg_ret)); msg_ptr = msg_ret; } (void) krb5_free_principal(kadm_context, user_princ); diff --git a/src/kadmin/v5passwdd/ChangeLog b/src/kadmin/v5passwdd/ChangeLog index a63cc97..1fedd80 100644 --- a/src/kadmin/v5passwdd/ChangeLog +++ b/src/kadmin/v5passwdd/ChangeLog @@ -1,3 +1,21 @@ +2000-05-24 Ken Raeburn <raeburn@mit.edu> + Ezra Peisach <epeisach@mit.edu> + + * proto_serv.c (proto_serv): Don't overflow err_str. Pass data + pointer and not a krb5_data to sprintf. Remove unused variable + adm_errmsg. Remove unused label done. Declare variable + mime_setting only if MIME_SUPPORTED is defined. Make variables + db_opened and kret volatile. + (proto_fmt_reply_msg): Unused variable deleted. + +2000-05-23 Tom Yu <tlyu@mit.edu> + + * kadm5_defs.h: Add argument for length of error string. + + * main.c (pwd_change): Add argument for length of error string. + + * proto_serv.c (proto_serv): Fix up call to pwd_change(). + 2000-02-28 Ezra Peisach <epeisach@mit.edu> * proto_serv.c (proto_serv): For error return,strdup the returned diff --git a/src/kadmin/v5passwdd/kadm5_defs.h b/src/kadmin/v5passwdd/kadm5_defs.h index 08650bd..17ec2e5 100644 --- a/src/kadmin/v5passwdd/kadm5_defs.h +++ b/src/kadmin/v5passwdd/kadm5_defs.h @@ -259,7 +259,8 @@ krb5_int32 pwd_change krb5_ticket *, krb5_data *, krb5_data *, - char [])); + char [], + int)); #if 0 diff --git a/src/kadmin/v5passwdd/main.c b/src/kadmin/v5passwdd/main.c index a9b381e..cec5bf8 100644 --- a/src/kadmin/v5passwdd/main.c +++ b/src/kadmin/v5passwdd/main.c @@ -230,7 +230,7 @@ krb5_error_code key_close_db(krb5_context context) krb5_int32 pwd_change(kcontext, debug_level, auth_context, ticket, - olddata, newdata, err_str) + olddata, newdata, err_str, err_str_len) krb5_context kcontext; int debug_level; krb5_auth_context auth_context; @@ -238,6 +238,7 @@ pwd_change(kcontext, debug_level, auth_context, ticket, krb5_data *olddata; krb5_data *newdata; char err_str[]; + int err_str_len; { kadm5_ret_t ret; krb5_int32 now; @@ -301,7 +302,7 @@ pwd_change(kcontext, debug_level, auth_context, ticket, principal, newdata->data, NULL, - err_str)) + err_str, err_str_len)) return(KRB5_ADM_PW_UNACCEPT); return(KRB5_ADM_SUCCESS); diff --git a/src/kadmin/v5passwdd/proto_serv.c b/src/kadmin/v5passwdd/proto_serv.c index 413c5ef..419f861 100644 --- a/src/kadmin/v5passwdd/proto_serv.c +++ b/src/kadmin/v5passwdd/proto_serv.c @@ -52,7 +52,6 @@ static const char *proto_rd_cmd_msg = "\004%d: cannot read administrative protoc static const char *proto_db_open_msg = "\004%d: cannot open database"; static const char *proto_db_close_msg = "\004%d: cannot close database"; static const char *proto_wr_reply_msg = "\004%d: cannot write administrative protocol reply"; -static const char *proto_fmt_reply_msg = "\004%d: cannot format administrative protocol reply"; extern char *programname; static int proto_proto_timeout = -1; @@ -109,7 +108,7 @@ proto_serv(kcontext, my_id, cl_sock, sv_p, cl_p) void *sv_p; void *cl_p; { - krb5_error_code kret; + volatile krb5_error_code kret; struct sockaddr_in *cl_addr; struct sockaddr_in *sv_addr; @@ -127,12 +126,14 @@ proto_serv(kcontext, my_id, cl_sock, sv_p, cl_p) #endif /* POSIX_SIGNALS */ char *curr_lang = (char *) NULL; +#ifdef MIME_SUPPORTED krb5_boolean mime_setting = 0; +#endif krb5_int32 num_args; krb5_data *arglist; - krb5_boolean db_opened; + volatile krb5_boolean db_opened; cl_addr = (struct sockaddr_in *) cl_p; sv_addr = (struct sockaddr_in *) sv_p; @@ -286,6 +287,7 @@ proto_serv(kcontext, my_id, cl_sock, sv_p, cl_p) */ while (1) { krb5_int32 cmd_error; + /* If this size changed, change the sprintf below */ char err_str[1024]; krb5_int32 cmd_repl_ncomps; krb5_data *cmd_repl_complist; @@ -412,7 +414,8 @@ proto_serv(kcontext, my_id, cl_sock, sv_p, cl_p) ticket, &arglist[1], &arglist[2], - &err_str); + err_str, + sizeof(err_str)); } else { DPRINT(DEBUG_REQUESTS, proto_debug_level, @@ -732,7 +735,7 @@ proto_serv(kcontext, my_id, cl_sock, sv_p, cl_p) ("> %d:UNKNOWN command %s\n", my_id, arglist[0].data)); cmd_error = KRB5_ADM_CMD_UNKNOWN; - sprintf(err_str, "Command %s not supported.", arglist[0]); + sprintf(err_str, "Command %-.900s not supported", arglist[0].data); /* XXX Knows size of err_str. */ } } else { @@ -770,7 +773,6 @@ proto_serv(kcontext, my_id, cl_sock, sv_p, cl_p) } } else { - char *adm_errmsg; krb5_data reply_comps; reply_comps.data = err_str; @@ -858,7 +860,6 @@ proto_serv(kcontext, my_id, cl_sock, sv_p, cl_p) key_close_db(kcontext); close(cl_sock); - done: DPRINT(DEBUG_CALLS, proto_debug_level, ("X proto_serv() = %d\n", kret)); return(kret); } diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog index d0bbda2..8d9be44 100644 --- a/src/kdc/ChangeLog +++ b/src/kdc/ChangeLog @@ -1,3 +1,39 @@ +2000-05-17 Tom Yu <tlyu@mit.edu> + + * kerberos_v4.c (process_v4): Zero out v4_pkt.mbz. + (kerberos_v4): Fix handling of APPL_REQUEST messages to deal with + ridiculously long realms, etc. Fix up some calls to + kerb_err_reply() to be more useful. Set req_*_ptr before any + possible calls to kerb_err_reply(). + +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * kdc_util.c (add_to_transited): Use strncpy/strncat when building + data in buffers so as not to overrun "prev", "current", and "exp". + * kerberos_v4.c (process_v4): Don't assume that the realm is null- + terminated. + (set_tgtkey): Truncate realm name if it's too long. + +2000-04-28 Ken Raeburn <raeburn@mit.edu> + Nalin Dahyabhai <nalin@redhat.com> + + * kdc_util.c (add_to_transited): Use strncpy/strncat when building + data in buffers. Fix some limit checks. + * kerberos_v4.c (kerb_err_reply): Use strncat so as not to overrun + error buffer. + +2000-04-22 Ken Raeburn <raeburn@mit.edu> + + * network.c: Include stddef.h. + (foreach_localaddr): Check each address against previously used + addresses, and skip duplicates, in case multiple interfaces have + the same address. + +2000-04-21 Ken Raeburn <raeburn@mit.edu> + + * network.c (foreach_localaddr): If called functions fail, drop + out of loop and return nonzero. + 2000-03-14 Ken Raeburn <raeburn@mit.edu> * sock2p.c: New file. diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c index f5a0016..e2c73a0 100644 --- a/src/kdc/kdc_util.c +++ b/src/kdc/kdc_util.c @@ -657,26 +657,30 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) clst = strlen(current) - 1; if (current[0] == ' ') { - strcpy(exp, current+1); + strncpy(exp, current+1, sizeof(exp) - 1); + exp[sizeof(exp) - 1] = '\0'; } else if ((current[0] == '/') && (prev[0] == '/')) { - strcpy(exp, prev); + strncpy(exp, prev, sizeof(exp) - 1); + exp[sizeof(exp) - 1] = '\0'; if (strlen(exp) + strlen(current) + 1 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } - strcat(exp, current); + strncat(exp, current, sizeof(exp) - 1 - strlen(exp)); } else if (current[clst] == '.') { - strcpy(exp, current); - if (strlen(exp) + strlen(current) + 1 >= MAX_REALM_LN) { + strncpy(exp, current, sizeof(exp) - 1); + exp[sizeof(exp) - 1] = '\0'; + if (strlen(exp) + strlen(prev) + 1 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } - strcat(exp, prev); + strncat(exp, prev, sizeof(exp) - 1 - strlen(exp)); } else { - strcpy(exp, current); + strncpy(exp, current, sizeof(exp) - 1); + exp[sizeof(exp) - 1] = '\0'; } /* read field into next */ @@ -718,11 +722,12 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) if ((next[nlst] != '.') && (next[0] != '/') && (pl = subrealm(exp, realm))) { added = TRUE; + current[sizeof(current) - 1] = '\0'; if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } - strcat(current, ","); + strncat(current, ",", sizeof(current) - 1 - strlen(current)); if (pl > 0) { strncat(current, realm, pl); } @@ -762,19 +767,22 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } - strcat(current, " "); + strncat(current, " ", sizeof(current) - 1 - strlen(current)); + current[sizeof(current) - 1] = '\0'; } if (strlen(current) + strlen(realm) + 1 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } - strcat(current, realm); + strncat(current, realm, sizeof(current) - 1 - strlen(current)); + current[sizeof(current) - 1] = '\0'; } if (strlen(current) + (pl>0?pl:-pl) + 2 >= MAX_REALM_LN) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto fail; } - strcat(current,","); + strncat(current,",", sizeof(current) - 1 - strlen(current)); + current[sizeof(current) - 1] = '\0'; if (pl > 0) { strncat(current, exp, pl); } @@ -798,8 +806,10 @@ add_to_transited(tgt_trans, new_trans, tgs, client, server) strcat(trans, current); new_trans->length = strlen(trans) + 1; - strcpy(prev, exp); - strcpy(current, next); + strncpy(prev, exp, sizeof(prev) - 1); + prev[sizeof(prev) - 1] = '\0'; + strncpy(current, next, sizeof(current) - 1); + current[sizeof(current) - 1] = '\0'; } if (!added) { diff --git a/src/kdc/kerberos_v4.c b/src/kdc/kerberos_v4.c index f05452e..6629c3e 100644 --- a/src/kdc/kerberos_v4.c +++ b/src/kdc/kerberos_v4.c @@ -233,11 +233,11 @@ krb5_data **resp; return(retval); if (!*local_realm) { /* local-realm name already set up */ - /* XXX assumes realm is null-terminated! */ lrealm = master_princ->realm.data; - if (strlen(lrealm) < sizeof(local_realm)) - strcpy(local_realm, lrealm); - else + if (master_princ->realm.length < sizeof(local_realm)) { + memcpy(local_realm, lrealm, master_princ->realm.length); + local_realm[master_princ->realm.length] = '\0'; + } else retval = KRB5_CONFIG_NOTENUFSPACE; } /* convert client_fulladdr to client_sockaddr: @@ -256,6 +256,7 @@ krb5_data **resp; return KRB5KRB_ERR_FIELD_TOOLONG; } v4_pkt.length = pkt->length; + v4_pkt.mbz = 0; memcpy( v4_pkt.dat, pkt->data, pkt->length); kerberos_v4( &client_sockaddr, &v4_pkt); @@ -622,6 +623,9 @@ kerberos_v4(client, pkt) req_act_vno = req_version; + /* set these to point to something safe */ + req_name_ptr = req_inst_ptr = req_realm_ptr = ""; + /* check if disabled, but we tell client */ if (kdc_v4 == KDC_V4_DISABLE) { lt = klog(L_KRB_PERR, @@ -700,7 +704,7 @@ kerberos_v4(client, pkt) if ((i = check_princ(req_name_ptr, req_inst_ptr, 0, &a_name_data, &k5key, 0))) { - kerb_err_reply(client, pkt, i, lt); + kerb_err_reply(client, pkt, i, "check_princ failed"); a_name_data.key_low = a_name_data.key_high = 0; krb5_free_keyblock_contents(kdc_context, &k5key); return; @@ -715,7 +719,7 @@ kerberos_v4(client, pkt) /* this does all the checking */ if ((i = check_princ(service, instance, lifetime, &s_name_data, &k5key, 1))) { - kerb_err_reply(client, pkt, i, lt); + kerb_err_reply(client, pkt, i, "check_princ failed"); a_name_data.key_high = a_name_data.key_low = 0; s_name_data.key_high = s_name_data.key_low = 0; krb5_free_keyblock_contents(kdc_context, &k5key); @@ -806,19 +810,40 @@ kerberos_v4(client, pkt) tk->length = 0; k_flags = 0; /* various kerberos flags */ + auth->mbz = 0; /* pkt->mbz already zeroed */ auth->length = 4 + strlen((char *)pkt->dat + 3); + if (auth->length + 1 > MAX_KTXT_LEN) { + lt = klog(L_KRB_PERR, + "APPL request with realm length too long from %s", + inet_ntoa(client_host)); + kerb_err_reply(client, pkt, RD_AP_INCON, + "realm length too long"); + return; + } + auth->length += (int) *(pkt->dat + auth->length) + (int) *(pkt->dat + auth->length + 1) + 2; + if (auth->length > MAX_KTXT_LEN) { + lt = klog(L_KRB_PERR, + "APPL request with funky tkt or req_id length from %s", + inet_ntoa(client_host)); + kerb_err_reply(client, pkt, RD_AP_INCON, + "funky tkt or req_id length"); + return; + } memcpy(auth->dat, pkt->dat, auth->length); strncpy(tktrlm, (char *)auth->dat + 3, REALM_SZ); + tktrlm[REALM_SZ-1] = '\0'; kvno = (krb5_kvno)auth->dat[2]; if (set_tgtkey(tktrlm, kvno)) { lt = klog(L_ERR_UNK, "FAILED set_tgtkey realm %s, kvno %d. Host: %s ", tktrlm, kvno, inet_ntoa(client_host)); - kerb_err_reply(client, pkt, kerno, lt); + /* no better error code */ + kerb_err_reply(client, pkt, + KERB_ERR_PRINCIPAL_UNKNOWN, lt); return; } kerno = krb_rd_req(auth, "krbtgt", tktrlm, client_host.s_addr, @@ -863,7 +888,7 @@ kerberos_v4(client, pkt) kerno = check_princ(service, instance, req_life, &s_name_data, &k5key, 1); if (kerno) { - kerb_err_reply(client, pkt, kerno, lt); + kerb_err_reply(client, pkt, kerno, "check_princ failed"); s_name_data.key_high = s_name_data.key_low = 0; krb5_free_keyblock_contents(kdc_context, &k5key); return; @@ -968,7 +993,7 @@ kerb_err_reply(client, pkt, err, string) static char e_msg[128]; strcpy(e_msg, "\nKerberos error -- "); - strcat(e_msg, string); + strncat(e_msg, string, sizeof(e_msg) - 1 - 19); cr_err_reply(e_pkt, req_name_ptr, req_inst_ptr, req_realm_ptr, req_time_ws, err, e_msg); krb4_sendto(f, (char *) e_pkt->dat, e_pkt->length, 0, @@ -1127,7 +1152,8 @@ set_tgtkey(r, kvno) if (!K4KDC_ENCTYPE_OK(k5key.enctype)) { krb_set_key_krb5(kdc_context, &k5key); - strcpy(lastrealm, r); + strncpy(lastrealm, r, sizeof(lastrealm) - 1); + lastrealm[sizeof(lastrealm) - 1] = '\0'; last_kvno = kvno; } else { /* unseal tgt key from master key */ @@ -1136,7 +1162,8 @@ set_tgtkey(r, kvno) kdb_encrypt_key(key, key, master_key, master_key_schedule, DECRYPT); krb_set_key((char *) key, 0); - strcpy(lastrealm, r); + strncpy(lastrealm, r, sizeof(lastrealm) - 1); + lastrealm[sizeof(lastrealm) - 1] = '\0'; last_kvno = kvno; } krb5_free_keyblock_contents(kdc_context, &k5key); diff --git a/src/kdc/network.c b/src/kdc/network.c index 502682a..a91fc95 100644 --- a/src/kdc/network.c +++ b/src/kdc/network.c @@ -1,7 +1,7 @@ /* * kdc/network.c * - * Copyright 1990 by the Massachusetts Institute of Technology. + * Copyright 1990,2000 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. @@ -35,6 +35,7 @@ #include <sys/ioctl.h> #include <syslog.h> +#include <stddef.h> #include <ctype.h> #ifdef HAVE_NETINET_IN_H #include <sys/types.h> @@ -120,13 +121,14 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) int (*betweenfn) (void *); int (*pass2fn) (void *, struct sockaddr *); { - struct ifreq *ifr, ifreq; + struct ifreq *ifr, ifreq, *ifr2; struct ifconf ifc; - int s, code, n, i; + int s, code, n, i, j; int est_if_count = 8, est_ifreq_size; char *buf = 0; size_t current_buf_size = 0; - + int fail = 0; + s = socket (USE_AF, USE_TYPE, USE_PROTO); if (s < 0) return SOCKET_ERRNO; @@ -184,6 +186,7 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) continue; } + #ifdef IFF_LOOPBACK /* None of the current callers want loopback addresses. */ if (ifreq.ifr_flags & IFF_LOOPBACK) @@ -193,13 +196,32 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) if (!(ifreq.ifr_flags & IFF_UP)) goto skip; + /* Make sure we didn't process this address already. */ + for (j = 0; j < i; j += ifreq_size(*ifr2)) { + ifr2 = (struct ifreq *)((caddr_t) ifc.ifc_buf+j); + if (ifr2->ifr_name[0] == 0) + continue; + if (ifr2->ifr_addr.sa_family == ifr->ifr_addr.sa_family + && ifreq_size (*ifr) == ifreq_size (*ifr2) + /* Compare address info. If this isn't good enough -- + i.e., if random padding bytes turn out to differ + when the addresses are the same -- then we'll have + to do it on a per address family basis. */ + && !memcmp (&ifr2->ifr_addr.sa_data, &ifr->ifr_addr.sa_data, + (ifreq_size (*ifr) + - offsetof (struct ifreq, ifr_addr.sa_data)))) + goto skip; + } + if ((*pass1fn) (data, &ifr->ifr_addr)) { - abort (); + fail = 1; + goto punt; } } if (betweenfn && (*betweenfn)(data)) { - abort (); + fail = 1; + goto punt; } if (pass2fn) @@ -211,13 +233,15 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) continue; if ((*pass2fn) (data, &ifr->ifr_addr)) { - abort (); + fail = 1; + goto punt; } } + punt: closesocket(s); free (buf); - return 0; + return fail; } struct socksetup { diff --git a/src/lib/ChangeLog b/src/lib/ChangeLog index b5abe94..3a8846c 100644 --- a/src/lib/ChangeLog +++ b/src/lib/ChangeLog @@ -1,3 +1,36 @@ +2000-06-02 Danilo Almeida <dalmeida@mit.edu> + + * win_glue.c (GetCallingAppVerInfo, krb5_vercheck): Use + APPVERINFO_SIZE-sized buffers instead of hard-coding a number + everywhere. Document the buffer size in funciton documentation. + + * krb5_32.def: Add krb5int_cc_default for the benefit of GSS API DLL. + +2000-05-23 Nalin Dahyabhai <nalin@redhat.com> + + * win_glue.c (GetCallingAppVerInfo): Don't overfill buffers + "AppTitle", "AppVer", and "AppIni". + +2000-05-15 Jeffrey Altman <jaltman@columbia.edu> + + * krb5_32.def -- Added exports for new public functions + + krb5_appdefault_string + krb5_appdefault_boolean + +2000-05-04 Danilo Almeida <dalmeida@mit.edu> + + * krb5_32.def: Reflect something closer to the reality of + what we would like to do for 1.3. + +2000-05-03 Nalin Dahyabhai <nalin@redhat.com> + + * win_glue.c (do_timebomb): Don't overflow buffer "buf". + +2000-04-29 Jeffrey Altman <jaltman@columbia.edu> + + * krb5_32.def: Add krb5_get_tgs_ktypes, krb5_free_ktypes for gssapi + 2000-03-15 Danilo Almeida <dalmeida@mit.edu> * krb5_32.def: Add krb5_get_prompt_types. diff --git a/src/lib/crypto/ChangeLog b/src/lib/crypto/ChangeLog index a48ec1f..5247eda 100644 --- a/src/lib/crypto/ChangeLog +++ b/src/lib/crypto/ChangeLog @@ -1,3 +1,7 @@ +2000-06-03 Tom Yu <tlyu@mit.edu> + + * Makefile.in(LIBMAJOR, LIBMINOR): Bump library version. + 2000-01-24 Tom Yu <tlyu@mit.edu> * crypto_libinit.c: Add terminating newline; use 0 and 1 instead diff --git a/src/lib/crypto/Makefile.in b/src/lib/crypto/Makefile.in index 71bddf5..64f19d1 100644 --- a/src/lib/crypto/Makefile.in +++ b/src/lib/crypto/Makefile.in @@ -106,8 +106,8 @@ SRCS=\ LIB=k5crypto -LIBMAJOR=2 -LIBMINOR=1 +LIBMAJOR=3 +LIBMINOR=0 RELDIR=crypto STOBJLISTS=crc32/OBJS.ST des/OBJS.ST dk/OBJS.ST enc_provider/OBJS.ST \ diff --git a/src/lib/crypto/dk/ChangeLog b/src/lib/crypto/dk/ChangeLog index 90e34f8..7908f56 100644 --- a/src/lib/crypto/dk/ChangeLog +++ b/src/lib/crypto/dk/ChangeLog @@ -1,3 +1,17 @@ +2000-06-03 Tom Yu <tlyu@mit.edu> + + * dk_encrypt.c (krb5_dk_encrypt, krb5_marc_dk_encrypt): Chain + ivecs. + + * dk_decrypt.c (krb5_dk_decrypt, krb5_marc_dk_decrypt): Chain + ivecs. + +2000-04-28 Ken Raeburn <raeburn@mit.edu> + + * derive.c (krb5_derive_key): If memory allocation fails, release + other allocated blocks before returning, instead of trying to + release them after returning. + 2000-01-21 Ken Raeburn <raeburn@mit.edu> * checksum.c (krb5_dk_make_checksum): enc_providers are now diff --git a/src/lib/crypto/dk/derive.c b/src/lib/crypto/dk/derive.c index 8765605..dbd4a2a 100644 --- a/src/lib/crypto/dk/derive.c +++ b/src/lib/crypto/dk/derive.c @@ -51,14 +51,14 @@ krb5_derive_key(enc, inkey, outkey, in_constant) return(ENOMEM); if ((outblockdata = (unsigned char *) malloc(blocksize)) == NULL) { - return(ENOMEM); free(inblockdata); + return(ENOMEM); } if ((rawkey = (unsigned char *) malloc(keybytes)) == NULL) { - return(ENOMEM); free(outblockdata); free(inblockdata); + return(ENOMEM); } inblock.data = inblockdata; diff --git a/src/lib/crypto/dk/dk_decrypt.c b/src/lib/crypto/dk/dk_decrypt.c index d307761..d6e7c0d 100644 --- a/src/lib/crypto/dk/dk_decrypt.c +++ b/src/lib/crypto/dk/dk_decrypt.c @@ -41,7 +41,7 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output) { krb5_error_code ret; size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen; - unsigned char *plaindata, *kedata, *kidata, *cksum; + unsigned char *plaindata, *kedata, *kidata, *cksum, *cn; krb5_keyblock ke, ki; krb5_data d1, d2; unsigned char constantdata[K5CLENGTH]; @@ -108,6 +108,11 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output) if ((ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) != 0) goto cleanup; + if (ivec != NULL && ivec->length == blocksize) + cn = d1.data + d1.length - blocksize; + else + cn = NULL; + /* verify the hash */ d1.length = hashsize; @@ -134,6 +139,9 @@ krb5_dk_decrypt(enc, hash, key, usage, ivec, input, output) memcpy(output->data, d2.data+blocksize, output->length); + if (cn != NULL) + memcpy(ivec->data, cn, blocksize); + ret = 0; cleanup: @@ -163,7 +171,7 @@ krb5_marc_dk_decrypt(enc, hash, key, usage, ivec, input, output) { krb5_error_code ret; size_t hashsize, blocksize, keybytes, keylength, enclen, plainlen; - unsigned char *plaindata, *kedata, *kidata, *cksum; + unsigned char *plaindata, *kedata, *kidata, *cksum, *cn; krb5_keyblock ke, ki; krb5_data d1, d2; unsigned char constantdata[K5CLENGTH]; @@ -230,6 +238,11 @@ krb5_marc_dk_decrypt(enc, hash, key, usage, ivec, input, output) if ((ret = ((*(enc->decrypt))(&ke, ivec, &d1, &d2))) != 0) goto cleanup; + if (ivec != NULL && ivec->length == blocksize) + cn = d1.data + d1.length - blocksize; + else + cn = NULL; + /* verify the hash */ d1.length = hashsize; @@ -264,6 +277,9 @@ krb5_marc_dk_decrypt(enc, hash, key, usage, ivec, input, output) memcpy(output->data, d2.data+4+blocksize, output->length); + if (cn != NULL) + memcpy(ivec->data, cn, blocksize); + ret = 0; cleanup: diff --git a/src/lib/crypto/dk/dk_encrypt.c b/src/lib/crypto/dk/dk_encrypt.c index 8627353..2bc2b6b 100644 --- a/src/lib/crypto/dk/dk_encrypt.c +++ b/src/lib/crypto/dk/dk_encrypt.c @@ -65,7 +65,7 @@ krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output) krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data d1, d2; - unsigned char *plaintext, *kedata, *kidata; + unsigned char *plaintext, *kedata, *kidata, *cn; krb5_keyblock ke, ki; /* allocate and set up plaintext and to-be-derived keys */ @@ -142,6 +142,11 @@ krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output) if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2)))) goto cleanup; + if (ivec != NULL && ivec->length == blocksize) + cn = d2.data + d2.length - blocksize; + else + cn = NULL; + /* hash the plaintext */ d2.length = enclen - plainlen; @@ -149,8 +154,14 @@ krb5_dk_encrypt(enc, hash, key, usage, ivec, input, output) output->length = enclen; - if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2))) + if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2))) { memset(d2.data, 0, d2.length); + goto cleanup; + } + + /* update ivec */ + if (cn != NULL) + memcpy(ivec->data, cn, blocksize); /* ret is set correctly by the prior call */ @@ -196,7 +207,7 @@ krb5_marc_dk_encrypt(enc, hash, key, usage, ivec, input, output) krb5_error_code ret; unsigned char constantdata[K5CLENGTH]; krb5_data d1, d2; - unsigned char *plaintext, *kedata, *kidata; + unsigned char *plaintext, *kedata, *kidata, *cn; krb5_keyblock ke, ki; /* allocate and set up plaintext and to-be-derived keys */ @@ -278,6 +289,11 @@ krb5_marc_dk_encrypt(enc, hash, key, usage, ivec, input, output) if ((ret = ((*(enc->encrypt))(&ke, ivec, &d1, &d2)))) goto cleanup; + if (ivec != NULL && ivec->length == blocksize) + cn = d2.data + d2.length - blocksize; + else + cn = NULL; + /* hash the plaintext */ d2.length = enclen - plainlen; @@ -285,8 +301,14 @@ krb5_marc_dk_encrypt(enc, hash, key, usage, ivec, input, output) output->length = enclen; - if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2))) + if ((ret = krb5_hmac(hash, &ki, 1, &d1, &d2))) { memset(d2.data, 0, d2.length); + goto cleanup; + } + + /* update ivec */ + if (cn != NULL) + memcpy(ivec->data, cn, blocksize); /* ret is set correctly by the prior call */ diff --git a/src/lib/crypto/old/ChangeLog b/src/lib/crypto/old/ChangeLog index cada473..74f994b 100644 --- a/src/lib/crypto/old/ChangeLog +++ b/src/lib/crypto/old/ChangeLog @@ -1,3 +1,9 @@ +2000-06-03 Tom Yu <tlyu@mit.edu> + + * old_encrypt.c (krb5_old_encrypt): Chain ivecs. + + * old_decrypt.c (krb5_old_decrypt): Chain ivecs. + 2000-01-21 Ken Raeburn <raeburn@mit.edu> * des_stringtokey.c (mit_des_string_to_key_int): Declare. diff --git a/src/lib/crypto/old/old_decrypt.c b/src/lib/crypto/old/old_decrypt.c index 1bcb0d3..bfbe56a 100644 --- a/src/lib/crypto/old/old_decrypt.c +++ b/src/lib/crypto/old/old_decrypt.c @@ -45,7 +45,7 @@ krb5_old_decrypt(enc, hash, key, usage, ivec, input, arg_output) { krb5_error_code ret; size_t blocksize, hashsize, plainsize; - unsigned char *cksumdata; + unsigned char *cksumdata, *cn; krb5_data output, cksum, crcivec; int alloced; @@ -82,6 +82,17 @@ krb5_old_decrypt(enc, hash, key, usage, ivec, input, arg_output) /* decrypt it */ + /* save last ciphertext block in case we decrypt in place */ + if (ivec != NULL && ivec->length == blocksize) { + cn = malloc(blocksize); + if (cn == NULL) { + ret = ENOMEM; + goto cleanup; + } + memcpy(cn, input->data + input->length - blocksize, blocksize); + } else + cn = NULL; + /* XXX this is gross, but I don't have much choice */ if ((key->enctype == ENCTYPE_DES_CBC_CRC) && (ivec == 0)) { crcivec.length = key->length; @@ -119,6 +130,10 @@ krb5_old_decrypt(enc, hash, key, usage, ivec, input, arg_output) } arg_output->length = plainsize; + /* update ivec */ + if (cn != NULL) + memcpy(ivec->data, cn, blocksize); + ret = 0; cleanup: @@ -127,6 +142,8 @@ cleanup: free(output.data); } + if (cn != NULL) + free(cn); memset(cksumdata, 0, hashsize); free(cksumdata); return(ret); diff --git a/src/lib/crypto/old/old_encrypt.c b/src/lib/crypto/old/old_encrypt.c index d90d0f8..8860ba5 100644 --- a/src/lib/crypto/old/old_encrypt.c +++ b/src/lib/crypto/old/old_encrypt.c @@ -55,6 +55,7 @@ krb5_old_encrypt(enc, hash, key, usage, ivec, input, output) krb5_error_code ret; size_t blocksize, hashsize, enclen; krb5_data datain, crcivec; + int real_ivec; (*(enc->block_size))(&blocksize); (*(hash->hash_size))(&hashsize); @@ -92,11 +93,17 @@ krb5_old_encrypt(enc, hash, key, usage, ivec, input, output) crcivec.length = key->length; crcivec.data = key->contents; ivec = &crcivec; - } + real_ivec = 0; + } else + real_ivec = 1; if ((ret = ((*(enc->encrypt))(key, ivec, output, output)))) goto cleanup; + /* update ivec */ + if (real_ivec && ivec != NULL && ivec->length == blocksize) + memcpy(ivec->data, output->data + output->length - blocksize, + blocksize); cleanup: if (ret) memset(output->data, 0, output->length); diff --git a/src/lib/crypto/prng.c b/src/lib/crypto/prng.c index 6d401a9..b22131e 100644 --- a/src/lib/crypto/prng.c +++ b/src/lib/crypto/prng.c @@ -158,4 +158,4 @@ void prng_cleanup (void) { free (random_state); inited = 0; -}
\ No newline at end of file +} diff --git a/src/lib/gssapi/ChangeLog b/src/lib/gssapi/ChangeLog index 1e0213f..060c2e7 100644 --- a/src/lib/gssapi/ChangeLog +++ b/src/lib/gssapi/ChangeLog @@ -1,3 +1,7 @@ +2000-06-03 Tom Yu <tlyu@mit.edu> + + * Makefile.in(LIBMINOR): Bump library version. + Tue Feb 22 10:23:19 2000 Ezra Peisach <epeisach@mit.edu> * Makefile.in (clean-unix): Add clean-libobjs. diff --git a/src/lib/gssapi/Makefile.in b/src/lib/gssapi/Makefile.in index bee2b85..20936da 100644 --- a/src/lib/gssapi/Makefile.in +++ b/src/lib/gssapi/Makefile.in @@ -24,7 +24,7 @@ SRCS=\ LIB=gssapi_krb5 LIBMAJOR=2 -LIBMINOR=1 +LIBMINOR=2 STOBJLISTS=OBJS.ST generic/OBJS.ST krb5/OBJS.ST SHLIB_EXPDEPS=\ $(TOPLIBD)/libkrb5$(SHLIBEXT) \ diff --git a/src/lib/gssapi/krb5/3des.txt b/src/lib/gssapi/krb5/3des.txt new file mode 100644 index 0000000..f39c6fc --- /dev/null +++ b/src/lib/gssapi/krb5/3des.txt @@ -0,0 +1,274 @@ +CAT Working Group K. Raeburn +Internet-draft MIT +Category: June xx, 2000 +Updates: RFC 1964 +Document: draft-raeburn-gssapi-krb5-3des-XX.txt + + Triple-DES Support for the Kerberos 5 GSSAPI Mechanism + +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 MIT Kerberos 5 release version 1.2 includes support for + triple-DES with key derivation [KrbRev]. Recent work by the EFF + [EFF] has demonstrated the vulnerability of single-DES mechanisms + to brute-force attacks by sufficiently motivated and well-funded + parties. + + The GSSAPI Kerberos 5 mechanism definition [GSSAPI-KRB5] + specifically enumerates encryption and checksum types, + independently of how such schemes may be used in Kerberos. In the + long run, a new Kerberos-based mechanism, which does not require + separately enumerating for the GSSAPI mechanism each of the various + encryption types defined by Kerberos, is a better approach. + Efforts to produce such a specification are under way. + + In the interest of providing increased security in the near term, + however, MIT is adding support for triple-DES to the existing + mechanism implementation we ship, as described here. + +2. New Algorithm Identifiers + + One new sealing algorithm is defined, for use in WRAP tokens: + + 02 00 - DES3-KD + + This algorithm uses triple-DES with key derivation, with a usage + value KG_USAGE_SEAL. Padding is still to 8-byte multiples, and the + IV for encrypting application data is zero. + + One new signing algorithm is defined, for use in MIC, Wrap, and + Delete tokens: + + 04 00 - HMAC SHA1 DES3-KD + + This algorithm generates an HMAC using SHA-1 and a derived DES3 key + with usage KG_USAGE_SIGN, as (should be described) in [KrbRev]. + [XXX: The current [KrbRev] description refers to out-of-date I-Ds + from Marc Horowitz. The text in [KrbRev] may be inadequate to + produce an interoperable implementation.] + + The checksum size for this algorithm is 20 octets. See section 4.3 + below for the use of checksum lengths of other than eight bytes. + +3. Key Derivation + + For purposes of key derivation, we add three new usage values to the + list defined in [KrbRev]; one for signing messages, one for + sealing messages, and one for encrypting sequence numbers: + + #define KG_USAGE_SEAL 22 + #define KG_USAGE_SIGN 23 + #define KG_USAGE_SEQ 24 + +4. Adjustments to Previous Definitions + +4.1. Quality of Protection + + The GSSAPI specification [GSSAPI] says that a zero QOP value + indicates the "default". The original specification for the + Kerberos 5 mechanism says that a zero QOP value (or a QOP value + with the appropriate bits clear) means DES encryption. + + Rather than continue to force the use of plain DES when the + application doesn't use mechanism-specific QOP values, the better + choice appears to be to redefine the DES QOP value as some non-zero + value, and define a triple-DES value as well. Then a zero value + continues to imply the default, which would be triple-DES + protection when given a triple-DES session key. + + Our values are: + + GSS_KRB5_INTEG_C_QOP_HMAC_SHA1 0x0004 + /* SHA-1 checksum encrypted with key derivation */ + + GSS_KRB5_CONF_C_QOP_DES 0x0100 + /* plain DES encryption */ + GSS_KRB5_CONF_C_QOP_DES3_KD 0x0200 + /* triple-DES with key derivation */ + + Rather than open the question of whether to specify means for + deriving a key of one type given a key of another type, and the + security implications of whether to generate a long key from a + shorter one, our implementation will simply return an error if the + QOP value specified does not correspond to the session key type. + + [XXX: Not implemented yet. Currently an error is reported for all + non-zero values. This should be changed before the release, so an + application can insist on getting no less than triple-DES + protection.] + +4.2. MIC Sequence Number Encryption + + The sequence numbers are encrypted in the context key (as defined + in [GSSAPI-KRB5] -- this will be either the Kerberos session key or + asubkey provided by the context initiator), using whatever + encryption system is designated by the type of that context key. + The IV is formed from the first N bytes of the SGN_CKSUM field, + where N is the number of bytes needed for the IV. (With all + algorithms described here and in [GSSAPI-KRB5], the checksum is at + least as large as the IV.) + +4.3. Message Layout + + Both MIC and Wrap tokens, as defined in [GSSAPI-KRB5], contain an + checksum field SGN_CKSUM. In [GSSAPI-KRB5], this field was + specified as being 8 bytes long. We now change this size to be + "defined by the checksum algorithm", and retroactively amend the + descriptions of all the checksum algorithms described in + [GSSAPI-KRB5] to explicitly specify 8-byte output. Application + data continues to immediately follow the checksum field in the Wrap + token. + + The revised message descriptions are thus: + + MIC: + + Byte no Name Description + 0..1 TOK_ID Identification field. + 2..3 SGN_ALG Integrity algorithm indicator. + 4..7 Filler Contains ff ff ff ff + 8..15 SND_SEQ Sequence number field. + 16..s+15 SGN_CKSUM Checksum of "to-be-signed data", + calculated according to algorithm + specified in SGN_ALG field. + + Wrap: + + 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. + 4..5 SEAL_ALG Sealing algorithm indicator. + 6..7 Filler Contains ff ff + 8..15 SND_SEQ Encrypted sequence number field. + 16..s+15 SGN_CKSUM Checksum of plaintext padded data, + calculated according to algorithm + specified in SGN_ALG field. + s+16..last Data encrypted or plaintext padded data + + Where "s" indicates the size of the checksum. + + As indicated above in section 2, we define the HMAC SHA1 DES3-KD + checksum algorithm to produce a 20-byte output, so encrypted data + begins at byte 36. + +5. Backwards Compatibility Considerations + + The context initiator should request of the KDC credentials using + session-key cryptosystem types supported by that implementation; if + the only types returned by the KDC are not supported by the + mechanism implementation, it should indicate a failure. This may + seem obvious, but early implementations of both Kerberos and the + GSSAPI Kerberos mechanism supported only DES keys, so the + cryptosystem compatibility question was easy to overlook. + + Under the current mechanism, no negotiation of algorithm types + occurs, so server-side (acceptor) implementations cannot request + that clients not use algorithm types not understood by the server. + However, administration of the server's Kerberos data has to be + done in communication with the KDC, and it is from the KDC that the + client will request credentials. The KDC could therefore be tasked + with limiting session keys for a given service to types actually + supported by the Kerberos and GSSAPI software on the server. + + This does have a drawback for cases where a service principal name + is used both for GSSAPI-based and non-GSSAPI-based communication, + if the GSSAPI implementation does not understand triple-DES but the + Kerberos implementation does. It means that triple-DES session + keys cannot be issued for that service principal, which keeps the + protection of non-GSSAPI services weaker than necessary. However, + in the most recent MIT releases thus far, while triple-DES support + has been present, it has required additional work to enable, so it + should not be in use for many services. + + It would also be possible to have clients attempt to get single-DES + session keys before trying to get triple-DES session keys, and have + the KDC refuse to issue the single-DES keys only for the most + critical of services, for which single-DES protection is considered + inadequate. However, that would eliminate the possibility of + connecting with the more secure cryptosystem to any service that + can be accessed with the weaker cryptosystem. + + We have chosen to go with the former approach, putting the burden + on the KDC administration and gaining the best protection possible + for GSSAPI services, possibly at the cost of protection of + non-GSSAPI Kerberos services running earlier versions of the + software. + [XXX: Actually, we haven't entirely decided and cast it in stone + yet, it's just what I've implemented; it's easy to change.] + +6. Security Considerations + + Various tradeoffs arise regarding the mixing of new and old + software, or GSSAPI-based and non-GSSAPI Kerberos authentication. + They are discussed in section 4. + +7. References + + [EFF] Electronic Frontier Foundation, "Cracking DES: Secrets of + Encryption Research, Wiretap Politics, and Chip Design", O'Reilly & + Associates, Inc., May, 1998. + + [GSSAPI] Linn, J., "Generic Security Service Application Program + Interface Version 2, Update 1", RFC 2743, January, 2000. + + [GSSAPI-KRB5] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", + RFC 1964, June, 1996. + + [KrbRev] Neuman, C., Kohl, J., Ts'o, T., "The Kerberos Network + Authentication Service (V5)", + draft-ietf-cat-kerberos-revisions-05.txt, March 10, 2000. + +8. Author's Address + + Kenneth Raeburn + Massachusetts Institute of Technology + 77 Massachusetts Avenue + Cambridge, MA 02139 + +9. Full Copyright Statement + + Copyright (C) The Internet Society (2000). 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." diff --git a/src/lib/gssapi/krb5/ChangeLog b/src/lib/gssapi/krb5/ChangeLog index 06639d4..a97570d 100644 --- a/src/lib/gssapi/krb5/ChangeLog +++ b/src/lib/gssapi/krb5/ChangeLog @@ -1,4 +1,107 @@ -2000-01-27 Ken Raeburn <raeburn@raeburn.org> +2000-06-09 Tom Yu <tlyu@mit.edu> + + * init_sec_context.c (get_credentials): The KDC as well as the + ccache may indicate that an enctype is not supported; reflect that + in the loop breakout condition. + +2000-06-07 Tom Yu <tlyu@mit.edu> + + * init_sec_context.c (get_credentials): Rework the enctype loop + again. + + * accept_sec_context.c (krb5_gss_accept_sec_context): Remove + explicit check of mech OID against credential. + +2000-06-04 Tom Yu <tlyu@mit.edu> + + * init_sec_context.c (get_credentials): Reverse sense of test; + break out of enctype loop if one succeeds. + +2000-06-03 Tom Yu <tlyu@mit.edu> + + * util_crypt.c (kg_encrypt): Copy ivec, since c_encrypt() now + updates ivecs. + (kg_decrypt): Copy ivec, since c_decrypt() now updates ivecs. + +2000-06-02 Ken Raeburn <raeburn@mit.edu> + + * init_sec_context.c (get_credentials): Don't check each enctype + against a list from the krb5 library; instead, just try to use it, + and go on to the next if the error code indicates we can't use it. + +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * gssapiP_krb5.h (KG_USAGE_SEQ): New value. + (enum qop): New type, derived from spec but currently not used. + * util_crypt.c (kg_encrypt, kg_decrypt): Added key derivation + usage value as an argument. Prototypes and callers updated; all + callers use KG_USAGE_SEAL, except KG_USAGE_SEQ when encrypting + sequence numbers. + * 3des.txt: New file. + +2000-5-19 Alexandra Ellwood <lxs@mit.edu> + + * acquire_cred.c: Changed to use krb5int_cc_default. This function + supports the Kerberos Login Library and pops up a dialog if the cache does + not contain valid tickets. This is used to automatically get a tgt before + obtaining service tickets. Note that this should be an internal function + because callers don't expect krb5_cc_default to pop up a dialog! + (We found this out the hard way :-) + +2000-05-03 Nalin Dahyabhai <nalin@redhat.com> + + * add_cred.c (krb5_gss_add_cred): Don't overflow buffers "ktboth" + or "ccboth". + +2000-04-21 Ken Raeburn <raeburn@mit.edu> + + * gssapiP_krb5.h (struct _krb5_gss_ctx_id_rec): Delete field + gsskrb5_version. + (struct _krb5_gss_cred_id_rec): Delete field rfcv2_mech. + * accept_sec_context.c, acquire_cred.c, add_cred.c, inq_cred.c, + k5seal.c, k5unseal.c, ser_ctx.c: + Delete krb5-mech2 support. + + * init_sec_context.c (get_credentials): Enctype argument is now a + pointer to a list of enctypes. Explicitly try each in order until + success or an error other than cryptosystem not being supported. + (krb5_gss_init_sec_context): Pass list of cryptosystems, starting + with 3DES. + + * gssapiP_krb5.h (enum sgn_alg, enum seal_alg): New types, + giving symbolic names for values from RFC 1964, a Microsoft win2k + I-D, and our proposed 3des-sha1 values. + (KG_USAGE_SEAL, KG_USAGE_SIGN): New macros. + + * accept_sec_context.c (rd_req_keyproc): Already-disabled routine + deleted. + (krb5_gss_accept_sec_context): Use sgn_alg and seal_alg symbolic + names. Add a case for des3-hmac-sha1. + * k5seal.c (make_seal_token_v1): Likewise. Do key derivation for + checksums. + * k5unseal.c (kg_unseal_v1): Likewise. + * util_crypt.c (kg_encrypt, kg_decrypt): Do key derivation for + encryption. + + * util_crypt.c (zeros): Unused variable deleted. + +2000-04-18 Ken Raeburn <raeburn@mit.edu> + + * wrap_size_limit.c: Remove mech2 support. Add MIT copyright. + +2000-04-08 Tom Yu <tlyu@mit.edu> + + * wrap_size_limit.c (krb5_gss_wrap_size_limit): Fix up + wrap_size_limit() to deal with integrity wrap tokens properly. + The rfc1964 mech always pads and confounds regardless of whether + confidentiality is requested. + +2000-03-20 Ken Raeburn <raeburn@mit.edu> + + * accept_sec_context.c, init_sec_context.c: Disable krb5-mech2 + stuff for now. (Tom Yu's krb5-1.1 patch.) + +2000-01-27 Ken Raeburn <raeburn@mit.edu> * init_sec_context.c (krb5_gss_init_sec_context): Default to des-cbc-crc. diff --git a/src/lib/gssapi/krb5/accept_sec_context.c b/src/lib/gssapi/krb5/accept_sec_context.c index fc920ec..c4d5467 100644 --- a/src/lib/gssapi/krb5/accept_sec_context.c +++ b/src/lib/gssapi/krb5/accept_sec_context.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * 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. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -49,39 +73,12 @@ #include "k5-int.h" #include "gssapiP_krb5.h" #include <memory.h> +#include <assert.h> /* * $Id$ */ -#if 0 - -/* XXXX This widen/narrow stuff is bletcherous, but it seems to be - necessary. Perhaps there is a "better" way, but I don't know what it - is */ - -#include <krb5/widen.h> -static krb5_error_code -rd_req_keyproc(krb5_pointer keyprocarg, krb5_principal server, - krb5_kvno kvno, krb5_keyblock **keyblock) -#include <krb5/narrow.h> -{ - krb5_error_code code; - krb5_keytab_entry ktentry; - - if (code = krb5_kt_get_entry((krb5_keytab) keyprocarg, server, kvno, - &ktentry)) - return(code); - - code = krb5_copy_keyblock(&ktentry.key, keyblock); - - (void) krb5_kt_free_entry(&ktentry); - - return(code); -} - -#endif - /* Decode, decrypt and store the forwarded creds in the local ccache. */ static krb5_error_code rd_and_store_for_creds(context, inbuf, out_cred) @@ -145,7 +142,6 @@ rd_and_store_for_creds(context, inbuf, out_cred) /* cred->princ already set */ cred->prerfc_mech = 1; /* this cred will work with all three mechs */ cred->rfc_mech = 1; - cred->rfcv2_mech = 1; cred->keytab = NULL; /* no keytab associated with this... */ cred->ccache = ccache; /* but there is a credential cache */ cred->tgt_expire = creds[0]->times.endtime; /* store the end time */ @@ -206,11 +202,10 @@ krb5_gss_accept_sec_context(minor_status, context_handle, krb5_ui_4 gss_flags = 0; int decode_req_message = 0; krb5_gss_ctx_id_rec *ctx = 0; -#if 0 krb5_enctype enctype; -#endif krb5_timestamp now; gss_buffer_desc token; + int err; krb5_auth_context auth_context = NULL; krb5_ticket * ticket = NULL; int option_id; @@ -222,7 +217,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle, gss_cred_id_t cred_handle = NULL; krb5_gss_cred_id_t deleg_cred = NULL; int token_length; - int gsskrb5_vers; int nctypes; krb5_cksumtype *ctypes = 0; struct kg2_option fwcred; @@ -296,13 +290,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle, &(ap_req.length), &ptr, KG_TOK_CTX_AP_REQ, input_token->length))) { - if (! cred->rfc_mech) { - code = G_WRONG_MECH; - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } mech_used = gss_mech_krb5; - gsskrb5_vers = 1000; } else if ((code == G_WRONG_MECH) && !(code = g_verify_token_header((gss_OID) gss_mech_krb5_old, &(ap_req.length), @@ -315,56 +303,15 @@ krb5_gss_accept_sec_context(minor_status, context_handle, * compatibility, and use it to decide when to use the * old behavior. */ - if (! cred->prerfc_mech) { - code = G_WRONG_MECH; - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } mech_used = gss_mech_krb5_old; - gsskrb5_vers = 1000; - } else if ((code == G_WRONG_MECH) && - !(code = g_verify_token_header((gss_OID) gss_mech_krb5_v2, - &token_length, - &ptr, KG2_TOK_INITIAL, - input_token->length))) { - if (! cred->rfcv2_mech) { - code = G_WRONG_MECH; - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } - mech_used = gss_mech_krb5_v2; - gsskrb5_vers = 2000; } else { major_status = GSS_S_DEFECTIVE_TOKEN; goto fail; } - if (gsskrb5_vers == 2000) { - /* gss krb5 v2 */ - - fwcred.option_id = KRB5_GSS_FOR_CREDS_OPTION; - fwcred.data = NULL; - - if (GSS_ERROR(major_status = - kg2_parse_token(&code, ptr, token_length, - &gss_flags, &nctypes, &ctypes, - delegated_cred_handle?1:0, - &fwcred, &ap_req, NULL))) { - goto fail; - } - - gss_flags = (ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]; - - gss_flags &= ~GSS_C_DELEG_FLAG; /* mask out the delegation flag; - if there's a delegation, we'll - set it below */ - } else { - /* gss krb5 v1 */ - - sptr = (char *) ptr; - TREAD_STR(sptr, ap_req.data, ap_req.length); - decode_req_message = 1; - } + sptr = (char *) ptr; + TREAD_STR(sptr, ap_req.data, ap_req.length); + decode_req_message = 1; /* construct the sender_addr */ @@ -416,9 +363,7 @@ krb5_gss_accept_sec_context(minor_status, context_handle, } #endif - if (gsskrb5_vers == 2000) { - bigend = 1; - } else { + { /* gss krb5 v1 */ /* stash this now, for later. */ @@ -557,7 +502,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle, ctx->gss_flags = KG_IMPLFLAGS(gss_flags); ctx->seed_init = 0; ctx->big_endian = bigend; - ctx->gsskrb5_version = gsskrb5_vers; /* Intern the ctx pointer so that delete_sec_context works */ if (! kg_save_ctx_id((gss_ctx_id_t) ctx)) { @@ -603,114 +547,37 @@ krb5_gss_accept_sec_context(minor_status, context_handle, goto fail; } - if (gsskrb5_vers == 2000) { - int cblen; - krb5_boolean valid; + switch(ctx->subkey->enctype) { + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_CRC: + ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; + ctx->signalg = SGN_ALG_DES_MAC_MD5; + ctx->cksum_size = 8; + ctx->sealalg = SEAL_ALG_DES; - /* intersect the token ctypes with the local ctypes */ - - if (code = krb5_c_keyed_checksum_types(context, ctx->subkey->enctype, - &ctx->nctypes, &ctx->ctypes)) - goto fail; - - if (nctypes == 0) { - code = KRB5_CRYPTO_INTERNAL; - goto fail; - } - - kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes); - - if (nctypes == 0) { - code = KG_NO_CTYPES; - goto fail; - } - - /* process the delegated cred, if any */ - - if (fwcred.data) { - krb5_data option; - - option.length = fwcred.length; - option.data = fwcred.data; - - if (code = rd_and_store_for_creds(context, &option, &deleg_cred)) { - major_status = GSS_S_FAILURE; - goto fail; - } - - gss_flags |= GSS_C_DELEG_FLAG; /* got a delegation */ - } - - /* construct the checksum buffer */ - - cblen = 4*5; - if (input_chan_bindings) - cblen += (input_chan_bindings->initiator_address.length+ - input_chan_bindings->acceptor_address.length+ - input_chan_bindings->application_data.length); - - cksumdata.length = cblen + ((char *)(ap_req.data-2) - (char *)(ptr-2)); + /* fill in the encryption descriptors */ - if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) { - code = ENOMEM; + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) { major_status = GSS_S_FAILURE; goto fail; } - ptr2 = cksumdata.data; - - if (input_chan_bindings) { - TWRITE_INT(ptr2, input_chan_bindings->initiator_addrtype, 1); - TWRITE_BUF(ptr2, input_chan_bindings->initiator_address, 1); - TWRITE_INT(ptr2, input_chan_bindings->acceptor_addrtype, 1); - TWRITE_BUF(ptr2, input_chan_bindings->acceptor_address, 1); - TWRITE_BUF(ptr2, input_chan_bindings->application_data, 1); - } else { - memset(ptr2, 0, cblen); - ptr2 += cblen; - } - - memcpy(ptr2, ptr-2, ((char *)(ap_req.data-2) - (char *)(ptr-2))); + for (i=0; i<ctx->enc->length; i++) + /*SUPPRESS 113*/ + ctx->enc->contents[i] ^= 0xf0; - if (code = krb5_c_verify_checksum(context, ctx->subkey, - KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM, - &cksumdata, authdat->checksum, - &valid)) { + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) { major_status = GSS_S_FAILURE; goto fail; } - free(cksumdata.data); - cksumdata.data = 0; + break; - if (!valid) { - code = 0; - major_status = GSS_S_BAD_SIG; - goto fail; - } - } else { - /* gss krb5 v1 */ - - switch(ctx->subkey->enctype) { - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_CRC: - ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; - ctx->signalg = 0; - ctx->cksum_size = 8; - ctx->sealalg = 0; - break; -#if 0 - case ENCTYPE_DES3_CBC_MD5: - enctype = ENCTYPE_DES3_CBC_RAW; - ctx->signalg = 3; - ctx->cksum_size = 16; - ctx->sealalg = 1; - break; -#endif - default: - code = KRB5_BAD_ENCTYPE; - goto fail; - } + case ENCTYPE_DES3_CBC_SHA1: + ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD; + ctx->cksum_size = 20; + ctx->sealalg = SEAL_ALG_DES3KD; /* fill in the encryption descriptors */ @@ -719,14 +586,16 @@ krb5_gss_accept_sec_context(minor_status, context_handle, goto fail; } - for (i=0; i<ctx->enc->length; i++) - /*SUPPRESS 113*/ - ctx->enc->contents[i] ^= 0xf0; - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) { major_status = GSS_S_FAILURE; goto fail; } + + break; + + default: + code = KRB5_BAD_ENCTYPE; + goto fail; } ctx->endtime = ticket->enc_part2->times.endtime; @@ -769,122 +638,22 @@ krb5_gss_accept_sec_context(minor_status, context_handle, /* the reply token hasn't been sent yet, but that's ok. */ ctx->established = 1; - if (ctx->gsskrb5_version == 2000) { - krb5_ui_4 tok_flags; - - tok_flags = - (ctx->gss_flags & GSS_C_DELEG_FLAG)?KG2_RESP_FLAG_DELEG_OK:0; - - cksumdata.length = 8 + 4*ctx->nctypes + 4; - - if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) { - code = ENOMEM; - major_status = GSS_S_FAILURE; - goto fail; - } - - /* construct the token fields */ - - ptr = cksumdata.data; - - ptr[0] = (KG2_TOK_RESPONSE >> 8) & 0xff; - ptr[1] = KG2_TOK_RESPONSE & 0xff; - - ptr[2] = (tok_flags >> 24) & 0xff; - ptr[3] = (tok_flags >> 16) & 0xff; - ptr[4] = (tok_flags >> 8) & 0xff; - ptr[5] = tok_flags & 0xff; - - ptr[6] = (ctx->nctypes >> 8) & 0xff; - ptr[7] = ctx->nctypes & 0xff; - - ptr += 8; - - for (i=0; i<ctx->nctypes; i++) { - ptr[i] = (ctx->ctypes[i] >> 24) & 0xff; - ptr[i+1] = (ctx->ctypes[i] >> 16) & 0xff; - ptr[i+2] = (ctx->ctypes[i] >> 8) & 0xff; - ptr[i+3] = ctx->ctypes[i] & 0xff; - - ptr += 4; - } - - memset(ptr, 0, 4); - - /* make the MIC token */ + token.length = g_token_size((gss_OID) mech_used, ap_rep.length); - { - gss_buffer_desc text, token; - - text.length = cksumdata.length; - text.value = cksumdata.data; - - /* ctx->seq_send must be set before this call */ - - if (GSS_ERROR(major_status = - krb5_gss_get_mic(&code, ctx, - GSS_C_QOP_DEFAULT, - &text, &token))) - goto fail; - - mic.length = token.length; - mic.data = token.value; - } - - token.length = g_token_size((gss_OID) mech_used, - (cksumdata.length-2)+4+ap_rep.length+ - mic.length); - - if ((token.value = (unsigned char *) xmalloc(token.length)) - == NULL) { - code = ENOMEM; - major_status = GSS_S_FAILURE; - goto fail; - } - ptr = token.value; - g_make_token_header((gss_OID) mech_used, - (cksumdata.length-2)+4+ap_rep.length+mic.length, - &ptr, KG2_TOK_RESPONSE); - - memcpy(ptr, cksumdata.data+2, cksumdata.length-2); - ptr += cksumdata.length-2; - - ptr[0] = (ap_rep.length >> 8) & 0xff; - ptr[1] = ap_rep.length & 0xff; - memcpy(ptr+2, ap_rep.data, ap_rep.length); - - ptr += (2+ap_rep.length); - - ptr[0] = (mic.length >> 8) & 0xff; - ptr[1] = mic.length & 0xff; - memcpy(ptr+2, mic.data, mic.length); - - ptr += (2+mic.length); - - free(cksumdata.data); - cksumdata.data = 0; - - /* gss krb5 v2 */ - } else { - /* gss krb5 v1 */ - - token.length = g_token_size((gss_OID) mech_used, ap_rep.length); - - if ((token.value = (unsigned char *) xmalloc(token.length)) - == NULL) { - major_status = GSS_S_FAILURE; - code = ENOMEM; - goto fail; - } - ptr = token.value; - g_make_token_header((gss_OID) mech_used, ap_rep.length, - &ptr, KG_TOK_CTX_AP_REP); + if ((token.value = (unsigned char *) xmalloc(token.length)) + == NULL) { + major_status = GSS_S_FAILURE; + code = ENOMEM; + goto fail; + } + ptr = token.value; + g_make_token_header((gss_OID) mech_used, ap_rep.length, + &ptr, KG_TOK_CTX_AP_REP); - TWRITE_STR(ptr, ap_rep.data, ap_rep.length); + TWRITE_STR(ptr, ap_rep.data, ap_rep.length); - ctx->established = 1; + ctx->established = 1; - } } else { token.length = 0; token.value = NULL; @@ -1014,13 +783,8 @@ krb5_gss_accept_sec_context(minor_status, context_handle, if (code) return (major_status); - if (gsskrb5_vers == 2000) { - tmsglen = 12+scratch.length; - toktype = KG2_TOK_RESPONSE; - } else { - tmsglen = scratch.length; - toktype = KG_TOK_CTX_ERROR; - } + tmsglen = scratch.length; + toktype = KG_TOK_CTX_ERROR; token.length = g_token_size((gss_OID) mech_used, tmsglen); token.value = (unsigned char *) xmalloc(token.length); @@ -1030,24 +794,6 @@ krb5_gss_accept_sec_context(minor_status, context_handle, ptr = token.value; g_make_token_header((gss_OID) mech_used, tmsglen, &ptr, toktype); - if (gsskrb5_vers == 2000) { - krb5_ui_4 flags; - - flags = KG2_RESP_FLAG_ERROR; - - ptr[0] = (flags << 24) & 0xff; - ptr[1] = (flags << 16) & 0xff; - ptr[2] = (flags << 8) & 0xff; - ptr[3] = flags & 0xff; - - memset(ptr+4, 0, 6); - - ptr[10] = (scratch.length << 8) & 0xff; - ptr[11] = scratch.length & 0xff; - - ptr += 12; - } - TWRITE_STR(ptr, scratch.data, scratch.length); xfree(scratch.data); diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c index b67eb4f..8153d13 100644 --- a/src/lib/gssapi/krb5/acquire_cred.c +++ b/src/lib/gssapi/krb5/acquire_cred.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * 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. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -154,7 +178,7 @@ acquire_init_cred(context, minor_status, desired_name, output_princ, cred) /* open the default credential cache */ - if ((code = krb5_cc_default(context, &ccache))) { + if ((code = krb5int_cc_default(context, &ccache))) { *minor_status = code; return(GSS_S_CRED_UNAVAIL); } @@ -283,7 +307,7 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, size_t i; krb5_gss_cred_id_t cred; gss_OID_set ret_mechs; - int req_old, req_new, req_v2; + int req_old, req_new; OM_uint32 ret; krb5_error_code code; @@ -313,22 +337,18 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, if (desired_mechs == GSS_C_NULL_OID_SET) { req_old = 1; req_new = 1; - req_v2 = 1; } else { req_old = 0; req_new = 0; - req_v2 = 0; for (i=0; i<desired_mechs->count; i++) { if (g_OID_equal(gss_mech_krb5_old, &(desired_mechs->elements[i]))) req_old++; if (g_OID_equal(gss_mech_krb5, &(desired_mechs->elements[i]))) req_new++; - if (g_OID_equal(gss_mech_krb5_v2, &(desired_mechs->elements[i]))) - req_v2++; } - if (!req_old && !req_new && !req_v2) { + if (!req_old && !req_new) { *minor_status = 0; return(GSS_S_BAD_MECH); } @@ -347,7 +367,6 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, cred->princ = NULL; cred->prerfc_mech = req_old; cred->rfc_mech = req_new; - cred->rfcv2_mech = req_v2; cred->keytab = NULL; cred->ccache = NULL; @@ -447,10 +466,6 @@ krb5_gss_acquire_cred(minor_status, desired_name, time_req, (cred->rfc_mech && GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, gss_mech_krb5, - &ret_mechs))) || - (cred->rfcv2_mech && - GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, - gss_mech_krb5_v2, &ret_mechs)))) { if (cred->ccache) (void)krb5_cc_close(context, cred->ccache); diff --git a/src/lib/gssapi/krb5/add_cred.c b/src/lib/gssapi/krb5/add_cred.c index 2a6fdb4..918c264 100644 --- a/src/lib/gssapi/krb5/add_cred.c +++ b/src/lib/gssapi/krb5/add_cred.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * 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. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * 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. + * + */ +/* * Copyright (C) 1998 by the FundsXpress, INC. * * All rights reserved. @@ -110,8 +134,7 @@ krb5_gss_add_cred(minor_status, input_cred_handle, /* check that desired_mech isn't already in the credential */ if ((g_OID_equal(desired_mech, gss_mech_krb5_old) && cred->prerfc_mech) || - (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech) || - (g_OID_equal(desired_mech, gss_mech_krb5_v2) && cred->rfcv2_mech)) { + (g_OID_equal(desired_mech, gss_mech_krb5) && cred->rfc_mech)) { *minor_status = 0; return(GSS_S_DUPLICATE_ELEMENT); } @@ -156,7 +179,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle, new_cred->usage = cred_usage; new_cred->prerfc_mech = cred->prerfc_mech; new_cred->rfc_mech = cred->rfc_mech; - new_cred->rfcv2_mech = cred->rfcv2_mech; new_cred->tgt_expire = cred->tgt_expire; if (code = krb5_copy_principal(context, cred->princ, @@ -177,8 +199,9 @@ krb5_gss_add_cred(minor_status, input_cred_handle, return(GSS_S_FAILURE); } - strcpy(ktboth, kttype); - strcat(ktboth, ":"); + strncpy(ktboth, kttype, sizeof(ktboth) - 1); + ktboth[sizeof(ktboth) - 1] = '\0'; + strncat(ktboth, ":", sizeof(ktboth) - 1 - strlen(ktboth)); if (code = krb5_kt_get_name(context, cred->keytab, ktboth+strlen(ktboth), @@ -234,9 +257,10 @@ krb5_gss_add_cred(minor_status, input_cred_handle, return(GSS_S_FAILURE); } - strcpy(ccboth, cctype); - strcat(ccboth, ":"); - strcat(ccboth, ccname); + strncpy(ccboth, cctype, sizeof(ccboth) - 1); + ccboth[sizeof(ccboth) - 1] = '\0'; + strncat(ccboth, ":", sizeof(ccboth) - 1 - strlen(ccboth)); + strncat(ccboth, ccname, sizeof(ccboth) - 1 - strlen(ccboth)); if (code = krb5_cc_resolve(context, ccboth, &new_cred->ccache)) { if (new_cred->rcache) @@ -280,8 +304,6 @@ krb5_gss_add_cred(minor_status, input_cred_handle, cred->prerfc_mech = 1; else if (g_OID_equal(desired_mech, gss_mech_krb5)) cred->rfc_mech = 1; - else if (g_OID_equal(desired_mech, gss_mech_krb5_v2)) - cred->rfcv2_mech = 1; /* set the outputs */ diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h index e344b4f..166c4c4 100644 --- a/src/lib/gssapi/krb5/gssapiP_krb5.h +++ b/src/lib/gssapi/krb5/gssapiP_krb5.h @@ -1,4 +1,28 @@ /* + * Copyright 2000 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * 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. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -79,6 +103,39 @@ #define KG2_RESP_FLAG_ERROR 0x0001 #define KG2_RESP_FLAG_DELEG_OK 0x0002 +/* These are to be stored in little-endian order, i.e., des-mac is + stored as 02 00. */ +enum sgn_alg { + SGN_ALG_DES_MAC_MD5 = 0x0000, + SGN_ALG_MD2_5 = 0x0001, + SGN_ALG_DES_MAC = 0x0002, + SGN_ALG_3 = 0x0003, /* not published */ + SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; no support */ + SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004 +}; +enum seal_alg { + SEAL_ALG_NONE = 0xffff, + SEAL_ALG_DES = 0x0000, + SEAL_ALG_1 = 0x0001, /* not published */ + SEAL_ALG_MICROSOFT_RC4 = 0x0010, /* microsoft w2k; no support */ + SEAL_ALG_DES3KD = 0x0002 +}; + +#define KG_USAGE_SEAL 22 +#define KG_USAGE_SIGN 23 +#define KG_USAGE_SEQ 24 + +enum qop { + GSS_KRB5_INTEG_C_QOP_MD5 = 0x0001, /* *partial* MD5 = "MD2.5" */ + GSS_KRB5_INTEG_C_QOP_DES_MD5 = 0x0002, + GSS_KRB5_INTEG_C_QOP_DES_MAC = 0x0003, + GSS_KRB5_INTEG_C_QOP_HMAC_SHA1 = 0x0004, + GSS_KRB5_INTEG_C_QOP_MASK = 0x00ff, + GSS_KRB5_CONF_C_QOP_DES = 0x0100, + GSS_KRB5_CONF_C_QOP_DES3_KD = 0x0200, + GSS_KRB5_CONF_C_QOP_MASK = 0xff00 +}; + /** internal types **/ typedef krb5_principal krb5_gss_name_t; @@ -89,7 +146,6 @@ typedef struct _krb5_gss_cred_id_rec { krb5_principal princ; /* this is not interned as a gss_name_t */ int prerfc_mech; int rfc_mech; - int rfcv2_mech; /* keytab (accept) data */ krb5_keytab keytab; @@ -125,7 +181,6 @@ typedef struct _krb5_gss_ctx_id_rec { int big_endian; krb5_auth_context auth_context; gss_OID_desc *mech_used; - int gsskrb5_version; int nctypes; krb5_cksumtype *ctypes; } krb5_gss_ctx_id_rec, *krb5_gss_ctx_id_t; @@ -190,12 +245,18 @@ int kg_encrypt_size PROTOTYPE((krb5_context context, krb5_keyblock *key, int n)); krb5_error_code kg_encrypt PROTOTYPE((krb5_context context, - krb5_keyblock *key, - krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length)); + krb5_keyblock *key, int usage, + krb5_pointer iv, + krb5_pointer in, + krb5_pointer out, + int length)); krb5_error_code kg_decrypt PROTOTYPE((krb5_context context, - krb5_keyblock *key, - krb5_pointer iv, krb5_pointer in, krb5_pointer out, int length)); + krb5_keyblock *key, int usage, + krb5_pointer iv, + krb5_pointer in, + krb5_pointer out, + int length)); OM_uint32 kg_seal PROTOTYPE((krb5_context context, OM_uint32 *minor_status, diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c index d0c8bc9..5a84322 100644 --- a/src/lib/gssapi/krb5/init_sec_context.c +++ b/src/lib/gssapi/krb5/init_sec_context.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * 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. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -49,6 +73,7 @@ #include "gssapiP_krb5.h" #include <memory.h> #include <stdlib.h> +#include <assert.h> /* * $Id$ @@ -63,17 +88,18 @@ int krb5_gss_dbg_client_expcreds = 0; * ccache. */ static krb5_error_code get_credentials(context, cred, server, now, - endtime, enctype, out_creds) + endtime, enctypes, out_creds) krb5_context context; krb5_gss_cred_id_t cred; krb5_principal server; krb5_timestamp now; krb5_timestamp endtime; - krb5_enctype enctype; + const krb5_enctype *enctypes; krb5_creds **out_creds; { krb5_error_code code; krb5_creds in_creds; + int i; memset((char *) &in_creds, 0, sizeof(krb5_creds)); @@ -82,10 +108,21 @@ static krb5_error_code get_credentials(context, cred, server, now, if ((code = krb5_copy_principal(context, server, &in_creds.server))) goto cleanup; in_creds.times.endtime = endtime; - in_creds.keyblock.enctype = enctype; - if ((code = krb5_get_credentials(context, 0, cred->ccache, - &in_creds, out_creds))) + in_creds.keyblock.enctype = 0; + + for (i = 0; enctypes[i]; i++) { + in_creds.keyblock.enctype = enctypes[i]; + code = krb5_get_credentials(context, 0, cred->ccache, + &in_creds, out_creds); + if (code != KRB5_CC_NOT_KTYPE && code != KRB5KDC_ERR_ETYPE_NOSUPP) + break; + } + if (enctypes[i] == 0) { + code = KRB5_CONFIG_ETYPE_NOSUPP; + goto cleanup; + } + if (code) goto cleanup; /* @@ -93,7 +130,8 @@ static krb5_error_code get_credentials(context, cred, server, now, * boundaries) because accept_sec_context code is also similarly * non-forgiving. */ - if (!krb5_gss_dbg_client_expcreds && (*out_creds)->times.endtime < now) { + if (!krb5_gss_dbg_client_expcreds && *out_creds != NULL && + (*out_creds)->times.endtime < now) { code = KRB5KRB_AP_ERR_TKT_EXPIRED; goto cleanup; } @@ -117,196 +155,8 @@ make_ap_req_v2(context, ctx, cred, k_cred, chan_bindings, mech_type, token) gss_OID mech_type; gss_buffer_t token; { - krb5_flags mk_req_flags = 0; - krb5_int32 con_flags; - krb5_error_code code; - krb5_data credmsg, cksumdata, ap_req; - int i, tlen, cblen, nctypes; - krb5_cksumtype *ctypes; - unsigned char *t, *ptr; - - credmsg.data = 0; - cksumdata.data = 0; - ap_req.data = 0; - ctypes = 0; - - /* create the option data if necessary */ - if (ctx->gss_flags & GSS_C_DELEG_FLAG) { - /* first get KRB_CRED message, so we know its length */ - - /* clear the time check flag that was set in krb5_auth_con_init() */ - krb5_auth_con_getflags(context, ctx->auth_context, &con_flags); - krb5_auth_con_setflags(context, ctx->auth_context, - con_flags & ~KRB5_AUTH_CONTEXT_DO_TIME); - - code = krb5_fwd_tgt_creds(context, ctx->auth_context, 0, - cred->princ, ctx->there, cred->ccache, 1, - &credmsg); - - /* turn KRB5_AUTH_CONTEXT_DO_TIME back on */ - krb5_auth_con_setflags(context, ctx->auth_context, con_flags); - - if (code) { - /* don't fail here; just don't accept/do the delegation - request */ - ctx->gss_flags &= ~GSS_C_DELEG_FLAG; - } else { - if (credmsg.length > KRB5_INT16_MAX) { - krb5_free_data_contents(context, &credmsg); - return(KRB5KRB_ERR_FIELD_TOOLONG); - } - } - } else { - credmsg.length = 0; - } - - /* construct the list of compatible cksum types */ - - if ((code = krb5_c_keyed_checksum_types(context, - k_cred->keyblock.enctype, - &nctypes, &ctypes))) - goto cleanup; - - if (nctypes == 0) { - code = KRB5_CRYPTO_INTERNAL; - goto cleanup; - } - - /* construct the checksum fields */ - - cblen = 4*5; - if (chan_bindings) - cblen += (chan_bindings->initiator_address.length+ - chan_bindings->acceptor_address.length+ - chan_bindings->application_data.length); - - cksumdata.length = cblen + 8 + 4*nctypes + 4; - if (credmsg.length) - cksumdata.length += 4 + credmsg.length; - - if ((cksumdata.data = (char *) malloc(cksumdata.length)) == NULL) - goto cleanup; - - /* helper macros. This code currently depends on a long being 32 - bits, and htonl dtrt. */ - - ptr = cksumdata.data; - - if (chan_bindings) { - TWRITE_INT(ptr, chan_bindings->initiator_addrtype, 1); - TWRITE_BUF(ptr, chan_bindings->initiator_address, 1); - TWRITE_INT(ptr, chan_bindings->acceptor_addrtype, 1); - TWRITE_BUF(ptr, chan_bindings->acceptor_address, 1); - TWRITE_BUF(ptr, chan_bindings->application_data, 1); - } else { - memset(ptr, 0, cblen); - ptr += cblen; - } - - /* construct the token fields */ - - ptr[0] = (KG2_TOK_INITIAL >> 8) & 0xff; - ptr[1] = KG2_TOK_INITIAL & 0xff; - - ptr[2] = (ctx->gss_flags >> 24) & 0xff; - ptr[3] = (ctx->gss_flags >> 16) & 0xff; - ptr[4] = (ctx->gss_flags >> 8) & 0xff; - ptr[5] = ctx->gss_flags & 0xff; - - ptr[6] = (nctypes >> 8) & 0xff; - ptr[7] = nctypes & 0xff; - - ptr += 8; - - for (i=0; i<nctypes; i++) { - ptr[0] = (ctypes[i] >> 24) & 0xff; - ptr[1] = (ctypes[i] >> 16) & 0xff; - ptr[2] = (ctypes[i] >> 8) & 0xff; - ptr[3] = ctypes[i] & 0xff; - - ptr += 4; - } - - if (credmsg.length) { - ptr[0] = (KRB5_GSS_FOR_CREDS_OPTION >> 8) & 0xff; - ptr[1] = KRB5_GSS_FOR_CREDS_OPTION & 0xff; - - ptr[2] = (credmsg.length >> 8) & 0xff; - ptr[3] = credmsg.length & 0xff; - - ptr += 4; - - memcpy(ptr, credmsg.data, credmsg.length); - - ptr += credmsg.length; - } - - memset(ptr, 0, 4); - - /* call mk_req. subkey and ap_req need to be used or destroyed */ - - mk_req_flags = AP_OPTS_USE_SUBKEY; - - if (ctx->gss_flags & GSS_C_MUTUAL_FLAG) - mk_req_flags |= AP_OPTS_MUTUAL_REQUIRED; - - if ((code = krb5_mk_req_extended(context, &ctx->auth_context, mk_req_flags, - &cksumdata, k_cred, &ap_req))) - goto cleanup; - - /* store the interesting stuff from creds and authent */ - ctx->endtime = k_cred->times.endtime; - ctx->krb_flags = k_cred->ticket_flags; - - /* build up the token */ - - /* allocate space for the token */ - tlen = g_token_size((gss_OID) mech_type, - (cksumdata.length-(2+cblen))+2+ap_req.length); - - if ((t = (unsigned char *) xmalloc(tlen)) == NULL) { - code = ENOMEM; - goto cleanup; - } - - ptr = t; - - g_make_token_header((gss_OID) mech_type, - (cksumdata.length-(2+cblen))+2+ap_req.length, - &ptr, KG2_TOK_INITIAL); - - /* skip over the channel bindings and the token id */ - memcpy(ptr, cksumdata.data+cblen+2, cksumdata.length-(cblen+2)); - ptr += cksumdata.length-(cblen+2); - ptr[0] = (ap_req.length >> 8) & 0xff; - ptr[1] = ap_req.length & 0xff; - ptr += 2; - memcpy(ptr, ap_req.data, ap_req.length); - - /* pass allocated data back */ - - ctx->nctypes = nctypes; - ctx->ctypes = ctypes; - - token->length = tlen; - token->value = (void *) t; - - code = 0; - -cleanup: - if (code) { - if (ctypes) - krb5_free_cksumtypes(context, ctypes); - } - - if (credmsg.data) - free(credmsg.data); - if (ap_req.data) - free(ap_req.data); - if (cksumdata.data) - free(cksumdata.data); - - return(code); + int krb5_mech2_supported = 0; + assert(krb5_mech2_supported); } static krb5_error_code @@ -480,13 +330,19 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, krb5_context context; krb5_gss_cred_id_t cred; krb5_creds *k_cred = 0; - krb5_enctype enctype = ENCTYPE_DES_CBC_CRC; + static const krb5_enctype wanted_enctypes[] = { +#if 1 + ENCTYPE_DES3_CBC_SHA1, +#endif + ENCTYPE_DES_CBC_CRC, + ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4, + 0 + }; krb5_error_code code; krb5_gss_ctx_id_rec *ctx, *ctx_free; krb5_timestamp now; gss_buffer_desc token; - int gsskrb5_vers = 0; - int i, err; + int i, j, err; int default_mech = 0; krb5_ui_4 resp_flags; OM_uint32 major_status; @@ -528,32 +384,19 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, err = 0; if (mech_type == GSS_C_NULL_OID) { default_mech = 1; - if (cred->rfcv2_mech) { - mech_type = gss_mech_krb5_v2; - gsskrb5_vers = 2000; - } else if (cred->rfc_mech) { + if (cred->rfc_mech) { mech_type = gss_mech_krb5; - gsskrb5_vers = 1000; - enctype = ENCTYPE_DES_CBC_CRC; } else if (cred->prerfc_mech) { mech_type = gss_mech_krb5_old; - gsskrb5_vers = 1000; - enctype = ENCTYPE_DES_CBC_CRC; } else { err = 1; } - } else if (g_OID_equal(mech_type, gss_mech_krb5_v2)) { - if (!cred->rfcv2_mech) - err = 1; - gsskrb5_vers = 2000; } else if (g_OID_equal(mech_type, gss_mech_krb5)) { if (!cred->rfc_mech) err = 1; - gsskrb5_vers = 1000; } else if (g_OID_equal(mech_type, gss_mech_krb5_old)) { if (!cred->prerfc_mech) err = 1; - gsskrb5_vers = 1000; } else { err = 1; } @@ -607,7 +450,6 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, ctx->seed_init = 0; ctx->big_endian = 0; /* all initiators do little-endian, as per spec */ ctx->seqstate = 0; - ctx->gsskrb5_version = gsskrb5_vers; ctx->nctypes = 0; ctx->ctypes = 0; @@ -628,27 +470,12 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, goto fail; if ((code = get_credentials(context, cred, ctx->there, now, - ctx->endtime, enctype, &k_cred))) + ctx->endtime, wanted_enctypes, &k_cred))) goto fail; - /* - * If the default mechanism was requested, and the keytype is - * DES_CBC, force the old mechanism - */ - if (default_mech && - ((k_cred->keyblock.enctype == ENCTYPE_DES_CBC_CRC) || - (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD4) || - (k_cred->keyblock.enctype == ENCTYPE_DES_CBC_MD5))) { - ctx->gsskrb5_version = gsskrb5_vers = 1000; + if (default_mech) { mech_type = gss_mech_krb5; - if (k_cred->keyblock.enctype != ENCTYPE_DES_CBC_CRC) { - krb5_free_creds(context, k_cred); - enctype = ENCTYPE_DES_CBC_CRC; - if ((code = get_credentials(context, cred, ctx->there, now, - ctx->endtime, enctype, &k_cred))) - goto fail; - } - } + } if (generic_gss_copy_oid(minor_status, mech_type, &ctx->mech_used) != GSS_S_COMPLETE) { @@ -660,24 +487,7 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, */ ctx->mech_used = krb5_gss_convert_static_mech_oid(ctx->mech_used); - if (ctx->gsskrb5_version == 2000) { - /* gsskrb5 v2 */ - if ((code = make_ap_req_v2(context, ctx, - cred, k_cred, input_chan_bindings, - mech_type, &token))) { - if ((code == KRB5_FCC_NOFILE) || (code == KRB5_CC_NOTFOUND) || - (code == KG_EMPTY_CCACHE)) - major_status = GSS_S_NO_CRED; - if (code == KRB5KRB_AP_ERR_TKT_EXPIRED) - major_status = GSS_S_CREDENTIALS_EXPIRED; - goto fail; - } - - krb5_auth_con_getlocalseqnumber(context, ctx->auth_context, - &ctx->seq_send); - krb5_auth_con_getlocalsubkey(context, ctx->auth_context, - &ctx->subkey); - } else { + { /* gsskrb5 v1 */ if ((code = make_ap_req_v1(context, ctx, cred, k_cred, input_chan_bindings, @@ -699,11 +509,41 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, switch(ctx->subkey->enctype) { case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_MD4: case ENCTYPE_DES_CBC_CRC: ctx->subkey->enctype = ENCTYPE_DES_CBC_RAW; - ctx->signalg = 0; + ctx->signalg = SGN_ALG_DES_MAC_MD5; ctx->cksum_size = 8; - ctx->sealalg = 0; + ctx->sealalg = SEAL_ALG_DES; + + /* The encryption key is the session key XOR + 0xf0f0f0f0f0f0f0f0. */ + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) + goto fail; + + for (i=0; i<ctx->enc->length; i++) + /*SUPPRESS 113*/ + ctx->enc->contents[i] ^= 0xf0; + + if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) + goto fail; + + break; + + case ENCTYPE_DES3_CBC_SHA1: + ctx->subkey->enctype = ENCTYPE_DES3_CBC_RAW; + ctx->signalg = SGN_ALG_HMAC_SHA1_DES3_KD; + ctx->cksum_size = 20; + ctx->sealalg = SEAL_ALG_DES3KD; + + code = krb5_copy_keyblock (context, ctx->subkey, &ctx->enc); + if (code) + goto fail; + code = krb5_copy_keyblock (context, ctx->subkey, &ctx->seq); + if (code) { + krb5_free_keyblock (context, ctx->enc); + goto fail; + } break; #if 0 case ENCTYPE_DES3_CBC_MD5: @@ -714,20 +554,10 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, break; #endif default: + *minor_status = KRB5_BAD_ENCTYPE; return GSS_S_FAILURE; } - /* the encryption key is the session key XOR 0xf0f0f0f0f0f0f0f0 */ - - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->enc))) - goto fail; - - for (i=0; i<ctx->enc->length; i++) - /*SUPPRESS 113*/ - ctx->enc->contents[i] ^= 0xf0; - - if ((code = krb5_copy_keyblock(context, ctx->subkey, &ctx->seq))) - goto fail; } if (k_cred) { @@ -824,94 +654,38 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, ptr = (unsigned char *) input_token->value; - if (ctx->gsskrb5_version == 2000) { - int token_length; - int nctypes; - krb5_cksumtype *ctypes = 0; - - /* gsskrb5 v2 */ - - if ((code = g_verify_token_header((gss_OID) ctx->mech_used, - &token_length, - &ptr, KG2_TOK_RESPONSE, - input_token->length))) { - major_status = GSS_S_DEFECTIVE_TOKEN; - goto fail; - } - - if (GSS_ERROR(major_status = - kg2_parse_token(minor_status, ptr, token_length, - &resp_flags, &nctypes, &ctypes, - 0, NULL, &ap_rep, &mic))) { - if (ctypes) - free(ctypes); - code = *minor_status; - goto fail; - } - major_status = GSS_S_FAILURE; - - kg2_intersect_ctypes(&ctx->nctypes, ctx->ctypes, nctypes, ctypes); + if ((err = g_verify_token_header((gss_OID) ctx->mech_used, + &(ap_rep.length), + &ptr, KG_TOK_CTX_AP_REP, + input_token->length))) { + if (g_verify_token_header((gss_OID) ctx->mech_used, + &(ap_rep.length), + &ptr, KG_TOK_CTX_ERROR, + input_token->length) == 0) { - free(ctypes); - - if (ctx->nctypes == 0) { - code = KG_NO_CTYPES; - goto fail; - } + /* Handle a KRB_ERROR message from the server */ - if (resp_flags & KG2_RESP_FLAG_ERROR) { - if ((code = krb5_rd_error(context, &ap_rep, &krb_error))) + sptr = (char *) ptr; /* PC compiler bug */ + TREAD_STR(sptr, ap_rep.data, ap_rep.length); + + code = krb5_rd_error(context, &ap_rep, &krb_error); + if (code) goto fail; - if (krb_error->error) code = krb_error->error + ERROR_TABLE_BASE_krb5; else code = 0; - krb5_free_error(context, krb_error); goto fail; + } else { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); } - - if (resp_flags & KG2_RESP_FLAG_DELEG_OK) - ctx->gss_flags |= GSS_C_DELEG_FLAG; - - /* drop through to ap_rep handling */ - } else { - /* gsskrb5 v1 */ - - if ((err = g_verify_token_header((gss_OID) ctx->mech_used, - &(ap_rep.length), - &ptr, KG_TOK_CTX_AP_REP, - input_token->length))) { - if (g_verify_token_header((gss_OID) ctx->mech_used, - &(ap_rep.length), - &ptr, KG_TOK_CTX_ERROR, - input_token->length) == 0) { - - /* Handle a KRB_ERROR message from the server */ - - sptr = (char *) ptr; /* PC compiler bug */ - TREAD_STR(sptr, ap_rep.data, ap_rep.length); - - code = krb5_rd_error(context, &ap_rep, &krb_error); - if (code) - goto fail; - if (krb_error->error) - code = krb_error->error + ERROR_TABLE_BASE_krb5; - else - code = 0; - krb5_free_error(context, krb_error); - goto fail; - } else { - *minor_status = 0; - return(GSS_S_DEFECTIVE_TOKEN); - } - } - - sptr = (char *) ptr; /* PC compiler bug */ - TREAD_STR(sptr, ap_rep.data, ap_rep.length); } + sptr = (char *) ptr; /* PC compiler bug */ + TREAD_STR(sptr, ap_rep.data, ap_rep.length); + /* decode the ap_rep */ if ((code = krb5_rd_rep(context, ctx->auth_context, &ap_rep, &ap_rep_data))) { @@ -938,26 +712,6 @@ krb5_gss_init_sec_context(minor_status, claimant_cred_handle, /* set established */ ctx->established = 1; - if (ctx->gsskrb5_version == 2000) { - gss_buffer_desc mic_data, mic_token; - - /* start with the token id */ - mic_data.value = ptr-2; - /* end before the ap-rep length */ - mic_data.length = ((char*)(ap_rep.data-2)-(char*)(ptr-2)); - - mic_token.length = mic.length; - mic_token.value = mic.data; - - if (GSS_ERROR(major_status = - krb5_gss_verify_mic(minor_status, *context_handle, - &mic_data, &mic_token, NULL))) { - code = *minor_status; - goto fail; - } - major_status = GSS_S_FAILURE; - } - /* set returns */ if (time_rec) { diff --git a/src/lib/gssapi/krb5/inq_cred.c b/src/lib/gssapi/krb5/inq_cred.c index c800012..6da0a52 100644 --- a/src/lib/gssapi/krb5/inq_cred.c +++ b/src/lib/gssapi/krb5/inq_cred.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * 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. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -121,10 +145,6 @@ krb5_gss_inquire_cred(minor_status, cred_handle, name, lifetime_ret, (cred->rfc_mech && GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, gss_mech_krb5, - &mechs))) || - (cred->rfcv2_mech && - GSS_ERROR(ret = generic_gss_add_oid_set_member(minor_status, - gss_mech_krb5_v2, &mechs)))) { krb5_free_principal(context, ret_name); /* *minor_status set above */ diff --git a/src/lib/gssapi/krb5/k5seal.c b/src/lib/gssapi/krb5/k5seal.c index ae8cc75..1ca108e 100644 --- a/src/lib/gssapi/krb5/k5seal.c +++ b/src/lib/gssapi/krb5/k5seal.c @@ -1,6 +1,6 @@ /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -10,7 +10,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -22,14 +22,14 @@ /* * Copyright (C) 1998 by the FundsXpress, INC. - * + * * All rights reserved. - * + * * 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 @@ -40,7 +40,7 @@ * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. - * + * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -49,196 +49,280 @@ #include "gssapiP_krb5.h" static krb5_error_code -make_priv_token_v2 PROTOTYPE((krb5_context context, - krb5_keyblock *subkey, +make_seal_token_v1 PROTOTYPE((krb5_context context, + krb5_keyblock *enc, + krb5_keyblock *seq, krb5_int32 *seqnum, int direction, gss_buffer_t text, gss_buffer_t token, + int signalg, + int cksum_size, + int sealalg, + int encrypt, + int toktype, + int bigend, gss_OID oid)); static krb5_error_code -make_priv_token_v2(context, subkey, seqnum, direction, text, token, oid) - krb5_context context; - krb5_keyblock *subkey; - krb5_int32 *seqnum; - int direction; - gss_buffer_t text; - gss_buffer_t token; - gss_OID oid; -{ - krb5_data plain; - krb5_enc_data cipher; - krb5_error_code code; - size_t enclen; - int tlen; - unsigned char *t, *ptr; - - plain.data = 0; - cipher.ciphertext.data = 0; - t = 0; - - plain.length = 7+text->length; - if ((plain.data = (void *) malloc(plain.length)) == NULL) { - code = ENOMEM; - goto cleanup; - } - - plain.data[0] = (*seqnum >> 24) & 0xff; - plain.data[1] = (*seqnum >> 16) & 0xff; - plain.data[2] = (*seqnum >> 8) & 0xff; - plain.data[3] = *seqnum & 0xff; - - plain.data[4] = direction?0:0xff; - - plain.data[5] = (text->length >> 8) & 0xff; - plain.data[6] = text->length & 0xff; - - memcpy(plain.data+7, text->value, text->length); - - if (code = krb5_c_encrypt_length(context, subkey->enctype, - plain.length, &enclen)) - goto cleanup; - - tlen = g_token_size((gss_OID) oid, 2+enclen); - - if ((t = (unsigned char *) xmalloc(tlen)) == NULL) - return(ENOMEM); - - ptr = t; - - g_make_token_header((gss_OID) oid, 2+enclen, &ptr, - KG2_TOK_WRAP_PRIV); - - ptr[0] = (enclen >> 8) & 0xff; - ptr[1] = enclen & 0xff; - - cipher.ciphertext.length = enclen; - cipher.ciphertext.data = ptr+2; - - if (code = krb5_c_encrypt(context, subkey, - KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV, - 0, &plain, &cipher)) - goto cleanup; - - /* that's it. return the token */ - - (*seqnum)++; - - token->length = tlen; - token->value = (void *) t; - - code = 0; - -cleanup: - if (plain.data) - free(plain.data); - if (code) { - if (t) - free(t); - } - - return(code); -} - -static krb5_error_code -make_integ_token_v2 PROTOTYPE((krb5_context context, - krb5_keyblock *subkey, - krb5_cksumtype ctype, - krb5_int32 *seqnum, - int direction, - gss_buffer_t text, - gss_buffer_t token, - int toktype, - gss_OID oid)); - -static krb5_error_code -make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token, - toktype, oid) - krb5_context context; - krb5_keyblock *subkey; - krb5_cksumtype ctype; - krb5_int32 *seqnum; - int direction; - gss_buffer_t text; - gss_buffer_t token; - int toktype; - gss_OID oid; +make_seal_token_v1(context, enc, seq, seqnum, direction, text, token, + signalg, cksum_size, sealalg, encrypt, toktype, + bigend, oid) + krb5_context context; + krb5_keyblock *enc; + krb5_keyblock *seq; + krb5_int32 *seqnum; + int direction; + gss_buffer_t text; + gss_buffer_t token; + int signalg; + int cksum_size; + int sealalg; + int encrypt; + int toktype; + int bigend; + gss_OID oid; { krb5_error_code code; - int tmp, tlen; - unsigned char *t, *ptr; - krb5_data plain; + size_t sumlen; + char *data_ptr; + krb5_data plaind; + krb5_checksum md5cksum; krb5_checksum cksum; + int conflen=0, tmsglen, tlen; + unsigned char *t, *ptr; - plain.data = 0; - t = 0; - cksum.contents = 0; + int encblksize, sumblksize; + + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_MD2_5: + case SGN_ALG_HMAC_MD5: + sumblksize = 1; + break; + case SGN_ALG_DES_MAC: + sumblksize = 8; + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + sumblksize = 1; + break; + default: + abort (); + return 123; /* find error code */ + } - /* assemble the checksum buffer and compute the checksum */ + switch (sealalg) { + case SEAL_ALG_NONE: + case SEAL_ALG_DES: + case SEAL_ALG_DES3KD: + encblksize = 8; + break; + default: + abort (); + return 12345654321; + } - plain.length = 7+text->length; + /* create the token buffer */ - if ((plain.data = (char *) malloc(plain.length)) == NULL) { - code = errno; - goto cleanup; + if (toktype == KG_TOK_SEAL_MSG) { + if (bigend && !encrypt) { + tmsglen = text->length; + } else { + conflen = kg_confounder_size(context, enc); + /* XXX knows that des block size is 8 */ + tmsglen = (conflen+text->length+8)&(~7); + } + } else { + tmsglen = 0; } - plain.data[0] = (*seqnum >> 24) & 0xff; - plain.data[1] = (*seqnum >> 16) & 0xff; - plain.data[2] = (*seqnum >> 8) & 0xff; - plain.data[3] = *seqnum & 0xff; + tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen); - plain.data[4] = direction?0:0xff; + if ((t = (unsigned char *) xmalloc(tlen)) == NULL) + return(ENOMEM); - plain.data[5] = (text->length >> 8) & 0xff; - plain.data[6] = text->length & 0xff; + /*** fill in the token */ - memcpy(plain.data+7, text->value, text->length); + ptr = t; - if (code = krb5_c_make_checksum(context, ctype, subkey, - (toktype == KG2_TOK_WRAP_INTEG)? - KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG: - KRB5_KEYUSAGE_GSS_TOK_MIC, - &plain, &cksum)) - goto cleanup; + g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype); - /* assemble the token itself */ + /* 0..1 SIGN_ALG */ - if (toktype == KG2_TOK_WRAP_INTEG) - tmp = 4+(7+text->length)+2+cksum.length; - else - tmp = 4+(5)+2+cksum.length; + ptr[0] = signalg & 0xff; + ptr[1] = (signalg >> 8) & 0xff; - tlen = g_token_size((gss_OID) oid, tmp); + /* 2..3 SEAL_ALG or Filler */ - if ((t = (unsigned char *) xmalloc(tlen)) == NULL) - return(ENOMEM); + if ((toktype == KG_TOK_SEAL_MSG) && encrypt) { + ptr[2] = sealalg & 0xff; + ptr[3] = (sealalg >> 8) & 0xff; + } else { + /* No seal */ + ptr[2] = 0xff; + ptr[3] = 0xff; + } - ptr = t; + /* 4..5 Filler */ + + ptr[4] = 0xff; + ptr[5] = 0xff; + + /* pad the plaintext, encrypt if needed, and stick it in the token */ + + /* initialize the the cksum */ + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_MD2_5: + case SGN_ALG_HMAC_MD5: + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3; + break; + default: + case SGN_ALG_DES_MAC: + abort (); + } - g_make_token_header((gss_OID) oid, tmp, &ptr, toktype); + if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen)) + return(code); + md5cksum.length = sumlen; + + if (toktype == KG_TOK_SEAL_MSG) { + unsigned char *plain; + unsigned char pad; + + if (!bigend || encrypt) { + if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { + xfree(t); + return(ENOMEM); + } + + if ((code = kg_make_confounder(context, enc, plain))) { + xfree(plain); + xfree(t); + return(code); + } + + memcpy(plain+conflen, text->value, text->length); + + /* XXX 8 is DES cblock size */ + pad = 8-(text->length%8); + + memset(plain+conflen+text->length, pad, pad); + } else { + /* plain is never used in the bigend && !encrypt case */ + plain = NULL; + } + + if (encrypt) { + if ((code = kg_encrypt(context, enc, KG_USAGE_SEAL, NULL, + (krb5_pointer) plain, + (krb5_pointer) (ptr+cksum_size+14), + tmsglen))) { + if (plain) + xfree(plain); + xfree(t); + return(code); + } + } else { + if (bigend) + memcpy(ptr+14+cksum_size, text->value, text->length); + else + memcpy(ptr+14+cksum_size, plain, tmsglen); + } + + /* compute the checksum */ + + /* 8 = head of token body as specified by mech spec */ + if (! (data_ptr = + (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) { + if (plain) + xfree(plain); + xfree(t); + return(ENOMEM); + } + (void) memcpy(data_ptr, ptr-2, 8); + if (bigend) + (void) memcpy(data_ptr+8, text->value, text->length); + else + (void) memcpy(data_ptr+8, plain, tmsglen); + plaind.length = 8 + (bigend ? text->length : tmsglen); + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq, + KG_USAGE_SIGN, &plaind, &md5cksum); + xfree(data_ptr); + + if (code) { + if (plain) + xfree(plain); + xfree(t); + return(code); + } - ptr[0] = (ctype >> 24) & 0xff; - ptr[1] = (ctype >> 16) & 0xff; - ptr[2] = (ctype >> 8) & 0xff; - ptr[3] = ctype & 0xff; + if (plain) + xfree(plain); + } else { + /* Sign only. */ + /* compute the checksum */ - ptr += 4; + if (! (data_ptr = (char *) xmalloc(8 + text->length))) { + xfree(t); + return(ENOMEM); + } + (void) memcpy(data_ptr, ptr-2, 8); + (void) memcpy(data_ptr+8, text->value, text->length); + plaind.length = 8 + text->length; + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, seq, + KG_USAGE_SIGN, &plaind, &md5cksum); + xfree(data_ptr); + if (code) { + xfree(t); + return(code); + } + } - if (toktype == KG2_TOK_WRAP_INTEG) { - memcpy(ptr, plain.data, 7+text->length); - ptr += 7+text->length; - } else { - memcpy(ptr, plain.data, 5); - ptr += 5; + switch(signalg) { + case SGN_ALG_DES_MAC_MD5: + case 3: + + if ((code = kg_encrypt(context, seq, KG_USAGE_SEAL, + (g_OID_equal(oid, gss_mech_krb5_old) ? + seq->contents : NULL), + md5cksum.contents, md5cksum.contents, 16))) { + xfree(md5cksum.contents); + xfree(t); + return code; + } + + cksum.length = cksum_size; + cksum.contents = md5cksum.contents + 16 - cksum.length; + + memcpy(ptr+14, cksum.contents, cksum.length); + break; + + case SGN_ALG_HMAC_SHA1_DES3_KD: + /* + * Using key derivation, the call to krb5_c_make_checksum + * already dealt with encrypting. + */ + if (md5cksum.length != cksum_size) + abort (); + memcpy (ptr+14, md5cksum.contents, md5cksum.length); + break; } - ptr[0] = (cksum.length >> 8) & 0xff; - ptr[1] = cksum.length & 0xff; - ptr += 2; + xfree(md5cksum.contents); + + /* create the seq_num */ - memcpy(ptr, cksum.contents, cksum.length); + if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum, + ptr+14, ptr+6))) { + xfree(t); + return(code); + } /* that's it. return the token */ @@ -247,372 +331,110 @@ make_integ_token_v2(context, subkey, ctype, seqnum, direction, text, token, token->length = tlen; token->value = (void *) t; - code = 0; - -cleanup: - if (plain.data) - free(plain.data); - if (cksum.contents) - krb5_free_checksum_contents(context, &cksum); - if (code) { - if (t) - free(t); - } - - return(code); + return(0); } -static krb5_error_code -make_seal_token_v1 PROTOTYPE((krb5_context context, - krb5_keyblock *enc, - krb5_keyblock *seq, - krb5_int32 *seqnum, - int direction, - gss_buffer_t text, - gss_buffer_t token, - int signalg, - int cksum_size, - int sealalg, - int encrypt, - int toktype, - int bigend, - gss_OID oid)); +/* if signonly is true, ignore conf_req, conf_state, + and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */ -static krb5_error_code -make_seal_token_v1(context, enc, seq, seqnum, direction, text, token, - signalg, cksum_size, sealalg, encrypt, toktype, - bigend, oid) - krb5_context context; - krb5_keyblock *enc; - krb5_keyblock *seq; - krb5_int32 *seqnum; - int direction; - gss_buffer_t text; - gss_buffer_t token; - int signalg; - int cksum_size; - int sealalg; - int encrypt; - int toktype; - int bigend; - gss_OID oid; +OM_uint32 +kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req, + input_message_buffer, conf_state, output_message_buffer, toktype) + krb5_context context; + 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; + int toktype; { - krb5_error_code code; - size_t sumlen; - char *data_ptr; - krb5_data plaind; - krb5_checksum md5cksum; - krb5_checksum cksum; - int conflen=0, tmsglen, tlen; - unsigned char *t, *ptr; - - /* create the token buffer */ - - if (toktype == KG_TOK_SEAL_MSG) { - if (bigend && !encrypt) { - tmsglen = text->length; - } else { - conflen = kg_confounder_size(context, enc); - /* XXX knows that des block size is 8 */ - tmsglen = (conflen+text->length+8)&(~7); - } - } else { - tmsglen = 0; - } - - tlen = g_token_size((gss_OID) oid, 14+cksum_size+tmsglen); - - if ((t = (unsigned char *) xmalloc(tlen)) == NULL) - return(ENOMEM); - - /*** fill in the token */ - - ptr = t; - - g_make_token_header((gss_OID) oid, 14+cksum_size+tmsglen, &ptr, toktype); - - /* 0..1 SIGN_ALG */ - - ptr[0] = signalg; - ptr[1] = 0; - - /* 2..3 SEAL_ALG or Filler */ - - if ((toktype == KG_TOK_SEAL_MSG) && encrypt) { - ptr[2] = sealalg; - ptr[3] = 0; - } else { - /* No seal */ - ptr[2] = 0xff; - ptr[3] = 0xff; - } - - /* 4..5 Filler */ - - ptr[4] = 0xff; - ptr[5] = 0xff; - - /* pad the plaintext, encrypt if needed, and stick it in the token */ - - /* initialize the the cksum */ - if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen)) - return(code); - - md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; - md5cksum.length = sumlen; - if (toktype == KG_TOK_SEAL_MSG) { - unsigned char *plain; - unsigned char pad; - - if (!bigend || encrypt) { - if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { - xfree(t); - return(ENOMEM); - } - - if ((code = kg_make_confounder(context, enc, plain))) { - xfree(plain); - xfree(t); - return(code); - } - - memcpy(plain+conflen, text->value, text->length); - - /* XXX 8 is DES cblock size */ - pad = 8-(text->length%8); - - memset(plain+conflen+text->length, pad, pad); - } else { - /* plain is never used in the bigend && !encrypt case */ - plain = NULL; - } + krb5_gss_ctx_id_rec *ctx; + krb5_error_code code; + krb5_timestamp now; - if (encrypt) { - if ((code = kg_encrypt(context, enc, NULL, (krb5_pointer) plain, - (krb5_pointer) (ptr+cksum_size+14), - tmsglen))) { - if (plain) - xfree(plain); - xfree(t); - return(code); - } - } else { - if (bigend) - memcpy(ptr+14+cksum_size, text->value, text->length); - else - memcpy(ptr+14+cksum_size, plain, tmsglen); - } - - /* compute the checksum */ - - /* 8 = head of token body as specified by mech spec */ - if (! (data_ptr = - (char *) xmalloc(8 + (bigend ? text->length : tmsglen)))) { - if (plain) - xfree(plain); - xfree(t); - return(ENOMEM); - } - (void) memcpy(data_ptr, ptr-2, 8); - if (bigend) - (void) memcpy(data_ptr+8, text->value, text->length); - else - (void) memcpy(data_ptr+8, plain, tmsglen); - plaind.length = 8 + (bigend ? text->length : tmsglen); - plaind.data = data_ptr; - code = krb5_c_make_checksum(context, md5cksum.checksum_type, - 0, 0, &plaind, &md5cksum); - xfree(data_ptr); - - if (code) { - if (plain) - xfree(plain); - xfree(t); - return(code); - memcpy(ptr+14+cksum_size, plain, tmsglen); - } - - if (plain) - xfree(plain); - } else { - /* compute the checksum */ - - if (! (data_ptr = (char *) xmalloc(8 + text->length))) { - xfree(t); - return(ENOMEM); - } - (void) memcpy(data_ptr, ptr-2, 8); - (void) memcpy(data_ptr+8, text->value, text->length); - plaind.length = 8 + text->length; - plaind.data = data_ptr; - code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, - &plaind, &md5cksum); - xfree(data_ptr); - if (code) { - xfree(t); - return(code); - } - } - - switch(signalg) { - case 0: - case 3: + output_message_buffer->length = 0; + output_message_buffer->value = NULL; + /* only default qop or matching established cryptosystem is allowed */ + #if 0 - /* XXX this depends on the key being a single-des key */ - - /* DES CBC doesn't use a zero IV like it should in some - krb5 implementations (beta5+). So we just do the - DES encryption the long way, and keep the last block - as the MAC */ - - /* XXX not converted to new api since it's inside an #if 0 */ - - /* initialize the the cksum and allocate the contents buffer */ - cksum.checksum_type = CKSUMTYPE_DESCBC; - cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC); - if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL) - return(ENOMEM); - - /* XXX not converted to new api since it's inside an #if 0 */ - if (code = krb5_calculate_checksum(context, cksum.checksum_type, - md5cksum.contents, 16, - seq->contents, - seq->length, - &cksum)) { - xfree(cksum.contents); - xfree(md5cksum.contents); - xfree(t); - return(code); - } - - memcpy(ptr+14, cksum.contents, 8); - - xfree(cksum.contents); + switch (qop_req & GSS_KRB5_CONF_C_QOP_MASK) { + case GSS_C_QOP_DEFAULT: + break; + default: + unknown_qop: + *minor_status = (OM_uint32) G_UNKNOWN_QOP; + return GSS_S_FAILURE; + case GSS_KRB5_CONF_C_QOP_DES: + if (ctx->sealalg != SEAL_ALG_DES) { + bad_qop: + *minor_status = (OM_uint32) G_BAD_QOP; + return GSS_S_FAILURE; + } + break; + case GSS_KRB5_CONF_C_QOP_DES3: + if (ctx->sealalg != SEAL_ALG_DES3) + goto bad_qop; + break; + } + switch (qop_req & GSS_KRB5_INTEG_C_QOP_MASK) { + case GSS_C_QOP_DEFAULT: + break; + default: + goto unknown_qop; + case GSS_KRB5_INTEG_C_QOP_MD5: + case GSS_KRB5_INTEG_C_QOP_DES_MD5: + case GSS_KRB5_INTEG_C_QOP_DES_MAC: + if (ctx->sealalg != SEAL_ALG_DES) + goto bad_qop; + break; + case GSS_KRB5_INTEG_C_QOP_HMAC_SHA1: + if (ctx->sealalg != SEAL_ALG_DES3KD) + goto bad_qop; + break; + } #else - if ((code = kg_encrypt(context, seq, - (g_OID_equal(oid, gss_mech_krb5_old) ? - seq->contents : NULL), - md5cksum.contents, md5cksum.contents, 16))) { - xfree(md5cksum.contents); - xfree(t); - return code; - } - - cksum.length = cksum_size; - cksum.contents = md5cksum.contents + 16 - cksum.length; - - memcpy(ptr+14, cksum.contents, cksum.length); + if (qop_req != 0) { + *minor_status = (OM_uint32) G_UNKNOWN_QOP; + return GSS_S_FAILURE; + } #endif - break; - } - - xfree(md5cksum.contents); - - /* create the seq_num */ + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_NO_CONTEXT); + } - if ((code = kg_make_seq_num(context, seq, direction?0:0xff, *seqnum, - ptr+14, ptr+6))) { - xfree(t); - return(code); - } + ctx = (krb5_gss_ctx_id_rec *) context_handle; - /* that's it. return the token */ + if (! ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } - (*seqnum)++; + if ((code = krb5_timeofday(context, &now))) { + *minor_status = code; + return(GSS_S_FAILURE); + } - token->length = tlen; - token->value = (void *) t; + code = make_seal_token_v1(context, ctx->enc, ctx->seq, + &ctx->seq_send, ctx->initiate, + input_message_buffer, output_message_buffer, + ctx->signalg, ctx->cksum_size, ctx->sealalg, + conf_req_flag, toktype, ctx->big_endian, + ctx->mech_used); - return(0); -} + if (code) { + *minor_status = code; + return(GSS_S_FAILURE); + } -/* if signonly is true, ignore conf_req, conf_state, - and do not encode the ENC_TYPE, MSG_LENGTH, or MSG_TEXT fields */ + if (conf_state) + *conf_state = conf_req_flag; -OM_uint32 -kg_seal(context, minor_status, context_handle, conf_req_flag, qop_req, - input_message_buffer, conf_state, output_message_buffer, toktype) - krb5_context context; - 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; - int toktype; -{ - krb5_gss_ctx_id_rec *ctx; - krb5_error_code code; - krb5_timestamp now; - - output_message_buffer->length = 0; - output_message_buffer->value = NULL; - - /* only default qop is allowed */ - if (qop_req != GSS_C_QOP_DEFAULT) { - *minor_status = (OM_uint32) G_UNKNOWN_QOP; - return(GSS_S_FAILURE); - } - - /* validate the context handle */ - if (! kg_validate_ctx_id(context_handle)) { - *minor_status = (OM_uint32) G_VALIDATE_FAILED; - return(GSS_S_NO_CONTEXT); - } - - ctx = (krb5_gss_ctx_id_rec *) context_handle; - - if (! ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } - - if ((code = krb5_timeofday(context, &now))) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - if (ctx->gsskrb5_version == 2000) { - if (toktype == KG_TOK_WRAP_MSG) { - if (conf_req_flag) - toktype = KG2_TOK_WRAP_PRIV; - else - toktype = KG2_TOK_WRAP_INTEG; - } else { - toktype = KG2_TOK_MIC; - } - - if (conf_req_flag) { - code = make_priv_token_v2(context, ctx->subkey, &ctx->seq_send, - ctx->initiate, input_message_buffer, - output_message_buffer, ctx->mech_used); - } else { - code = make_integ_token_v2(context, ctx->subkey, ctx->ctypes[0], - &ctx->seq_send, ctx->initiate, - input_message_buffer, - output_message_buffer, toktype, - ctx->mech_used); - } - } else { - code = make_seal_token_v1(context, ctx->enc, ctx->seq, - &ctx->seq_send, ctx->initiate, - input_message_buffer, output_message_buffer, - ctx->signalg, ctx->cksum_size, ctx->sealalg, - conf_req_flag, toktype, ctx->big_endian, - ctx->mech_used); - } - - if (code) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - if (conf_state) - *conf_state = conf_req_flag; - - *minor_status = 0; - return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE); + *minor_status = 0; + return((ctx->endtime < now)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE); } diff --git a/src/lib/gssapi/krb5/k5unseal.c b/src/lib/gssapi/krb5/k5unseal.c index 64a9539..9e4d353 100644 --- a/src/lib/gssapi/krb5/k5unseal.c +++ b/src/lib/gssapi/krb5/k5unseal.c @@ -1,6 +1,6 @@ /* * Copyright 1993 by OpenVision Technologies, Inc. - * + * * Permission to use, copy, modify, distribute, and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appears in all copies and @@ -10,7 +10,7 @@ * without specific, written prior permission. OpenVision makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. - * + * * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR @@ -22,14 +22,14 @@ /* * Copyright (C) 1998 by the FundsXpress, INC. - * + * * All rights reserved. - * + * * 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 @@ -40,7 +40,7 @@ * permission. FundsXpress makes no representations about the suitability of * this software for any purpose. It is provided "as is" without express * or implied warranty. - * + * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. @@ -53,834 +53,438 @@ * $Id$ */ -static OM_uint32 -kg2_verify_mic(context, minor_status, ctx, ptr, bodysize, - text, qop_state) - krb5_context context; - OM_uint32 *minor_status; - krb5_gss_ctx_id_rec *ctx; - unsigned char *ptr; - int bodysize; - gss_buffer_t text; - gss_qop_t *qop_state; +/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX + conf_state is only valid if SEAL. */ + +OM_uint32 +kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, + conf_state, qop_state, toktype) + krb5_context context; + OM_uint32 *minor_status; + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + gss_buffer_t message_buffer; + int *conf_state; + int *qop_state; + int toktype; { - size_t cksumlen; krb5_error_code code; - krb5_data plain; - krb5_cksumtype tctype; - krb5_ui_4 tseqnum; - int tdirection; + int tmsglen; + int conflen = 0; + int signalg; + int sealalg; + gss_buffer_desc token; krb5_checksum cksum; - krb5_boolean ckvalid; + krb5_checksum md5cksum; + krb5_data plaind; + char *data_ptr; krb5_timestamp now; + unsigned char *plain; + int cksum_len = 0; + int plainlen; + int direction; + krb5_int32 seqnum; OM_uint32 retval; + size_t sumlen; - plain.data = 0; - cksum.contents = 0; - - /* verify the header */ - - if (bodysize < 11) { - free(plain.data); - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); + if (toktype == KG_TOK_SEAL_MSG) { + message_buffer->length = 0; + message_buffer->value = NULL; } - /* allocate the checksum buffer */ - - plain.length = 7+text->length; - - if ((plain.data = (char *) malloc(plain.length)) == NULL) { - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } + /* get the sign and seal algorithms */ - /* suck out the body parts from the token */ + signalg = ptr[0] + (ptr[1]<<8); + sealalg = ptr[2] + (ptr[3]<<8); - tctype = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) | - (ptr[2]<<8) | ptr[3]); - ptr += 4; + /* Sanity checks */ - memcpy(plain.data, ptr, 5); - tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); - ptr += 4; - tdirection = ptr[0]; - ptr += 1; - - cksum.length = (ptr[0]<<8) | ptr[1]; - ptr += 2; - bodysize -= 11; - - if (cksum.length != bodysize) { - free(plain.data); - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); + if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; } - cksum.contents = ptr; - cksum.checksum_type = tctype; + if ((toktype != KG_TOK_SEAL_MSG) && + (sealalg != 0xffff)) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } - /* finish assembling the checksum buffer and compute the checksum */ + /* in the current spec, there is only one valid seal algorithm per + key type, so a simple comparison is ok */ - plain.data[5] = (text->length >> 8) & 0xff; - plain.data[6] = text->length & 0xff; + if ((toktype == KG_TOK_SEAL_MSG) && + !((sealalg == 0xffff) || + (sealalg == ctx->sealalg))) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; + } - memcpy(plain.data+7, text->value, text->length); + /* there are several mappings of seal algorithms to sign algorithms, + but few enough that we can try them all. */ - if (code = krb5_c_verify_checksum(context, ctx->subkey, - KRB5_KEYUSAGE_GSS_TOK_MIC, - &plain, &cksum, &ckvalid)) { - free(plain.data); - *minor_status = code; - return(GSS_S_FAILURE); + if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) || + (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) || + (ctx->sealalg == SEAL_ALG_DES3KD && + signalg != SGN_ALG_HMAC_SHA1_DES3_KD)) { + *minor_status = 0; + return GSS_S_DEFECTIVE_TOKEN; } - if (!ckvalid) { - free(plain.data); + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_MD2_5: + cksum_len = 8; + break; + case SGN_ALG_3: + cksum_len = 16; + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + cksum_len = 20; + break; + default: *minor_status = 0; - return(GSS_S_BAD_SIG); + return GSS_S_DEFECTIVE_TOKEN; } - /* check context expiry */ + if (toktype == KG_TOK_SEAL_MSG) + tmsglen = bodysize-(14+cksum_len); - if ((code = krb5_timeofday(context, &now))) { - free(plain.data); - *minor_status = code; - return(GSS_S_FAILURE); - } + /* get the token parameters */ - if (now > ctx->endtime) { - free(plain.data); - *minor_status = 0; - return(GSS_S_CONTEXT_EXPIRED); - } + /* decode the message, if SEAL */ - /* do sequencing checks */ + if (toktype == KG_TOK_SEAL_MSG) { + if (sealalg != 0xffff) { + if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } - if ((ctx->initiate && tdirection != 0xff) || - (!ctx->initiate && tdirection != 0)) { - free(plain.data); - *minor_status = G_BAD_DIRECTION; - return(GSS_S_BAD_SIG); - } + if ((code = kg_decrypt(context, ctx->enc, KG_USAGE_SEAL, NULL, + ptr+14+cksum_len, plain, tmsglen))) { + xfree(plain); + *minor_status = code; + return(GSS_S_FAILURE); + } + } else { + plain = ptr+14+cksum_len; + } - retval = g_order_check(&(ctx->seqstate), tseqnum); + plainlen = tmsglen; - free(plain.data); + if ((sealalg == 0xffff) && ctx->big_endian) { + token.length = tmsglen; + } else { + conflen = kg_confounder_size(context, ctx->enc); + token.length = tmsglen - conflen - plain[tmsglen-1]; + } - if (retval) { - *minor_status = 0; - return(retval); - } + if (token.length) { + if ((token.value = (void *) xmalloc(token.length)) == NULL) { + if (sealalg != 0xffff) + xfree(plain); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + memcpy(token.value, plain+conflen, token.length); + } + } else if (toktype == KG_TOK_SIGN_MSG) { + token = *message_buffer; + plain = token.value; + plainlen = token.length; + } else { + token.length = 0; + token.value = NULL; + plain = token.value; + plainlen = token.length; + } - if (qop_state) - *qop_state = GSS_C_QOP_DEFAULT; + /* compute the checksum of the message */ + + /* initialize the the cksum */ + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_MD2_5: + case SGN_ALG_HMAC_MD5: + case SGN_ALG_DES_MAC: + case SGN_ALG_3: + md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; + break; + case SGN_ALG_HMAC_SHA1_DES3_KD: + md5cksum.checksum_type = CKSUMTYPE_HMAC_SHA1_DES3; + break; + default: + abort (); + } - *minor_status = 0; - return(GSS_S_COMPLETE); -} + if (code = krb5_c_checksum_length(context, md5cksum.checksum_type, &sumlen)) + return(code); + md5cksum.length = sumlen; -static OM_uint32 -kg2_unwrap_integ(context, minor_status, ctx, ptr, bodysize, output, qop_state) - krb5_context context; - OM_uint32 *minor_status; - krb5_gss_ctx_id_rec *ctx; - unsigned char *ptr; - int bodysize; - gss_buffer_t output; - gss_qop_t *qop_state; -{ - krb5_error_code code; - OM_uint32 retval; - krb5_ui_4 tseqnum; - int tdirection; - int tmsglen; - unsigned char *tmsg; - krb5_data plain; - krb5_checksum tcksum; - krb5_boolean ckvalid; - krb5_timestamp now; + switch (signalg) { + case SGN_ALG_DES_MAC_MD5: + case SGN_ALG_3: + /* compute the checksum of the message */ - output->length = 0; - output->value = NULL; + /* 8 = bytes of token body to be checksummed according to spec */ - /* read the body parts out of the message */ + if (! (data_ptr = (void *) + xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) { + if (sealalg != 0xffff) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } - if (bodysize < 11) { - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); - } + (void) memcpy(data_ptr, ptr-2, 8); - tcksum.checksum_type = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) | - (ptr[2]<<8) | ptr[3]); - ptr += 4; + if (ctx->big_endian) + (void) memcpy(data_ptr+8, token.value, token.length); + else + (void) memcpy(data_ptr+8, plain, plainlen); - plain.data = ptr; + plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, + ctx->seq, KG_USAGE_SIGN, + &plaind, &md5cksum); + xfree(data_ptr); + + if (code) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return(GSS_S_FAILURE); + } - tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); - ptr += 4; - tdirection = ptr[0]; - ptr += 1; + if ((code = kg_encrypt(context, ctx->seq, KG_USAGE_SEAL, + (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? + ctx->seq->contents : NULL), + md5cksum.contents, md5cksum.contents, 16))) { + xfree(md5cksum.contents); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return GSS_S_FAILURE; + } - tmsglen = (ptr[0]<<8) | ptr[1]; - ptr += 2; - bodysize -= 11; + if (signalg == 0) + cksum.length = 8; + else + cksum.length = 16; + cksum.contents = md5cksum.contents + 16 - cksum.length; - if (bodysize < tmsglen) { - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); - } + code = memcmp(cksum.contents, ptr+14, cksum.length); + break; - tmsg = ptr; - ptr += tmsglen; - bodysize -= tmsglen; + case SGN_ALG_MD2_5: + if (!ctx->seed_init && + (code = kg_make_seed(context, ctx->subkey, ctx->seed))) { + xfree(md5cksum.contents); + if (sealalg != 0xffff) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return GSS_S_FAILURE; + } - plain.length = ((char*)ptr) - ((char *)plain.data); + if (! (data_ptr = (void *) + xmalloc(sizeof(ctx->seed) + 8 + + (ctx->big_endian ? token.length : plainlen)))) { + xfree(md5cksum.contents); + if (sealalg == 0) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + (void) memcpy(data_ptr, ptr-2, 8); + (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed)); + if (ctx->big_endian) + (void) memcpy(data_ptr+8+sizeof(ctx->seed), + token.value, token.length); + else + (void) memcpy(data_ptr+8+sizeof(ctx->seed), + plain, plainlen); + plaind.length = 8 + sizeof(ctx->seed) + + (ctx->big_endian ? token.length : plainlen); + plaind.data = data_ptr; + xfree(md5cksum.contents); + code = krb5_c_make_checksum(context, md5cksum.checksum_type, + ctx->seq, KG_USAGE_SIGN, + &plaind, &md5cksum); + xfree(data_ptr); + + if (code) { + if (sealalg == 0) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return(GSS_S_FAILURE); + } - tcksum.length = (ptr[0]<<8) | ptr[1]; - ptr += 2; - bodysize -= 2; + code = memcmp(md5cksum.contents, ptr+14, 8); + /* Falls through to defective-token?? */ - if (bodysize != tcksum.length) { - *minor_status = G_TOK_TRUNC; + default: + *minor_status = 0; return(GSS_S_DEFECTIVE_TOKEN); - } - - tcksum.contents = ptr; - /* verify the MIC */ + case SGN_ALG_HMAC_SHA1_DES3_KD: + /* compute the checksum of the message */ - if (code = krb5_c_verify_checksum(context, ctx->subkey, - KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG, - &plain, &tcksum, &ckvalid)) { - *minor_status = code; - return(GSS_S_FAILURE); - } + /* 8 = bytes of token body to be checksummed according to spec */ - if (!ckvalid) { - *minor_status = 0; - return(GSS_S_BAD_SIG); - } + if (! (data_ptr = (void *) + xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) { + if (sealalg != 0xffff) + xfree(plain); + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } - /* check context expiry */ - - if ((code = krb5_timeofday(context, &now))) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - if (now > ctx->endtime) { - *minor_status = 0; - return(GSS_S_CONTEXT_EXPIRED); - } - - /* do sequencing checks */ - - if ((ctx->initiate && tdirection != 0xff) || - (!ctx->initiate && tdirection != 0)) { - *minor_status = G_BAD_DIRECTION; - return(GSS_S_BAD_SIG); - } - - if (retval = g_order_check(&(ctx->seqstate), tseqnum)) { - *minor_status = 0; - return(retval); - } - - if (tmsglen) { - if ((output->value = (void *) malloc(tmsglen)) == NULL) { - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - memcpy(output->value, tmsg, tmsglen); - output->length = tmsglen; - } - - if (qop_state) - *qop_state = GSS_C_QOP_DEFAULT; - - *minor_status = 0; - return(GSS_S_COMPLETE); -} + (void) memcpy(data_ptr, ptr-2, 8); -static OM_uint32 -kg2_unwrap_priv(context, minor_status, ctx, ptr, bodysize, output, qop_state) - krb5_context context; - OM_uint32 *minor_status; - krb5_gss_ctx_id_rec *ctx; - unsigned char *ptr; - int bodysize; - gss_buffer_t output; - gss_qop_t *qop_state; -{ - krb5_error_code code; - OM_uint32 retval; - krb5_enc_data cipher; - krb5_data plain; - krb5_ui_4 tseqnum; - int tdirection; - int tmsglen; - unsigned char *tmsg; - krb5_timestamp now; + if (ctx->big_endian) + (void) memcpy(data_ptr+8, token.value, token.length); + else + (void) memcpy(data_ptr+8, plain, plainlen); - output->length = 0; - output->value = NULL; + plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); + plaind.data = data_ptr; + code = krb5_c_make_checksum(context, md5cksum.checksum_type, + ctx->seq, KG_USAGE_SIGN, + &plaind, &md5cksum); + xfree(data_ptr); - /* read the body parts out of the message */ + if (code) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; + return(GSS_S_FAILURE); + } - if (bodysize < 2) { - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); + code = memcmp(md5cksum.contents, ptr+14, md5cksum.length); + break; } - cipher.ciphertext.length = (ptr[0]<<8) | ptr[1]; - ptr += 2; - bodysize -= 2; + xfree(md5cksum.contents); + if (sealalg != 0xffff) + xfree(plain); - if (bodysize != cipher.ciphertext.length) { - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); - } + /* compare the computed checksum against the transmitted checksum */ - cipher.ciphertext.data = ptr; - cipher.enctype = ENCTYPE_UNKNOWN; - - plain.length = cipher.ciphertext.length; - if ((plain.data = (char *) malloc(plain.length)) == NULL) { + if (code) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); *minor_status = 0; - return(GSS_S_FAILURE); - } - - /* decrypt (and implicitly verify) the encrypted data */ - - if (code = krb5_c_decrypt(context, ctx->subkey, - KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV, - 0, &cipher, &plain)) { - free(plain.data); - *minor_status = code; - return(GSS_S_FAILURE); + return(GSS_S_BAD_SIG); } - /* parse out the encrypted fields */ - ptr = plain.data; - bodysize = plain.length; + /* it got through unscathed. Make sure the context is unexpired */ - if (bodysize < 7) { - free(plain.data); - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); - } + if (toktype == KG_TOK_SEAL_MSG) + *message_buffer = token; - tseqnum = ((ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]); - ptr += 4; - tdirection = ptr[0]; - ptr += 1; + if (conf_state) + *conf_state = (sealalg != 0xffff); - tmsglen = (ptr[0]<<8) | ptr[1]; - ptr += 2; - bodysize -= 7; - - /* check context expiry */ + if (qop_state) + *qop_state = GSS_C_QOP_DEFAULT; if ((code = krb5_timeofday(context, &now))) { - free(plain.data); *minor_status = code; return(GSS_S_FAILURE); } if (now > ctx->endtime) { - free(plain.data); *minor_status = 0; return(GSS_S_CONTEXT_EXPIRED); } /* do sequencing checks */ - if ((ctx->initiate && tdirection != 0xff) || - (!ctx->initiate && tdirection != 0)) { - free(plain.data); - *minor_status = G_BAD_DIRECTION; + if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction, + &seqnum))) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = code; return(GSS_S_BAD_SIG); } - if (retval = g_order_check(&(ctx->seqstate), tseqnum)) { - free(plain.data); - *minor_status = 0; - return(retval); - } - - /* now copy out the data. can't do a strict equality check here, - since the output could be padded. */ - - if (bodysize < tmsglen) { - free(plain.data); - *minor_status = G_TOK_TRUNC; - return(GSS_S_DEFECTIVE_TOKEN); - } - - tmsg = ptr; - - if (tmsglen) { - if ((output->value = (void *) malloc(tmsglen)) == NULL) { - free(plain.data); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - memcpy(output->value, tmsg, tmsglen); - output->length = tmsglen; + if ((ctx->initiate && direction != 0xff) || + (!ctx->initiate && direction != 0)) { + if (toktype == KG_TOK_SEAL_MSG) + xfree(token.value); + *minor_status = G_BAD_DIRECTION; + return(GSS_S_BAD_SIG); } - if (qop_state) - *qop_state = GSS_C_QOP_DEFAULT; + retval = g_order_check(&(ctx->seqstate), seqnum); - free(plain.data); + /* success or ordering violation */ *minor_status = 0; - return(GSS_S_COMPLETE); + return(retval); } /* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX conf_state is only valid if SEAL. */ OM_uint32 -kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, message_buffer, - conf_state, qop_state, toktype) - krb5_context context; - OM_uint32 *minor_status; - krb5_gss_ctx_id_rec *ctx; - unsigned char *ptr; - int bodysize; - gss_buffer_t message_buffer; - int *conf_state; - int *qop_state; - int toktype; +kg_unseal(context, minor_status, context_handle, input_token_buffer, + message_buffer, conf_state, qop_state, toktype) + krb5_context context; + OM_uint32 *minor_status; + gss_ctx_id_t context_handle; + gss_buffer_t input_token_buffer; + gss_buffer_t message_buffer; + int *conf_state; + int *qop_state; + int toktype; { - krb5_error_code code; - int tmsglen; - int conflen = 0; - int signalg; - int sealalg; - gss_buffer_desc token; - krb5_checksum cksum; - krb5_checksum desmac; - krb5_checksum md5cksum; - krb5_data plaind; - char *data_ptr; - krb5_timestamp now; - unsigned char *plain; - int cksum_len = 0; - int plainlen; - int err; - int direction; - krb5_int32 seqnum; - OM_uint32 retval; - size_t sumlen; - - if (toktype == KG_TOK_SEAL_MSG) { - message_buffer->length = 0; - message_buffer->value = NULL; - } - - /* get the sign and seal algorithms */ - - signalg = ptr[0] + (ptr[1]<<8); - sealalg = ptr[2] + (ptr[3]<<8); - - /* Sanity checks */ - - if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) { - *minor_status = 0; - return GSS_S_DEFECTIVE_TOKEN; - } - - if ((toktype != KG_TOK_SEAL_MSG) && - (sealalg != 0xffff)) { - *minor_status = 0; - return GSS_S_DEFECTIVE_TOKEN; - } - - /* in the current spec, there is only one valid seal algorithm per - key type, so a simple comparison is ok */ - - if ((toktype == KG_TOK_SEAL_MSG) && - !((sealalg == 0xffff) || - (sealalg == ctx->sealalg))) { - *minor_status = 0; - return GSS_S_DEFECTIVE_TOKEN; - } - - /* there are several mappings of seal algorithms to sign algorithms, - but few enough that we can try them all. */ - - if (((ctx->sealalg == 0) && - (signalg > 1)) || - ((ctx->sealalg == 1) && - (signalg != 3))) { - *minor_status = 0; - return GSS_S_DEFECTIVE_TOKEN; - } - - switch (signalg) { - case 0: - case 1: - cksum_len = 8; - break; - case 3: - cksum_len = 16; - break; - } - - if (toktype == KG_TOK_SEAL_MSG) - tmsglen = bodysize-(14+cksum_len); - - /* get the token parameters */ - - /* decode the message, if SEAL */ - - if (toktype == KG_TOK_SEAL_MSG) { - if (sealalg != 0xffff) { - if ((plain = (unsigned char *) xmalloc(tmsglen)) == NULL) { - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } + krb5_gss_ctx_id_rec *ctx; + unsigned char *ptr; + int bodysize; + int err; + + /* validate the context handle */ + if (! kg_validate_ctx_id(context_handle)) { + *minor_status = (OM_uint32) G_VALIDATE_FAILED; + return(GSS_S_NO_CONTEXT); + } - if ((code = kg_decrypt(context, ctx->enc, NULL, - ptr+14+cksum_len, plain, tmsglen))) { - xfree(plain); - *minor_status = code; - return(GSS_S_FAILURE); - } - } else { - plain = ptr+14+cksum_len; - } - - plainlen = tmsglen; - - if ((sealalg == 0xffff) && ctx->big_endian) { - token.length = tmsglen; - } else { - conflen = kg_confounder_size(context, ctx->enc); - token.length = tmsglen - conflen - plain[tmsglen-1]; - } - - if (token.length) { - if ((token.value = (void *) xmalloc(token.length)) == NULL) { - if (sealalg != 0xffff) - xfree(plain); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - memcpy(token.value, plain+conflen, token.length); - } - } else if (toktype == KG_TOK_SIGN_MSG) { - token = *message_buffer; - plain = token.value; - plainlen = token.length; - } else { - token.length = 0; - token.value = NULL; - plain = token.value; - plainlen = token.length; - } - - /* compute the checksum of the message */ - - /* initialize the the cksum */ - if (code = krb5_c_checksum_length(context, CKSUMTYPE_RSA_MD5, &sumlen)) - return(code); - - md5cksum.checksum_type = CKSUMTYPE_RSA_MD5; - md5cksum.length = sumlen; - - switch (signalg) { - case 0: - case 3: - /* compute the checksum of the message */ - - /* 8 = bytes of token body to be checksummed according to spec */ - - if (! (data_ptr = (void *) - xmalloc(8 + (ctx->big_endian ? token.length : plainlen)))) { - if (sealalg != 0xffff) - xfree(plain); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - - (void) memcpy(data_ptr, ptr-2, 8); - - if (ctx->big_endian) - (void) memcpy(data_ptr+8, token.value, token.length); - else - (void) memcpy(data_ptr+8, plain, plainlen); - - plaind.length = 8 + (ctx->big_endian ? token.length : plainlen); - plaind.data = data_ptr; - code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, - &plaind, &md5cksum); - xfree(data_ptr); - - if (code) { - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return(GSS_S_FAILURE); - } - -#if 0 - /* XXX this depends on the key being a single-des key, but that's - all that kerberos supports right now */ - - /* initialize the the cksum and allocate the contents buffer */ - cksum.checksum_type = CKSUMTYPE_DESCBC; - cksum.length = krb5_checksum_size(context, CKSUMTYPE_DESCBC); - if ((cksum.contents = (krb5_octet *) xmalloc(cksum.length)) == NULL) { - xfree(md5cksum.contents); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - - /* XXX not converted to new api since it's inside an #if 0 */ - if (code = krb5_calculate_checksum(context, cksum.checksum_type, - md5cksum.contents, 16, - ctx->seq.key->contents, - ctx->seq.key->length, - &cksum)) { - xfree(cksum.contents); - xfree(md5cksum.contents); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return(GSS_S_FAILURE); - } - - code = memcmp(cksum.contents, ptr+14, cksum.length); - - xfree(cksum.contents); -#else - if ((code = kg_encrypt(context, ctx->seq, - (g_OID_equal(ctx->mech_used, gss_mech_krb5_old) ? - ctx->seq->contents : NULL), - md5cksum.contents, md5cksum.contents, 16))) { - xfree(md5cksum.contents); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return GSS_S_FAILURE; - } - - if (signalg == 0) - cksum.length = 8; - else - cksum.length = 16; - cksum.contents = md5cksum.contents + 16 - cksum.length; - - code = memcmp(cksum.contents, ptr+14, cksum.length); -#endif - break; - - case 1: - if (!ctx->seed_init && - (code = kg_make_seed(context, ctx->subkey, ctx->seed))) { - xfree(md5cksum.contents); - if (sealalg != 0xffff) - xfree(plain); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return GSS_S_FAILURE; - } - - if (! (data_ptr = (void *) - xmalloc(sizeof(ctx->seed) + 8 + - (ctx->big_endian ? token.length : plainlen)))) { - xfree(md5cksum.contents); - if (sealalg == 0) - xfree(plain); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = ENOMEM; - return(GSS_S_FAILURE); - } - (void) memcpy(data_ptr, ptr-2, 8); - (void) memcpy(data_ptr+8, ctx->seed, sizeof(ctx->seed)); - if (ctx->big_endian) - (void) memcpy(data_ptr+8+sizeof(ctx->seed), - token.value, token.length); - else - (void) memcpy(data_ptr+8+sizeof(ctx->seed), - plain, plainlen); - plaind.length = 8 + sizeof(ctx->seed) + - (ctx->big_endian ? token.length : plainlen); - plaind.data = data_ptr; - xfree(md5cksum.contents); - code = krb5_c_make_checksum(context, md5cksum.checksum_type, 0, 0, - &plaind, &md5cksum); - xfree(data_ptr); - - if (code) { - if (sealalg == 0) - xfree(plain); - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return(GSS_S_FAILURE); - } - - code = memcmp(md5cksum.contents, ptr+14, 8); - - default: - *minor_status = 0; - return(GSS_S_DEFECTIVE_TOKEN); - } - - xfree(md5cksum.contents); - if (sealalg != 0xffff) - xfree(plain); - - /* compare the computed checksum against the transmitted checksum */ - - if (code) { - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = 0; - return(GSS_S_BAD_SIG); - } - - - /* it got through unscathed. Make sure the context is unexpired */ - - if (toktype == KG_TOK_SEAL_MSG) - *message_buffer = token; - - if (conf_state) - *conf_state = (sealalg != 0xffff); - - if (qop_state) - *qop_state = GSS_C_QOP_DEFAULT; - - if ((code = krb5_timeofday(context, &now))) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - if (now > ctx->endtime) { - *minor_status = 0; - return(GSS_S_CONTEXT_EXPIRED); - } - - /* do sequencing checks */ - - if ((code = kg_get_seq_num(context, ctx->seq, ptr+14, ptr+6, &direction, - &seqnum))) { - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = code; - return(GSS_S_BAD_SIG); - } - - if ((ctx->initiate && direction != 0xff) || - (!ctx->initiate && direction != 0)) { - if (toktype == KG_TOK_SEAL_MSG) - xfree(token.value); - *minor_status = G_BAD_DIRECTION; - return(GSS_S_BAD_SIG); - } - - retval = g_order_check(&(ctx->seqstate), seqnum); - - /* success or ordering violation */ - - *minor_status = 0; - return(retval); -} + ctx = (krb5_gss_ctx_id_rec *) context_handle; -/* message_buffer is an input if SIGN, output if SEAL, and ignored if DEL_CTX - conf_state is only valid if SEAL. */ + if (! ctx->established) { + *minor_status = KG_CTX_INCOMPLETE; + return(GSS_S_NO_CONTEXT); + } -OM_uint32 -kg_unseal(context, minor_status, context_handle, input_token_buffer, - message_buffer, conf_state, qop_state, toktype) - krb5_context context; - OM_uint32 *minor_status; - gss_ctx_id_t context_handle; - gss_buffer_t input_token_buffer; - gss_buffer_t message_buffer; - int *conf_state; - int *qop_state; - int toktype; -{ - krb5_gss_ctx_id_rec *ctx; - unsigned char *ptr; - int bodysize; - int err; - OM_uint32 retval; - - /* validate the context handle */ - if (! kg_validate_ctx_id(context_handle)) { - *minor_status = (OM_uint32) G_VALIDATE_FAILED; - return(GSS_S_NO_CONTEXT); - } - - ctx = (krb5_gss_ctx_id_rec *) context_handle; - - if (! ctx->established) { - *minor_status = KG_CTX_INCOMPLETE; - return(GSS_S_NO_CONTEXT); - } - - /* parse the token, leave the data in message_buffer, setting conf_state */ - - /* verify the header */ - - ptr = (unsigned char *) input_token_buffer->value; - - if (ctx->gsskrb5_version == 2000) { - if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, - &bodysize, &ptr, KG2_TOK_MIC, - input_token_buffer->length))) { - return(kg2_verify_mic(context, minor_status, ctx, ptr, bodysize, - message_buffer, qop_state)); - } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, - &bodysize, &ptr, - KG2_TOK_WRAP_INTEG, - input_token_buffer->length))) { - if (GSS_ERROR(retval = kg2_unwrap_integ(context, minor_status, - ctx, ptr, bodysize, - message_buffer, qop_state))) - return(retval); - - if (conf_state) - *conf_state = 0; - return(GSS_S_COMPLETE); - } else if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, - &bodysize, &ptr, - KG2_TOK_WRAP_PRIV, - input_token_buffer->length))) { - if (GSS_ERROR(retval = kg2_unwrap_priv(context, minor_status, - ctx, ptr, bodysize, - message_buffer, qop_state))) - return(retval); - - if (conf_state) - *conf_state = 1; - return(GSS_S_COMPLETE); - } - } else { - if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, - &bodysize, &ptr, toktype, - input_token_buffer->length))) { - return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, - message_buffer, conf_state, qop_state, - toktype)); - } - } - - *minor_status = err; - return(GSS_S_DEFECTIVE_TOKEN); + /* parse the token, leave the data in message_buffer, setting conf_state */ + + /* verify the header */ + + ptr = (unsigned char *) input_token_buffer->value; + + if (!(err = g_verify_token_header((gss_OID) ctx->mech_used, + &bodysize, &ptr, toktype, + input_token_buffer->length))) { + return(kg_unseal_v1(context, minor_status, ctx, ptr, bodysize, + message_buffer, conf_state, qop_state, + toktype)); + } + + *minor_status = err; + return(GSS_S_DEFECTIVE_TOKEN); } diff --git a/src/lib/gssapi/krb5/ser_sctx.c b/src/lib/gssapi/krb5/ser_sctx.c index 2a6231e..1989a7d 100644 --- a/src/lib/gssapi/krb5/ser_sctx.c +++ b/src/lib/gssapi/krb5/ser_sctx.c @@ -233,7 +233,6 @@ kg_ctx_size(kcontext, arg, sizep) * krb5_int32 for seq_recv. * krb5_int32 for established. * krb5_int32 for big_endian. - * krb5_int32 for gsskrb5_version. * krb5_int32 for nctypes. * krb5_int32 for trailer. */ @@ -349,8 +348,6 @@ kg_ctx_externalize(kcontext, arg, buffer, lenremain) &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->big_endian, &bp, &remain); - (void) krb5_ser_pack_int32((krb5_int32) ctx->gsskrb5_version, - &bp, &remain); (void) krb5_ser_pack_int32((krb5_int32) ctx->nctypes, &bp, &remain); @@ -477,8 +474,6 @@ kg_ctx_internalize(kcontext, argp, buffer, lenremain) (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->big_endian = (int) ibuf; (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); - ctx->gsskrb5_version = (int) ibuf; - (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); ctx->nctypes = (int) ibuf; if ((kret = kg_oid_internalize(kcontext, &ctx->mech_used, &bp, diff --git a/src/lib/gssapi/krb5/util_cksum.c b/src/lib/gssapi/krb5/util_cksum.c index 10e6b65..47ffc5b 100644 --- a/src/lib/gssapi/krb5/util_cksum.c +++ b/src/lib/gssapi/krb5/util_cksum.c @@ -27,6 +27,7 @@ #include "gssapiP_krb5.h" #include <memory.h> +/* Checksumming the channel bindings always uses plain MD5. */ krb5_error_code kg_checksum_channel_bindings(context, cb, cksum, bigend) krb5_context context; diff --git a/src/lib/gssapi/krb5/util_crypt.c b/src/lib/gssapi/krb5/util_crypt.c index 93d4694..049e4d6 100644 --- a/src/lib/gssapi/krb5/util_crypt.c +++ b/src/lib/gssapi/krb5/util_crypt.c @@ -54,8 +54,6 @@ * $Id$ */ -static unsigned char zeros[8] = {0,0,0,0,0,0,0,0}; - int kg_confounder_size(context, key) krb5_context context; @@ -105,9 +103,10 @@ kg_encrypt_size(context, key, n) } krb5_error_code -kg_encrypt(context, key, iv, in, out, length) +kg_encrypt(context, key, usage, iv, in, out, length) krb5_context context; krb5_keyblock *key; + int usage; krb5_pointer iv; krb5_pointer in; krb5_pointer out; @@ -123,7 +122,10 @@ kg_encrypt(context, key, iv, in, out, length) return(code); ivd.length = blocksize; - ivd.data = iv; + ivd.data = malloc(ivd.length); + if (ivd.data == NULL) + return ENOMEM; + memcpy(ivd.data, iv, ivd.length); pivd = &ivd; } else { pivd = NULL; @@ -135,18 +137,19 @@ kg_encrypt(context, key, iv, in, out, length) outputd.ciphertext.length = length; outputd.ciphertext.data = out; - return(krb5_c_encrypt(context, key, - /* XXX this routine is only used for the old - bare-des stuff which doesn't use the - key usage */ 0, pivd, &inputd, &outputd)); + code = krb5_c_encrypt(context, key, usage, pivd, &inputd, &outputd); + if (pivd != NULL) + krb5_free_data_contents(context, pivd); + return code; } /* length is the length of the cleartext. */ krb5_error_code -kg_decrypt(context, key, iv, in, out, length) +kg_decrypt(context, key, usage, iv, in, out, length) krb5_context context; krb5_keyblock *key; + int usage; krb5_pointer iv; krb5_pointer in; krb5_pointer out; @@ -162,7 +165,10 @@ kg_decrypt(context, key, iv, in, out, length) return(code); ivd.length = blocksize; - ivd.data = iv; + ivd.data = malloc(ivd.length); + if (ivd.data == NULL) + return ENOMEM; + memcpy(ivd.data, iv, ivd.length); pivd = &ivd; } else { pivd = NULL; @@ -175,8 +181,8 @@ kg_decrypt(context, key, iv, in, out, length) outputd.length = length; outputd.data = out; - return(krb5_c_decrypt(context, key, - /* XXX this routine is only used for the old - bare-des stuff which doesn't use the - key usage */ 0, pivd, &inputd, &outputd)); + code = krb5_c_decrypt(context, key, usage, pivd, &inputd, &outputd); + if (pivd != NULL) + krb5_free_data_contents(context, pivd); + return code; } diff --git a/src/lib/gssapi/krb5/util_seed.c b/src/lib/gssapi/krb5/util_seed.c index 206ee68..b4a9044 100644 --- a/src/lib/gssapi/krb5/util_seed.c +++ b/src/lib/gssapi/krb5/util_seed.c @@ -47,7 +47,7 @@ kg_make_seed(context, key, seed) for (i=0; i<tmpkey->length; i++) tmpkey->contents[i] = key->contents[key->length - 1 - i]; - code = kg_encrypt(context, tmpkey, NULL, zeros, seed, 16); + code = kg_encrypt(context, tmpkey, KG_USAGE_SEAL, NULL, zeros, seed, 16); krb5_free_keyblock(context, tmpkey); diff --git a/src/lib/gssapi/krb5/util_seqnum.c b/src/lib/gssapi/krb5/util_seqnum.c index e14b2f3..b8f2b38 100644 --- a/src/lib/gssapi/krb5/util_seqnum.c +++ b/src/lib/gssapi/krb5/util_seqnum.c @@ -47,7 +47,7 @@ kg_make_seq_num(context, key, direction, seqnum, cksum, buf) plain[6] = direction; plain[7] = direction; - return(kg_encrypt(context, key, cksum, plain, buf, 8)); + return(kg_encrypt(context, key, KG_USAGE_SEQ, cksum, plain, buf, 8)); } krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum) @@ -61,7 +61,7 @@ krb5_error_code kg_get_seq_num(context, key, cksum, buf, direction, seqnum) krb5_error_code code; unsigned char plain[8]; - if (code = kg_decrypt(context, key, cksum, buf, plain, 8)) + if (code = kg_decrypt(context, key, KG_USAGE_SEQ, cksum, buf, plain, 8)) return(code); if ((plain[4] != plain[5]) || diff --git a/src/lib/gssapi/krb5/wrap_size_limit.c b/src/lib/gssapi/krb5/wrap_size_limit.c index f7fee73..55d4bce 100644 --- a/src/lib/gssapi/krb5/wrap_size_limit.c +++ b/src/lib/gssapi/krb5/wrap_size_limit.c @@ -1,4 +1,28 @@ /* + * Copyright 2000 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * 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. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * 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. + * + */ +/* * Copyright 1993 by OpenVision Technologies, Inc. * * Permission to use, copy, modify, distribute, and sell this software @@ -66,6 +90,9 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, krb5_context context; krb5_gss_ctx_id_rec *ctx; krb5_error_code code; + OM_uint32 data_size, conflen; + OM_uint32 ohlen; + int overhead; if (GSS_ERROR(kg_get_context(minor_status, &context))) return(GSS_S_FAILURE); @@ -88,92 +115,23 @@ krb5_gss_wrap_size_limit(minor_status, context_handle, conf_req_flag, return(GSS_S_NO_CONTEXT); } - if (ctx->gsskrb5_version == 2000) { - if (conf_req_flag) { - /* this is pretty gross. take the max output, and call - krb5_c_encrypt_length to see how much overhead is added - on. subtract that much, and see if it fits in the - requested space. If not, start subtracting 1 until it - does. This doesn't necessarily give us the optimal - packing, but I think that's ok (I could start adding 1 - until I went over, but that seems like it's not worth - the effort). This is probably O(blocksize), but that's - never going to be large. */ - - OM_uint32 headerlen, plainlen; - size_t enclen; - - headerlen = g_token_size((gss_OID) ctx->mech_used, 2); - plainlen = req_output_size - headerlen; - - if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, - plainlen, &enclen)) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - plainlen -= plainlen - (enclen - plainlen); - - if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, - plainlen, &enclen)) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - while (headerlen + enclen > req_output_size) { - plainlen--; - - if (code = krb5_c_encrypt_length(context, ctx->enc->enctype, - plainlen, &enclen)) { - *minor_status = code; - return(GSS_S_FAILURE); - } - } - - /* subtract off the fixed size inside the encrypted part */ - - plainlen -= 7; - - *max_input_size = plainlen; - } else { - size_t cksumlen; - OM_uint32 headerlen; - - if (code = krb5_c_checksum_length(context, ctx->ctypes[0], - &cksumlen)) { - *minor_status = code; - return(GSS_S_FAILURE); - } - - headerlen = g_token_size((gss_OID) ctx->mech_used, 13 + cksumlen); - - *max_input_size = req_output_size - headerlen; - } - } else { - OM_uint32 data_size, conflen; - OM_uint32 ohlen; - int overhead; - - /* Calculate the token size and subtract that from the output size */ - overhead = 7 + ctx->mech_used->length; - data_size = req_output_size; - if (conf_req_flag) { - conflen = kg_confounder_size(context, ctx->enc); - data_size = (conflen + data_size + 8) & (~7); - } - ohlen = g_token_size((gss_OID) ctx->mech_used, - (unsigned int) (data_size + ctx->cksum_size + 14)) - - req_output_size; - - if (ohlen+overhead < req_output_size) - /* - * Cannot have trailer length that will cause us to pad over - * our length - */ - *max_input_size = (req_output_size - ohlen - overhead) & (~7); - else - *max_input_size = 0; - } + /* Calculate the token size and subtract that from the output size */ + overhead = 7 + ctx->mech_used->length; + data_size = req_output_size; + conflen = kg_confounder_size(context, ctx->enc); + data_size = (conflen + data_size + 8) & (~(OM_uint32)7); + ohlen = g_token_size((gss_OID) ctx->mech_used, + (unsigned int) (data_size + ctx->cksum_size + 14)) + - req_output_size; + + if (ohlen+overhead < req_output_size) + /* + * Cannot have trailer length that will cause us to pad over our + * length. + */ + *max_input_size = (req_output_size - ohlen - overhead) & (~(OM_uint32)7); + else + *max_input_size = 0; *minor_status = 0; return(GSS_S_COMPLETE); diff --git a/src/lib/kadm5/ChangeLog b/src/lib/kadm5/ChangeLog index 8706ec0..cb83f11 100644 --- a/src/lib/kadm5/ChangeLog +++ b/src/lib/kadm5/ChangeLog @@ -1,3 +1,27 @@ +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * alt_prof.c (kadm5_get_config_params): Include des3 in supported + enctypes by default. + +2000-05-19 Ken Raeburn <raeburn@mit.edu> + + * ovsec_glue.c (ovsec_kadm_chpass_principal_util): Use 1024 for + hard-coded length, to match existing callers. + +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * admin.h: Add a length parameter to kadm5_chpass_principal_util(). + * admin_internal.h: Add a length parameter to + _kadm5_chpass_principal_util(). + * chpass_util.c (_kadm5_chpass_principal_util): Add a length parameter, + and use it to avoid overflowing "msg_ret". + * ovsec_glue.c (ovsec_kadm_chpass_principal_util): Adjust for new + parameter in kadm5_chpass_principal_util(). + +2000-05-01 Nalin Dahyabhai <nalin@redhat.com> + + * logger.c (klog_com_err_proc): Don't overflow buffer "outbuf". + 2000-02-26 Tom Yu <tlyu@mit.edu> * kadm_rpc_xdr.c (xdr_cprinc3_arg): Don't XDR the nonexistent diff --git a/src/lib/kadm5/admin.h b/src/lib/kadm5/admin.h index 159c7fb..2164e1e 100644 --- a/src/lib/kadm5/admin.h +++ b/src/lib/kadm5/admin.h @@ -411,7 +411,8 @@ kadm5_ret_t kadm5_chpass_principal_util(void *server_handle, krb5_principal princ, char *new_pw, char **ret_pw, - char *msg_ret); + char *msg_ret, + int msg_len); kadm5_ret_t kadm5_free_principal_ent(void *server_handle, kadm5_principal_ent_t diff --git a/src/lib/kadm5/admin_internal.h b/src/lib/kadm5/admin_internal.h index d2d1533..97cb5e5 100644 --- a/src/lib/kadm5/admin_internal.h +++ b/src/lib/kadm5/admin_internal.h @@ -62,7 +62,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, krb5_principal princ, char *new_pw, char **ret_pw, - char *msg_ret); + char *msg_ret, + int msg_len); /* this is needed by the alt_prof code I stole. The functions maybe shouldn't be named krb5_*, but they are. */ diff --git a/src/lib/kadm5/alt_prof.c b/src/lib/kadm5/alt_prof.c index 5582df0..4d1e769 100644 --- a/src/lib/kadm5/alt_prof.c +++ b/src/lib/kadm5/alt_prof.c @@ -644,8 +644,8 @@ krb5_error_code kadm5_get_config_params(context, kdcprofile, kdcenv, if (aprofile) krb5_aprof_get_string(aprofile, hierarchy, TRUE, &svalue); if (svalue == NULL) - svalue = strdup("des-cbc-crc:normal"); - + svalue = strdup("des3-hmac-sha1:normal des-cbc-crc:normal"); + params.keysalts = NULL; params.num_keysalts = 0; krb5_string_to_keysalts(svalue, diff --git a/src/lib/kadm5/chpass_util.c b/src/lib/kadm5/chpass_util.c index dbf610c..ec97a0e 100644 --- a/src/lib/kadm5/chpass_util.c +++ b/src/lib/kadm5/chpass_util.c @@ -61,7 +61,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, krb5_principal princ, char *new_pw, char **ret_pw, - char *msg_ret) + char *msg_ret, + int msg_len) { int code, code2, pwsize; static char buffer[255]; @@ -94,12 +95,18 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, memset(buffer, 0, sizeof(buffer)); #endif if (code == KRB5_LIBOS_BADPWDMATCH) { - strcpy(msg_ret, string_text(CHPASS_UTIL_NEW_PASSWORD_MISMATCH)); + strncpy(msg_ret, string_text(CHPASS_UTIL_NEW_PASSWORD_MISMATCH), + msg_len - 1); + msg_ret[msg_len - 1] = '\0'; return(code); } else { - sprintf(msg_ret, "%s %s\n%s\n", error_message(code), - string_text(CHPASS_UTIL_WHILE_READING_PASSWORD), - string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED)); + strncpy(msg_ret, error_message(code), msg_len - 1); + strncat(msg_ret, " ", msg_len - 1); + strncat(msg_ret, string_text(CHPASS_UTIL_WHILE_READING_PASSWORD), + msg_len - 1); + strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED), + msg_len - 1); + msg_ret[msg_len - 1] = '\0'; return(code); } } @@ -107,7 +114,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, #ifdef ZEROPASSWD memset(buffer, 0, sizeof(buffer)); #endif - strcpy(msg_ret, string_text(CHPASS_UTIL_NO_PASSWORD_READ)); + strncpy(msg_ret, string_text(CHPASS_UTIL_NO_PASSWORD_READ), msg_len - 1); + msg_ret[msg_len - 1] = '\0'; return(KRB5_LIBOS_CANTREADPWD); /* could do better */ } } @@ -123,7 +131,8 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, #endif if (code == KADM5_OK) { - strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_CHANGED)); + strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_CHANGED), msg_len - 1); + msg_ret[msg_len - 1] = '\0'; return(0); } @@ -141,12 +150,15 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, /* Ok, we have a password quality error. Return a good message */ if (code == KADM5_PASS_REUSE) { - strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_REUSE)); + strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_REUSE), msg_len - 1); + msg_ret[msg_len - 1] = '\0'; return(code); } if (code == KADM5_PASS_Q_DICT) { - strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_IN_DICTIONARY)); + strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_IN_DICTIONARY), + msg_len - 1); + msg_ret[msg_len - 1] = '\0'; return(code); } @@ -155,18 +167,32 @@ kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, code2 = kadm5_get_principal (lhandle, princ, &princ_ent, KADM5_PRINCIPAL_NORMAL_MASK); if (code2 != 0) { - sprintf(msg_ret, "%s %s\n%s %s\n\n%s\n ", error_message(code2), - string_text(CHPASS_UTIL_GET_PRINC_INFO), - error_message(code), - string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE), - string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED)); + strncpy(msg_ret, error_message(code2), msg_len - 1); + strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret)); + strncat(msg_ret, string_text(CHPASS_UTIL_GET_PRINC_INFO), msg_len - 1 - strlen(msg_ret)); + strncat(msg_ret, "\n", msg_len - 1 - strlen(msg_ret)); + strncat(msg_ret, error_message(code), msg_len - 1 - strlen(msg_ret)); + strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret)); + strncat(msg_ret, string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE), + msg_len - 1 - strlen(msg_ret)); + strncat(msg_ret, "\n\n", msg_len - 1 - strlen(msg_ret)); + strncat(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED), + msg_len - 1 - strlen(msg_ret)); + strncat(msg_ret, "\n", msg_len - 1 - strlen(msg_ret)); + msg_ret[msg_len - 1] = '\0'; return(code); } if ((princ_ent.aux_attributes & KADM5_POLICY) == 0) { - sprintf(msg_ret, "%s %s\n\n%s", error_message(code), - string_text(CHPASS_UTIL_NO_POLICY_YET_Q_ERROR), - string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED)); + strncpy(msg_ret, error_message(code), msg_len - 1 - strlen(msg_ret)); + strncat(msg_ret, " ", msg_len - 1 - strlen(msg_ret)); + strncpy(msg_ret, string_text(CHPASS_UTIL_NO_POLICY_YET_Q_ERROR), + msg_len - 1 - strlen(msg_ret)); + strncat(msg_ret, "\n\n", msg_len - 1 - strlen(msg_ret)); + strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED), + msg_len - 1 - strlen(msg_ret)); + msg_ret[msg_len - 1] = '\0'; + (void) kadm5_free_principal_ent(lhandle, &princ_ent); return(code); } diff --git a/src/lib/kadm5/clnt/ChangeLog b/src/lib/kadm5/clnt/ChangeLog index 79dc124..931bc99 100644 --- a/src/lib/kadm5/clnt/ChangeLog +++ b/src/lib/kadm5/clnt/ChangeLog @@ -1,3 +1,19 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * clnt_chpass_util.c (kadm5_chpass_principal_util): Adjust for new + length parameter in both kadm5_chpass_principal_util() and in + _kadm5_chpass_principal_util(). + +2000-05-09 Ken Raeburn <raeburn@mit.edu> + + * client_init.c (enctypes): Add des3 and des-md5 to the list of + permitted enctypes. + +2000-05-01 Nalin Dahyabhai <nalin@redhat.com> + + * client_init.c (_kadm5_init_any): Fix determination of client + name length for overflow checking. + 2000-02-26 Tom Yu <tlyu@mit.edu> * client_principal.c (kadm5_create_principal_3): Remove keepold diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c index a3d2613..b3832bb 100644 --- a/src/lib/kadm5/clnt/client_init.c +++ b/src/lib/kadm5/clnt/client_init.c @@ -134,6 +134,8 @@ static int preauth_search_list[] = { }; static krb5_enctype enctypes[] = { + ENCTYPE_DES3_CBC_SHA1, + ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_CRC, 0, }; @@ -282,9 +284,15 @@ static kadm5_ret_t _kadm5_init_any(char *client_name, goto error; if (realm) { + if(strlen(service_name) + strlen(realm) + 1 >= sizeof(full_service_name)) { + goto error; + } sprintf(full_service_name, "%s@%s", service_name, realm); } else { /* krb5_princ_realm(creds.client) is not null terminated */ + if(strlen(service_name) + krb5_princ_realm(handle->context, creds.client)->length + 1 >= sizeof(full_service_name)) { + goto error; + } strcpy(full_service_name, service_name); strcat(full_service_name, "@"); strncat(full_service_name, krb5_princ_realm(handle->context, diff --git a/src/lib/kadm5/clnt/clnt_chpass_util.c b/src/lib/kadm5/clnt/clnt_chpass_util.c index d6c7f0b..ae9ced0 100644 --- a/src/lib/kadm5/clnt/clnt_chpass_util.c +++ b/src/lib/kadm5/clnt/clnt_chpass_util.c @@ -5,11 +5,12 @@ kadm5_ret_t kadm5_chpass_principal_util(void *server_handle, krb5_principal princ, char *new_pw, char **ret_pw, - char *msg_ret) + char *msg_ret, + int msg_len) { kadm5_server_handle_t handle = server_handle; CHECK_HANDLE(server_handle); return _kadm5_chpass_principal_util(handle, handle->lhandle, princ, - new_pw, ret_pw, msg_ret); + new_pw, ret_pw, msg_ret, msg_len); } diff --git a/src/lib/kadm5/logger.c b/src/lib/kadm5/logger.c index 4f2ad20..bf6bbfd 100644 --- a/src/lib/kadm5/logger.c +++ b/src/lib/kadm5/logger.c @@ -199,8 +199,9 @@ klog_com_err_proc(whoami, code, format, ap) /* If reporting an error message, separate it. */ if (code) { - strcat(outbuf, error_message(code)); - strcat(outbuf, " - "); + outbuf[sizeof(outbuf) - 1] = '\0'; + strncat(outbuf, error_message(code), sizeof(outbuf) - 1 - strlen(outbuf)); + strncat(outbuf, " - ", sizeof(outbuf) - 1 - strlen(outbuf)); } cp = &outbuf[strlen(outbuf)]; diff --git a/src/lib/kadm5/ovsec_glue.c b/src/lib/kadm5/ovsec_glue.c index 6118282..ce81893 100644 --- a/src/lib/kadm5/ovsec_glue.c +++ b/src/lib/kadm5/ovsec_glue.c @@ -102,8 +102,10 @@ ovsec_kadm_ret_t ovsec_kadm_chpass_principal_util(void *server_handle, char **ret_pw, char *msg_ret) { - return kadm5_chpass_principal_util(server_handle, princ, new_pw, - ret_pw, msg_ret); + /* Oh crap. Can't change the API without bumping the API version... */ + memset(msg_ret, '\0', 1024); + return kadm5_chpass_principal_util(server_handle, princ, new_pw, + ret_pw, msg_ret, 1024); } ovsec_kadm_ret_t ovsec_kadm_randkey_principal(void *server_handle, diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog index 792936d..44a0a2b 100644 --- a/src/lib/kadm5/srv/ChangeLog +++ b/src/lib/kadm5/srv/ChangeLog @@ -1,3 +1,11 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * adb_openclose.c (osa_adb_create_db): Open lock files using O_EXCL + and fdopen() the descriptor instead of using fopen(). + * svr_chpass_util.c (kadm5_chpass_principal_util): Adjust for new + length parameter in both kadm5_chpass_principal_util() and in + _kadm5_chpass_principal_util(). + 2000-03-16 Ken Raeburn <raeburn@mit.edu> Matt Crawford <crawdad@fnal.gov> diff --git a/src/lib/kadm5/srv/adb_openclose.c b/src/lib/kadm5/srv/adb_openclose.c index e776192..2a9bba8 100644 --- a/src/lib/kadm5/srv/adb_openclose.c +++ b/src/lib/kadm5/srv/adb_openclose.c @@ -24,7 +24,7 @@ struct _locklist { osa_adb_ret_t osa_adb_create_db(char *filename, char *lockfilename, int magic) { - FILE *lf; + int lf; DB *db; HASHINFO info; @@ -41,10 +41,10 @@ osa_adb_ret_t osa_adb_create_db(char *filename, char *lockfilename, return errno; /* only create the lock file if we successfully created the db */ - lf = fopen(lockfilename, "w+"); - if (lf == NULL) + lf = THREEPARAMOPEN(lockfilename, O_RDWR | O_CREAT | O_EXCL, 0600); + if (lf == -1) return errno; - (void) fclose(lf); + (void) close(lf); return OSA_ADB_OK; } @@ -333,7 +333,7 @@ osa_adb_ret_t osa_adb_get_lock(osa_adb_db_t db, int mode) osa_adb_ret_t osa_adb_release_lock(osa_adb_db_t db) { - int ret; + int ret, fd; if (!db->lock->lockcnt) /* lock already unlocked */ return OSA_ADB_NOTLOCKED; @@ -341,8 +341,9 @@ osa_adb_ret_t osa_adb_release_lock(osa_adb_db_t db) if (--db->lock->lockcnt == 0) { if (db->lock->lockmode == OSA_ADB_PERMANENT) { /* now we need to create the file since it does not exist */ - if ((db->lock->lockfile = fopen(db->lock->filename, - "w+")) == NULL) + fd = THREEPARAMOPEN(db->lock->filename,O_RDWR | O_CREAT | O_EXCL, + 0600); + if ((db->lock->lockfile = fdopen(fd, "w+")) == NULL) return OSA_ADB_NOLOCKFILE; } else if (ret = krb5_lock_file(db->lock->context, fileno(db->lock->lockfile), diff --git a/src/lib/kadm5/srv/svr_chpass_util.c b/src/lib/kadm5/srv/svr_chpass_util.c index df2bf4c..4c4c6bb 100644 --- a/src/lib/kadm5/srv/svr_chpass_util.c +++ b/src/lib/kadm5/srv/svr_chpass_util.c @@ -5,11 +5,12 @@ kadm5_ret_t kadm5_chpass_principal_util(void *server_handle, krb5_principal princ, char *new_pw, char **ret_pw, - char *msg_ret) + char *msg_ret, + int msg_len) { kadm5_server_handle_t handle = server_handle; CHECK_HANDLE(server_handle); return _kadm5_chpass_principal_util(handle, handle->lhandle, princ, - new_pw, ret_pw, msg_ret); + new_pw, ret_pw, msg_ret, msg_len); } diff --git a/src/lib/kadm5/unit-test/ChangeLog b/src/lib/kadm5/unit-test/ChangeLog index b8e4b71..b59aeba 100644 --- a/src/lib/kadm5/unit-test/ChangeLog +++ b/src/lib/kadm5/unit-test/ChangeLog @@ -1,3 +1,10 @@ +2000-05-09 Ken Raeburn <raeburn@mit.edu> + + * api.2/chpass-principal-v2.exp (test200): Expect an additional + key to be reported, since des3 has been added to the list. + * api.2/get-principal-v2.exp (test101_102): Likewise. + * api.2/randkey-principal-v2.exp (test100): Likewise. + 2000-02-08 Tom Yu <tlyu@mit.edu> * api.1/lock.exp: Since a "wait" directive to the command list of diff --git a/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp b/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp index 40a78c9..ef45510 100644 --- a/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp +++ b/src/lib/kadm5/unit-test/api.2/chpass-principal-v2.exp @@ -53,10 +53,10 @@ proc test200 {} { } # XXX Perhaps I should actually check the key type returned. - if {$num_keys == 2} { + if {$num_keys == 3} { pass "$test" } else { - fail "$test: $num_keys keys, should be 2" + fail "$test: $num_keys keys, should be 3" } if { ! [cmd {kadm5_destroy $server_handle}]} { error "$test: unexpected failure in destroy" diff --git a/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp b/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp index 0e3e1b5..d2eb85a 100644 --- a/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp +++ b/src/lib/kadm5/unit-test/api.2/get-principal-v2.exp @@ -143,8 +143,8 @@ proc test101_102 {rpc} { } set failed 0 - if {$num_keys != 2} { - fail "$test: num_keys $num_keys should be 2" + if {$num_keys != 3} { + fail "$test: num_keys $num_keys should be 3" set failed 1 } for {set i 0} {$i < $num_keys} {incr i} { diff --git a/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp b/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp index 5c8fdc5..d9cc971 100644 --- a/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp +++ b/src/lib/kadm5/unit-test/api.2/randkey-principal-v2.exp @@ -47,10 +47,10 @@ proc test100 {} { } # XXX Perhaps I should actually check the key type returned. - if {$num_keys == 1} { + if {$num_keys == 2} { pass "$test" } else { - fail "$test: $num_keys keys, should be 1" + fail "$test: $num_keys keys, should be 2" } if { ! [cmd {kadm5_destroy $server_handle}]} { error "$test: unexpected failure in destroy" diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog index a710eb7..0c22f79 100644 --- a/src/lib/kdb/ChangeLog +++ b/src/lib/kdb/ChangeLog @@ -1,3 +1,26 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * t_kdb.c (gen_principal): Don't overflow "pnamebuf" if bad data was + passed in. + +2000-05-03 Nalin Dahyabhai <nalin@redhat.com> + + * setup_mkey.c (krb5_db_setup_mkey_name): Use REALM_SEP_STRING + when computing size of buffer that is to include it. + + * fetch_mkey.c (krb5_db_fetch_mkey): Make sure "defkeyfile" is + null terminated after construction. + * store_mkey.c (krb5_db_store_mkey): Likewise. + +2000-04-27 Ken Raeburn <raeburn@mit.edu> + Ezra Peisach <epeisach@mit.edu> + + * t_kdb.c (gen_principal): Force argument to isalnum to be in + range 0..255. + (do_testing): Cast pid_t to long before passing to fprintf, and + use %ld format. Fix argument lists to find_principal and + delete_principal. + 2000-03-16 Ezra Peisach <epeisach@mit.edu> * kdb_xdr.c (krb5_dbe_lookup_mod_princ_data): Get rid of diff --git a/src/lib/kdb/fetch_mkey.c b/src/lib/kdb/fetch_mkey.c index 2ff5c29..7ae26bb 100644 --- a/src/lib/kdb/fetch_mkey.c +++ b/src/lib/kdb/fetch_mkey.c @@ -133,7 +133,7 @@ krb5_db_fetch_mkey(context, mname, etype, fromkeyboard, twice, keyfile, (void) strncat(defkeyfile, realm->data, min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, realm->length)); - (void) strcat(defkeyfile, ""); + defkeyfile[sizeof(defkeyfile) - 1] = '\0'; #ifdef ANSI_STDIO if (!(kf = fopen((keyfile) ? keyfile : defkeyfile, "rb"))) diff --git a/src/lib/kdb/setup_mkey.c b/src/lib/kdb/setup_mkey.c index 0898a63..1788ecd 100644 --- a/src/lib/kdb/setup_mkey.c +++ b/src/lib/kdb/setup_mkey.c @@ -56,7 +56,7 @@ krb5_db_setup_mkey_name(context, keyname, realm, fullname, principal) keylen = strlen(keyname); - fname = malloc(keylen+rlen+2); + fname = malloc(keylen+rlen+strlen(REALM_SEP_STRING)+1); if (!fname) return ENOMEM; diff --git a/src/lib/kdb/store_mkey.c b/src/lib/kdb/store_mkey.c index d18630a..47e0bc9 100644 --- a/src/lib/kdb/store_mkey.c +++ b/src/lib/kdb/store_mkey.c @@ -68,7 +68,7 @@ krb5_db_store_mkey(context, keyfile, mname, key) (void) strncat(defkeyfile, realm->data, min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, realm->length)); - (void) strcat(defkeyfile, ""); + defkeyfile[sizeof(defkeyfile) - 1] = '\0'; keyfile = defkeyfile; } diff --git a/src/lib/kdb/t_kdb.c b/src/lib/kdb/t_kdb.c index 8358088..10e6163 100644 --- a/src/lib/kdb/t_kdb.c +++ b/src/lib/kdb/t_kdb.c @@ -363,15 +363,23 @@ gen_principal(kcontext, realm, do_rand, n, princp, namep) complen = RANDOM(1,MAX_COMP_SIZE); for (j=0; j<complen; j++) { *cp = (char) RANDOM(0,256); - while (!isalnum(*cp)) + while (!isalnum(*cp & 0xff)) *cp = (char) RANDOM(0,256); cp++; + if(cp + strlen(realm) >= pnamebuf + sizeof(pnamebuf)) + break; } + if(cp + strlen(realm) >= pnamebuf + sizeof(pnamebuf)) + break; *cp = '/'; cp++; } - cp[-1] = '@'; - strcpy(cp, realm); + if(cp + strlen(realm) < pnamebuf + sizeof(pnamebuf)) { + cp[-1] = '@'; + strcpy(cp, realm); + } else { + strcpy(cp , ""); + } } else { instname = instnames[n % (sizeof(instnames)/sizeof(instnames[0]))]; @@ -894,45 +902,40 @@ do_testing(db, passes, verbose, timing, rcases, check, save_db, dontclean, &stat_kb, rseed))) { fprintf(stderr, - "%d: (%d,%d) Failed add of %s with %s\n", - getpid(), i, j, playback_name(base+j), + "%ld: (%d,%d) Failed add of %s with %s\n", + (long) getpid(), i, j, playback_name(base+j), error_message(kret)); break; } if (verbose > 4) - fprintf(stderr, "*A[%d](%s)\n", getpid(), + fprintf(stderr, "*A[%ld](%s)\n", (long) getpid(), playback_name(base+j)); } for (j=0; (j<nper) && (!kret); j++) { if ((kret = find_principal(ccontext, playback_principal(base+j), - &master_encblock, - &stat_kb, - rseed))) { + check))) { fprintf(stderr, - "%d: (%d,%d) Failed lookup of %s with %s\n", - getpid(), i, j, playback_name(base+j), + "%ld: (%d,%d) Failed lookup of %s with %s\n", + (long) getpid(), i, j, playback_name(base+j), error_message(kret)); break; } if (verbose > 4) - fprintf(stderr, "-S[%d](%s)\n", getpid(), + fprintf(stderr, "-S[%ld](%s)\n", (long) getpid(), playback_name(base+j)); } for (j=0; (j<nper) && (!kret); j++) { if ((kret = delete_principal(ccontext, - playback_principal(base+j), - &master_encblock, - &stat_kb, - rseed))) { + playback_principal(base+j)))) { fprintf(stderr, - "%d: (%d,%d) Failed delete of %s with %s\n", - getpid(), i, j, playback_name(base+j), + "%ld: (%d,%d) Failed delete of %s with %s\n", + (long) getpid(), i, j, playback_name(base+j), error_message(kret)); break; } if (verbose > 4) - fprintf(stderr, "XD[%d](%s)\n", getpid(), + fprintf(stderr, "XD[%ld](%s)\n", (long) getpid(), playback_name(base+j)); } krb5_db_fini(ccontext); @@ -949,13 +952,13 @@ do_testing(db, passes, verbose, timing, rcases, check, save_db, dontclean, for (i=0; i<nprocs; i++) { if (waitpid(children[i], &existat, 0) == children[i]) { if (verbose) - fprintf(stderr, "%d finished with %d\n", children[i], - existat); + fprintf(stderr, "%ld finished with %d\n", + (long) children[i], existat); if (existat) kret = KRB5KRB_ERR_GENERIC; } else - fprintf(stderr, "Wait for %d failed\n", children[i]); + fprintf(stderr, "Wait for %ld failed\n", (long) children[i]); } } diff --git a/src/lib/krb4/ChangeLog b/src/lib/krb4/ChangeLog index 187505b..a2eaf10 100644 --- a/src/lib/krb4/ChangeLog +++ b/src/lib/krb4/ChangeLog @@ -1,3 +1,91 @@ +2000-06-09 Tom Yu <tlyu@mit.edu> + + * configure.in: Check for strdup(). + + * kparse.c: Remove strsave() and replace with an inlined static + version of strdup() if HAVE_STRDUP is not defined. + + * g_ad_tkt.c (get_ad_tkt): ptr may be signed; cast while + assigning to larger types. [from Charles Hannum by way of + ghudson] + +2000-05-23 Ken Raeburn <raeburn@mit.edu> + + * decomp_tkt.c (dcmp_tkt_int): Add a couple more length checks. + Reject names that are exactly ANAME_SZ (etc) bytes long without + the trailing nul, because krb.h says the *_SZ macros are "maximum + sizes ... +1". + * mk_auth.c (krb_mk_auth): Force nul termination of inst. + * sendauth.c (krb_sendauth): Force nul termination of srv_inst. + +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * Password.c (GetUserInfo): Truncate user name if it's too long + to fit. + * cr_auth_repl.c (cr_auth_reply): Bail if the reply packet won't + fit into its buffer. + * cr_ciph.c (create_ciph): Ditto. + * cr_death_pkt.c (krb_create_death_packet): Truncate "aname" to + make it fit into the packet's data buffer. + * cr_err_repl.c (cr_err_reply): Bail if the reply packet won't + fit into its buffer. + * cr_tkt.c (krb_create_ticket): Ditto. + * g_ad_tkt.c (get_ad_tkt): Stop if data being added to buffer + would overflow it. Add more sanity checks when decomposing the + credential received. + * g_in_tkt.c (krb_mk_in_tkt_preauth): Bail if the request packet + won't fit into its buffer. + * g_krbhst.c (get_krbhst_default): Truncate the guessed KDC's + hostname if it is too long. + * g_pw_in_tkt.c: Remove useless strcpy() prototype. + * kntoln.c (krb_kntoln): Don't overflow buffer "lname". + * mk_err.c (krb_mk_err): Return the needed buffer length if the + pointer passed in is NULL. + * mk_req.c (krb_mk_req): Bail if the reply packet won't + fit into its buffer. + * rd_req.c (krb_rd_req): Sanity check the realm name being read, + and truncate the service name, nstance, and realm from credential + read from keytab. + * realmofhost.c (krb_realmofhost): Truncate realm names read + from file if they are too long. + * send_to_kdc.c (send_to_kdc): Truncate passed-in realm name. + +2000-05-08 Ken Raeburn <raeburn@mit.edu> + + * rd_req.c (krb_rd_req): Mask length byte with 0xff in case the + length is over 127 and char is signed. + + * recvauth.c (krb_recvauth): If the number of bytes to be read + from the net is not positive, just return an error. + +2000-05-03 Tom Yu <tlyu@mit.edu> + + * cr_tkt.c: Delete prototype for krb_cr_tkt_int(), since the + definition is K&R style and contains narrow types. Thank you + HP/UX for having a compiler that actually makes this a fatal + error. + +2000-04-28 Ken Raeburn <raeburn@mit.edu> + Nalin Dahyabhai <nalin@redhat.com> + + * dest_tkt.c (dest_tkt): Don't overflow buffer "shmidname". + * in_tkt.c (in_tkt): Don't overflow buffer "shmidname". + * kuserok.c (kuserok): Don't overflow buffer "pbuf". + * tf_util.c (tf_init): Don't overflow buffer "shmidname". + * win_store.c (krb__get_cnffile): Don't overflow buffers "defname" + and "cnfname". + (krb__get_realmsfile): Don't overflow buffers "defname" and + "realmsname". + +2000-04-28 Tom Yu <tlyu@mit.edu> + + * rd_req.c (krb_rd_req): Fix some uses of strcpy(). + +2000-03-12 Ezra Peisach <epeisach@mit.edu> + + * cr_tkt.c (krb_cr_tkt_int): Add static prototype. + * decomp_tkt.c: (dcmp_tkt_int): Add static prototype + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/lib/krb4/Password.c b/src/lib/krb4/Password.c index b296630..5862e0e 100644 --- a/src/lib/krb4/Password.c +++ b/src/lib/krb4/Password.c @@ -177,7 +177,8 @@ OSErr GetUserInfo( char *password ) // already got a password, just get the initial ticket ////////////////////////////////////////////////////// if (*gPassword) { - strcpy (UserName, krb_get_default_user( )); + strncpy (UserName, krb_get_default_user( ), sizeof(UserName)-1); + UserName[sizeof(UserName) - 1] = '\0'; /* FIXME jcm - if we have a password then no dialog comes up for setting the uinstance. */ rc = kname_parse(uname, uinst, realm, UserName); @@ -201,7 +202,8 @@ OSErr GetUserInfo( char *password ) } // Insert user's name in dialog - strcpy (UserName, krb_get_default_user( )); + strncpy (UserName, krb_get_default_user( ), sizeof(UserName) - 1); + UserName[sizeof(UserName) - 1] = '\0'; if (*UserName) { tempStr[0] = strlen(UserName); memcpy( &(tempStr[1]), UserName, tempStr[0]); @@ -417,7 +419,8 @@ CacheInitialTicket( serviceName ) if (!serviceName || (serviceName[0] == '\0')) return err; - strcpy (UserName, krb_get_default_user()); + strncpy (UserName, krb_get_default_user(), sizeof(UserName) - 1); + UserName[sizeof(UserName) - 1] = '\0'; err = kname_parse(uname, uinst, urealm, UserName); if (err) return err; diff --git a/src/lib/krb4/configure.in b/src/lib/krb4/configure.in index 0434c7d..59937e1 100644 --- a/src/lib/krb4/configure.in +++ b/src/lib/krb4/configure.in @@ -38,7 +38,7 @@ else AC_DEFINE(BITS32) fi AC_DEFINE(KRB4_USE_KEYTAB) -AC_HAVE_FUNCS(strsave seteuid setreuid setresuid) +AC_HAVE_FUNCS(strdup seteuid setreuid setresuid) AC_PROG_AWK KRB5_BUILD_LIBOBJS KRB5_BUILD_LIBRARY_WITH_DEPS diff --git a/src/lib/krb4/cr_auth_repl.c b/src/lib/krb4/cr_auth_repl.c index 5203506..a0562d9 100644 --- a/src/lib/krb4/cr_auth_repl.c +++ b/src/lib/krb4/cr_auth_repl.c @@ -83,6 +83,16 @@ create_auth_reply(pname,pinst,prealm,time_ws,n,x_date,kvno,cipher) if (n != 0) *v = 3; + /* Make sure the response will actually fit into its buffer. */ + if(sizeof(pkt->dat) < 3 + strlen(pname) + + 1 + strlen(pinst) + + 1 + strlen(prealm) + + 4 + 1 + 4 + + 1 + 2 + cipher->length) { + pkt->length = 0; + return NULL; + } + /* Add the basic info */ (void) strcpy((char *) (pkt->dat+2), pname); pkt->length = 3 + strlen(pname); diff --git a/src/lib/krb4/cr_ciph.c b/src/lib/krb4/cr_ciph.c index d15a4e0..d9c7512 100644 --- a/src/lib/krb4/cr_ciph.c +++ b/src/lib/krb4/cr_ciph.c @@ -71,6 +71,17 @@ create_ciph(c, session, service, instance, realm, life, kvno, tkt, ptr = (char *) c->dat; + if(sizeof(c->dat) / 8 < (8 + + strlen(service) + 1 + + strlen(instance) + 1 + + strlen(realm) + 1 + + 1 + 1 + 1 + + tkt->length + 4 + + 7) / 8) { + c->length = 0; + return(KFAILURE); + } + memcpy(ptr, (char *) session, 8); ptr += 8; diff --git a/src/lib/krb4/cr_death_pkt.c b/src/lib/krb4/cr_death_pkt.c index 8daa2d6..c356267 100644 --- a/src/lib/krb4/cr_death_pkt.c +++ b/src/lib/krb4/cr_death_pkt.c @@ -52,8 +52,9 @@ krb_create_death_packet(a_name) *v = (unsigned char) KRB_PROT_VERSION; *t = (unsigned char) AUTH_MSG_DIE; *t |= HOST_BYTE_ORDER; - (void) strcpy((char *) (pkt->dat+2),a_name); - pkt->length = 3 + strlen(a_name); + (void) strncpy((char *) (pkt->dat+2),a_name,sizeof(pkt->dat) - 3); + pkt->dat[sizeof(pkt->dat) - 1] = '\0'; + pkt->length = 3 + strlen(pkt->dat+2); return pkt; } #endif /* DEBUG */ diff --git a/src/lib/krb4/cr_err_repl.c b/src/lib/krb4/cr_err_repl.c index 7f68bda..54e87d8 100644 --- a/src/lib/krb4/cr_err_repl.c +++ b/src/lib/krb4/cr_err_repl.c @@ -78,6 +78,15 @@ cr_err_reply(pkt,pname,pinst,prealm,time_ws,e,e_string) *t = (unsigned char) AUTH_MSG_ERR_REPLY; *t |= HOST_BYTE_ORDER; + /* Make sure the reply will fit into the buffer. */ + if(sizeof(pkt->dat) < 3 + strlen(pname) + + 1 + strlen(pinst) + + 1 + strlen(prealm) + + 4 + 4 + + 1 + strlen(e_string)) { + pkt->length = 0; + return; + } /* Add the basic info */ (void) strcpy((char *) (pkt->dat+2),pname); pkt->length = 3 + strlen(pname); diff --git a/src/lib/krb4/cr_tkt.c b/src/lib/krb4/cr_tkt.c index a8224f8..34bec48 100644 --- a/src/lib/krb4/cr_tkt.c +++ b/src/lib/krb4/cr_tkt.c @@ -14,6 +14,7 @@ #include "prot.h" #include <string.h> #include <krb5.h> + /* * Create ticket takes as arguments information that should be in a * ticket, and the KTEXT object in which the ticket should be @@ -134,6 +135,23 @@ krb_cr_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, register char *data; /* running index into ticket */ tkt->length = 0; /* Clear previous data */ + + /* Check length of ticket */ + if (sizeof(tkt->dat) < (sizeof(flags) + + 1 + strlen(pname) + + 1 + strlen(pinstance) + + 1 + strlen(prealm) + + 4 + /* address */ + 8 + /* session */ + 1 + /* life */ + 4 + /* issue time */ + 1 + strlen(sname) + + 1 + strlen(sinstance) + + 7) / 8) { /* roundoff */ + memset(tkt->dat, 0, sizeof(tkt->dat)); + return KFAILURE /* XXX */; + } + flags |= HOST_BYTE_ORDER; /* ticket byte order */ memcpy((char *) (tkt->dat), (char *) &flags, sizeof(flags)); data = ((char *)tkt->dat) + sizeof(flags); diff --git a/src/lib/krb4/decomp_tkt.c b/src/lib/krb4/decomp_tkt.c index 03398ac..06e9e31 100644 --- a/src/lib/krb4/decomp_tkt.c +++ b/src/lib/krb4/decomp_tkt.c @@ -19,6 +19,12 @@ extern int krb_debug; #endif +static int dcmp_tkt_int PROTOTYPE((KTEXT tkt, unsigned char *flags, + char *pname, char *pinstance, char *prealm, + unsigned KRB4_32 *paddress, C_Block session, + int *life, unsigned KRB4_32 *time_sec, + char *sname, char *sinstance, C_Block key, + Key_schedule key_s, krb5_keyblock *k5key)); /* * This routine takes a ticket and pointers to the variables that * should be filled in based on the information in the ticket. It @@ -186,17 +192,17 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session, if (HOST_BYTE_ORDER != ((*flags >> K_FLAG_ORDER)& 1)) tkt_swap_bytes++; - if (strlen(ptr) > ANAME_SZ) + if (strlen(ptr) >= ANAME_SZ) return(KFAILURE); (void) strcpy(pname,ptr); /* pname */ ptr += strlen(pname) + 1; - if (strlen(ptr) > INST_SZ) + if (strlen(ptr) >= INST_SZ) return(KFAILURE); (void) strcpy(pinstance,ptr); /* instance */ ptr += strlen(pinstance) + 1; - if (strlen(ptr) > REALM_SZ) + if (strlen(ptr) >= REALM_SZ) return(KFAILURE); (void) strcpy(prealm,ptr); /* realm */ ptr += strlen(prealm) + 1; @@ -223,9 +229,13 @@ dcmp_tkt_int(tkt, flags, pname, pinstance, prealm, paddress, session, if (tkt_swap_bytes) *time_sec = krb4_swab32(*time_sec); + if (strlen(ptr) >= ANAME_SZ) + return KFAILURE; (void) strcpy(sname,ptr); /* service name */ ptr += 1 + strlen(sname); + if (strlen (ptr) >= INST_SZ) + return KFAILURE; (void) strcpy(sinstance,ptr); /* instance */ ptr += 1 + strlen(sinstance); diff --git a/src/lib/krb4/dest_tkt.c b/src/lib/krb4/dest_tkt.c index 7057818..50c1352 100644 --- a/src/lib/krb4/dest_tkt.c +++ b/src/lib/krb4/dest_tkt.c @@ -87,8 +87,9 @@ out: /* * handle the shared memory case */ - (void) strcpy(shmidname, file); - (void) strcat(shmidname, ".shm"); + (void) strncpy(shmidname, file, sizeof(shmidname) - 1); + shmidname[sizeof(shmidname) - 1] = '\0'; + (void) strcat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname)); if ((i = krb_shm_dest(shmidname)) != KSUCCESS) return(i); #endif /* TKT_SHMEM */ diff --git a/src/lib/krb4/g_ad_tkt.c b/src/lib/krb4/g_ad_tkt.c index b3abb2d..afcd0c6 100644 --- a/src/lib/krb4/g_ad_tkt.c +++ b/src/lib/krb4/g_ad_tkt.c @@ -19,6 +19,19 @@ extern int krb_debug; extern int swap_bytes; +/* Return the length of the string if a NUL is found within the first + * max_len bytes, otherwise, -1. */ +static int krb_strnlen(const char *str, int max_len) +{ + int i; + for(i = 0; i < max_len; i++) { + if(str[i] == '\0') { + return i; + } + } + return -1; +} + /* * get_ad_tkt obtains a new service ticket from Kerberos, using * the ticket-granting ticket which must be in the ticket file. @@ -136,11 +149,22 @@ get_ad_tkt(service,sinstance,realm,lifetime) return(AD_NOTGT); /* timestamp */ /* FIXME -- always 0 now, should we fill it in??? */ + if(pkt->length + 4 > sizeof(pkt->dat)) + return(INTK_ERR); memcpy((char *) (pkt->dat+pkt->length), (char *) &time_ws, 4); pkt->length += 4; + + if(pkt->length + 1 > sizeof(pkt->dat)) + return(INTK_ERR); *(pkt->dat+(pkt->length)++) = (char) lifetime; + + if(pkt->length + 1 + strlen(service) > sizeof(pkt->dat)) + return(INTK_ERR); (void) strcpy((char *) (pkt->dat+pkt->length),service); pkt->length += 1 + strlen(service); + + if(pkt->length + 1 + strlen(sinstance) > sizeof(pkt->dat)) + return(INTK_ERR); (void) strcpy((char *)(pkt->dat+pkt->length),sinstance); pkt->length += 1 + strlen(sinstance); @@ -199,18 +223,27 @@ get_ad_tkt(service,sinstance,realm,lifetime) memcpy((char *)ses, ptr, 8); ptr += 8; - (void) strcpy(s_name,ptr); + if(krb_strnlen(ptr, sizeof(s_name)) < 0) + return RD_AP_MODIFIED; + (void) strncpy(s_name,ptr,sizeof(s_name) - 1); + s_name[sizeof(s_name) - 1] = '\0'; ptr += strlen(s_name) + 1; - (void) strcpy(s_instance,ptr); + if(krb_strnlen(ptr, sizeof(s_instance)) < 0) + return RD_AP_MODIFIED; + (void) strncpy(s_instance,ptr,sizeof(s_instance)-1); + s_instance[sizeof(s_instance)-1] = '\0'; ptr += strlen(s_instance) + 1; - (void) strcpy(rlm,ptr); + if(krb_strnlen(ptr, sizeof(rlm)) < 0) + return RD_AP_MODIFIED; + (void) strncpy(rlm,ptr,sizeof(rlm) - 1); + rlm[sizeof(rlm)-1]; ptr += strlen(rlm) + 1; - lifetime = (unsigned long) ptr[0]; - kvno = (unsigned long) ptr[1]; - tkt->length = (int) ptr[2]; + lifetime = (unsigned char) ptr[0]; + kvno = (unsigned char) ptr[1]; + tkt->length = (unsigned char) ptr[2]; ptr += 3; memcpy((char *)(tkt->dat), ptr, tkt->length); ptr += tkt->length; diff --git a/src/lib/krb4/g_in_tkt.c b/src/lib/krb4/g_in_tkt.c index c9d6183..361273c 100644 --- a/src/lib/krb4/g_in_tkt.c +++ b/src/lib/krb4/g_in_tkt.c @@ -152,6 +152,20 @@ krb_mk_in_tkt_preauth(user, instance, realm, service, sinstance, life, *t = (unsigned char) AUTH_MSG_KDC_REQUEST; *t |= HOST_BYTE_ORDER; + /* Make sure the ticket data will fit into the buffer. */ + if(sizeof(pkt->dat) < 2 + /* protocol version + flags */ + 3 + strlen(user) + + 1 + strlen(instance) + + 1 + strlen(realm) + + 4 + /* timestamp */ + 1 + /* lifetime */ + 1 + strlen(service) + + 1 + strlen(sinstance) + + preauth_len) { + pkt->length = 0; + return INTK_ERR; + } + /* Now for the variable info */ (void) strcpy((char *)(pkt->dat+2),user); /* aname */ pkt->length = 3 + strlen(user); diff --git a/src/lib/krb4/g_krbhst.c b/src/lib/krb4/g_krbhst.c index 529ac07..4e0fd6d 100644 --- a/src/lib/krb4/g_krbhst.c +++ b/src/lib/krb4/g_krbhst.c @@ -52,9 +52,11 @@ get_krbhst_default(h, r, n) int n; { if (n==1) { - (void) strcpy(h,KRB_HOST); - (void) strcat(h,"."); - (void) strcat(h,r); /* KRB_HOST.REALM (ie. kerberos.CYGNUS.COM) */ + (void) strncpy(h,KRB_HOST,MAXHOSTNAMELEN-1); + h[MAXHOSTNAMELEN-1] = '\0'; + (void) strncat(h,".",MAXHOSTNAMELEN-1-strlen(h)); + (void) strncat(h,r,MAXHOSTNAMELEN-1-strlen(h)); + /* KRB_HOST.REALM (ie. kerberos.CYGNUS.COM) */ return(KSUCCESS); } else diff --git a/src/lib/krb4/g_krbrlm.c b/src/lib/krb4/g_krbrlm.c index 983150c..c750231 100644 --- a/src/lib/krb4/g_krbrlm.c +++ b/src/lib/krb4/g_krbrlm.c @@ -44,7 +44,8 @@ krb_get_lrealm(r,n) cnffile = krb__get_cnffile(); if (!cnffile) { if (n == 1) { - (void) strcpy(r, KRB_REALM); + (void) strncpy(r, KRB_REALM, REALM_SZ); + r[REALM_SZ - 1] = '\0'; return(KSUCCESS); } else diff --git a/src/lib/krb4/g_pw_in_tkt.c b/src/lib/krb4/g_pw_in_tkt.c index 6723df8..13f762b 100644 --- a/src/lib/krb4/g_pw_in_tkt.c +++ b/src/lib/krb4/g_pw_in_tkt.c @@ -176,7 +176,6 @@ krb_get_pw_in_tkt_preauth(user,instance,realm,service,sinstance,life,password) #include <signal.h> #include <setjmp.h> #else -char *strcpy(); int strcmp(); #endif #if defined(__svr4__) || defined(__SVR4) diff --git a/src/lib/krb4/in_tkt.c b/src/lib/krb4/in_tkt.c index ea17be8..4e220f9 100644 --- a/src/lib/krb4/in_tkt.c +++ b/src/lib/krb4/in_tkt.c @@ -159,8 +159,9 @@ in_tkt(pname,pinst) } (void) close(tktfile); #ifdef TKT_SHMEM - (void) strcpy(shmidname, file); - (void) strcat(shmidname, ".shm"); + (void) strncpy(shmidname, file, sizeof(shmidname) - 1); + shmidname[sizeof(shmidname) - 1] = '\0'; + (void) strncat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname)); return(krb_shm_create(shmidname)); #else /* !TKT_SHMEM */ return(KSUCCESS); diff --git a/src/lib/krb4/kntoln.c b/src/lib/krb4/kntoln.c index 8b6cdfe..f86599c 100644 --- a/src/lib/krb4/kntoln.c +++ b/src/lib/krb4/kntoln.c @@ -38,6 +38,10 @@ * KSUCCESS if all goes well, otherwise KFAILURE. */ +/* The definition of MAX_USERNAME here MUST agree with kuserok.c, or bad + * things will happen. */ +#define MAX_USERNAME 10 + krb_kntoln(ad,lname) AUTH_DAT *ad; char *lname; @@ -51,6 +55,7 @@ krb_kntoln(ad,lname) return(KFAILURE); if (strcmp(ad->prealm,lrealm)) return(KFAILURE); - (void) strcpy(lname,ad->pname); + (void) strncpy(lname,ad->pname,MAX_USERNAME-1); + lname[MAX_USERNAME - 1] = '\0'; return(KSUCCESS); } diff --git a/src/lib/krb4/kparse.c b/src/lib/krb4/kparse.c index 98e48fb..e72295c 100644 --- a/src/lib/krb4/kparse.c +++ b/src/lib/krb4/kparse.c @@ -54,8 +54,8 @@ static char *strutol(); -#ifndef HAVE_STRSAVE -static char *strsave(); +#ifndef HAVE_STRDUP +static char *strdup(); #endif #ifndef HAVE_STDLIB_H extern char *malloc(); @@ -104,7 +104,7 @@ int fGetParameterSet( fp,parm,parmcount ) keyword); return(PS_BAD_KEYWORD); } - parm[i].value = strsave( value ); + parm[i].value = strdup(value); break; } } @@ -552,34 +552,6 @@ int fGetChar(fp) return(ch); } - -/* - * Routine Name: strsave - * - * Function: return a pointer to a saved copy of the - * input string. the copy will be allocated - * as large as necessary. - * - * Explicit Parameters: pointer to string to save - * - * Implicit Parameters: None - * - * External Procedures: malloc,strcpy,strlen - * - * Side Effects: None - * - * Return Value: pointer to copied string - * - */ -#ifndef HAVE_STRSAVE -static char * strsave(p) - char *p; -{ - return(strcpy(malloc(strlen(p)+1),p)); -} -#endif - - /* * strutol changes all characters in a string to lower case, in place. * the pointer to the beginning of the string is returned. @@ -770,3 +742,42 @@ main(argc,argv) exit(0); } #endif + +/* + * Copyright (c) 1988 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that: (1) source distributions retain this entire copyright + * notice and comment, and (2) distributions including binaries display + * the following acknowledgement: ``This product includes software + * developed by the University of California, Berkeley and its contributors'' + * in the documentation or other materials provided with the distribution + * and in all advertising materials mentioning features or use of this + * software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* based on @(#)strdup.c 5.3 (Berkeley) 6/1/90 */ + +#ifndef HAVE_STRDUP +static char * +strdup(str) + const char *str; +{ + int len; + char *copy; + + if (!str) + return((char *)0); + len = strlen(str) + 1; + if (!(copy = malloc((u_int)len))) + return((char *)0); + memcpy(copy, str, len); + return(copy); +} +#endif diff --git a/src/lib/krb4/kuserok.c b/src/lib/krb4/kuserok.c index 0aee893..20587cb 100644 --- a/src/lib/krb4/kuserok.c +++ b/src/lib/krb4/kuserok.c @@ -118,8 +118,11 @@ kuserok(kdata, luser) if ((pwd = getpwnam(luser)) == NULL) { return(NOTOK); } - (void) strcpy(pbuf, pwd->pw_dir); - (void) strcat(pbuf, "/.klogin"); + if (strlen (pwd->pw_dir) + sizeof ("/.klogin") >= sizeof (pbuf)) + return NOTOK; + (void) strncpy(pbuf, pwd->pw_dir, sizeof(pbuf) - 1); + pbuf[sizeof(pbuf) - 1] = '\0'; + (void) strncat(pbuf, "/.klogin", sizeof(pbuf) - 1 - strlen(pbuf)); if (access(pbuf, F_OK)) { /* not accessible */ /* diff --git a/src/lib/krb4/mk_auth.c b/src/lib/krb4/mk_auth.c index 39a2e2f..a94a25d 100644 --- a/src/lib/krb4/mk_auth.c +++ b/src/lib/krb4/mk_auth.c @@ -124,8 +124,10 @@ krb_mk_auth(options, ticket, service, inst, realm, checksum, version, buf) realm = krb_realm; } - if (!(options & KOPT_DONT_CANON)) - (void) strncpy(inst, krb_get_phost(inst), INST_SZ); + if (!(options & KOPT_DONT_CANON)) { + (void) strncpy(inst, krb_get_phost(inst), INST_SZ - 1); + inst[INST_SZ-1] = 0; + } /* get the ticket if desired */ if (!(options & KOPT_DONT_MK_REQ)) { diff --git a/src/lib/krb4/mk_err.c b/src/lib/krb4/mk_err.c index e30e299..029aa9f 100644 --- a/src/lib/krb4/mk_err.c +++ b/src/lib/krb4/mk_err.c @@ -41,6 +41,14 @@ krb_mk_err(p,e,e_string) { u_char *start; + /* Just return the buffer length if p is NULL, because writing to the + * buffer would be a bad idea. Note that this feature is a change from + * previous versions, and can therefore only be used safely in this + * source tree, where we know this function supports it. */ + if(p == NULL) { + return 2 + sizeof(e) + strlen(e_string); + } + start = p; /* Create fixed part of packet */ diff --git a/src/lib/krb4/mk_req.c b/src/lib/krb4/mk_req.c index 1936cb2..468dccd 100644 --- a/src/lib/krb4/mk_req.c +++ b/src/lib/krb4/mk_req.c @@ -130,6 +130,19 @@ krb_mk_req(authent,service,instance,realm,checksum) if (retval != KSUCCESS) return (retval); + if(sizeof(authent->dat) / 8 < (3 + + strlen(realm) + 1 + 2 + + 3 + ticket->length + + strlen(cr.pname) + 1 + + strlen(cr.pinst) + 1 + + strlen(myrealm) + 1 + + 4 + /* checksum */ + 4 + /* timestamp */ + 7) / 8) { /* round-up */ + authent->length = 0; + return KFAILURE; + } + if (krb_ap_req_debug) DEB (("%s %s %s %s %s\n", service, instance, realm, cr.pname, cr.pinst)); diff --git a/src/lib/krb4/rd_req.c b/src/lib/krb4/rd_req.c index c9b6ac7..09f914d 100644 --- a/src/lib/krb4/rd_req.c +++ b/src/lib/krb4/rd_req.c @@ -108,6 +108,19 @@ krb_clear_key_krb5(ctx) krb5_key = 0; } +/* A helper function to let us see if a buffer is properly terminated. */ +static int +krb_strnlen(const char *str, size_t max_len) +{ + int i = 0; + for(i = 0; i < max_len; i++) { + if(str[i] == '\0') { + return i; + } + } + return -1; +} + /* * krb_rd_req() takes an AUTH_MSG_APPL_REQUEST or * AUTH_MSG_APPL_REQUEST_MUTUAL message created by krb_mk_req(), @@ -184,6 +197,8 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn) krb5_keyblock keyblock; int status; + tkt->mbz = req_id->mbz = 0; + if (authent->length <= 0) return(RD_AP_MODIFIED); @@ -219,8 +234,13 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn) mutual = 0; #endif /* lint */ s_kvno = *ptr++; /* get server key version */ - (void) strcpy(realm,ptr); /* And the realm of the issuing KDC */ - ptr += strlen(ptr) + 1; /* skip the realm "hint" */ + if(krb_strnlen(ptr, sizeof(realm)) < 0) { + return RD_AP_MODIFIED; /* must have been modified, the client wouldn't + try to trick us with wacky data */ + } + (void) strncpy(realm,ptr,REALM_SZ); /* And the realm of the issuing KDC */ + realm[REALM_SZ-1] = '\0'; + ptr += strlen(realm) + 1; /* skip the realm "hint" */ /* * If "fn" is NULL, key info should already be set; don't @@ -249,13 +269,16 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn) return(RD_AP_UNDEC); #endif /* !NOENCRYPTION */ - (void) strcpy(st_rlm,realm); - (void) strcpy(st_nam,service); - (void) strcpy(st_inst,instance); + (void) strncpy(st_rlm,realm, sizeof(st_rlm) - 1); + st_rlm[sizeof(st_rlm) - 1] = '\0'; + (void) strncpy(st_nam,service, sizeof(st_nam) - 1); + st_nam[sizeof(st_nam) - 1] = '\0'; + (void) strncpy(st_inst,instance, sizeof(st_inst) - 1); + st_inst[sizeof(st_inst) - 1] = '\0'; } /* Get ticket from authenticator */ - tkt->length = (int) *ptr++; + tkt->length = (int) *ptr++ & 0xff; if ((tkt->length + (ptr+1 - (char *) authent->dat)) > authent->length) return(RD_AP_MODIFIED); memcpy((char *)(tkt->dat), ptr+1, tkt->length); @@ -324,13 +347,16 @@ krb_rd_req(authent,service,instance,from_addr,ad,fn) #define check_ptr() if ((ptr - (char *) req_id->dat) > req_id->length) return(RD_AP_MODIFIED); ptr = (char *) req_id->dat; - (void) strcpy(r_aname,ptr); /* Authentication name */ + (void) strncpy(r_aname,ptr,ANAME_SZ); /* Authentication name */ + r_aname[ANAME_SZ-1] = '\0'; ptr += strlen(r_aname)+1; check_ptr(); - (void) strcpy(r_inst,ptr); /* Authentication instance */ + (void) strncpy(r_inst,ptr,INST_SZ); /* Authentication instance */ + r_inst[INST_SZ-1] = '\0'; ptr += strlen(r_inst)+1; check_ptr(); - (void) strcpy(r_realm,ptr); /* Authentication name */ + (void) strncpy(r_realm,ptr,REALM_SZ); /* Authentication name */ + r_realm[REALM_SZ-1] = '\0'; ptr += strlen(r_realm)+1; check_ptr(); memcpy((char *)&ad->checksum, ptr, 4); /* Checksum */ diff --git a/src/lib/krb4/realmofhost.c b/src/lib/krb4/realmofhost.c index 90e01bb..1e4b786 100644 --- a/src/lib/krb4/realmofhost.c +++ b/src/lib/krb4/realmofhost.c @@ -131,14 +131,18 @@ krb_realmofhost(host) if (domain && (strlen(trans_host) == strlen(domain)) && !strcasecmp (trans_host, domain)) { /* got domain match, save for later */ - (void) strcpy (ret_realm, trans_realm); + (void) strncpy (ret_realm, trans_realm, + sizeof(ret_realm) - 1); + ret_realm[sizeof(ret_realm) - 1] = '\0'; continue; } } else { /* want exact match of hostname */ if ((strlen(lhost) == strlen(trans_host)) && !strcasecmp (trans_host, lhost)) { - (void) strcpy (ret_realm, trans_realm); + (void) strncpy (ret_realm, trans_realm, + sizeof(ret_realm) - 1); + ret_realm[sizeof(ret_realm) - 1] = '\0'; break; } } diff --git a/src/lib/krb4/recvauth.c b/src/lib/krb4/recvauth.c index e62e3f9..2a66656 100644 --- a/src/lib/krb4/recvauth.c +++ b/src/lib/krb4/recvauth.c @@ -188,9 +188,12 @@ krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata, if (i < KRB_SENDAUTH_VLEN) { /* since we already got the space, and part of the ticket, we read fewer bytes to get the rest of the ticket */ + int len_to_read = tkt_len - KRB_SENDAUTH_VLEN + 1 + i; + if (len_to_read <= 0) + return KFAILURE; if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN), - (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i)) - != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i)) + len_to_read) + != len_to_read) return(errno); } else { if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) != diff --git a/src/lib/krb4/send_to_kdc.c b/src/lib/krb4/send_to_kdc.c index c7e0fb3..f93b9d0 100644 --- a/src/lib/krb4/send_to_kdc.c +++ b/src/lib/krb4/send_to_kdc.c @@ -94,12 +94,13 @@ send_to_kdc(pkt,rpkt,realm) * local realm. */ if (realm) - (void) strcpy(lrealm, realm); + (void) strncpy(lrealm, realm, sizeof(lrealm) - 1); else if (krb_get_lrealm(lrealm,1)) { DEB (("%s: can't get local realm\n", prog)); return(SKDC_CANT); } + lrealm[sizeof(lrealm) - 1] = '\0'; DEB (("lrealm is %s\n", lrealm)); if (SOCKET_INITIALIZE()) { diff --git a/src/lib/krb4/sendauth.c b/src/lib/krb4/sendauth.c index 9b8fb39..76c470c 100644 --- a/src/lib/krb4/sendauth.c +++ b/src/lib/krb4/sendauth.c @@ -208,7 +208,8 @@ krb_sendauth(options, fd, ticket, service, inst, realm, checksum, } /* copy instance into local storage, so mk_auth can canonicalize */ - (void) strncpy(srv_inst, inst, INST_SZ); + (void) strncpy(srv_inst, inst, INST_SZ-1); + srv_inst[INST_SZ-1] = 0; rem = krb_mk_auth (options, ticket, service, srv_inst, realm, checksum, version, packet); if (rem != KSUCCESS) diff --git a/src/lib/krb4/tf_util.c b/src/lib/krb4/tf_util.c index ebf500b..0d69719 100644 --- a/src/lib/krb4/tf_util.c +++ b/src/lib/krb4/tf_util.c @@ -181,8 +181,9 @@ int tf_init(tf_name, rw) tf_name = tkt_string(); #ifdef TKT_SHMEM - (void) strcpy(shmidname, tf_name); - (void) strcat(shmidname, ".shm"); + (void) strncpy(shmidname, tf_name, sizeof(shmidname) - 1); + shmidname[sizeof(shmidname) - 1] = '\0'; + (void) strncat(shmidname, ".shm", sizeof(shmidname) - 1 - strlen(shmidname)); #endif /* TKT_SHMEM */ /* diff --git a/src/lib/krb4/win_store.c b/src/lib/krb4/win_store.c index 50507aa..28d11bd 100644 --- a/src/lib/krb4/win_store.c +++ b/src/lib/krb4/win_store.c @@ -62,15 +62,17 @@ krb__get_cnffile() char defname[FILENAME_MAX]; UINT rc; - rc = GetWindowsDirectory(defname, sizeof(defname)); + defname[sizeof(defname) - 1] = '\0'; + rc = GetWindowsDirectory(defname, sizeof(defname) - 1); assert(rc > 0); - strcat(defname, "\\"); + strncat(defname, "\\", sizeof(defname) - 1 - strlen(defname)); - strcat(defname, DEF_KRB_CONF); + strncat(defname, DEF_KRB_CONF, sizeof(defname) - 1 - strlen(defname)); + cnfname[sizeof(cnfname) - 1] = '\0'; GetPrivateProfileString(INI_FILES, INI_KRB_CONF, defname, - cnfname, sizeof(cnfname), KERBEROS_INI); + cnfname, sizeof(cnfname) - 1, KERBEROS_INI); cnffile = fopen(cnfname, "r"); @@ -94,15 +96,17 @@ krb__get_realmsfile() char defname[FILENAME_MAX]; UINT rc; - rc = GetWindowsDirectory(defname, sizeof(defname)); + defname[sizeof(defname) - 1] = '\0'; + rc = GetWindowsDirectory(defname, sizeof(defname) - 1); assert(rc > 0); - strcat(defname, "\\"); + strncat(defname, "\\", sizeof(defname) - 1 - strlen(defname)); - strcat(defname, DEF_KRB_REALMS); + strncat(defname, DEF_KRB_REALMS, sizeof(defname) - 1 - strlen(defname)); + defname[sizeof(defname) - 1] = '\0'; GetPrivateProfileString(INI_FILES, INI_KRB_REALMS, defname, - realmsname, sizeof(realmsname), KERBEROS_INI); + realmsname, sizeof(realmsname) - 1, KERBEROS_INI); realmsfile = fopen(realmsname, "r"); diff --git a/src/lib/krb5/ChangeLog b/src/lib/krb5/ChangeLog index a2ab81a..b8a5385 100644 --- a/src/lib/krb5/ChangeLog +++ b/src/lib/krb5/ChangeLog @@ -1,3 +1,11 @@ +2000-06-03 Tom Yu <tlyu@mit.edu> + + * Makefile.in (LIBMAJOR, LIBMINOR): Bump version. + +2000-04-18 Ken Raeburn <raeburn@mit.edu> + + * Makefile.in (SHLIB_EXPLIBS): Add @RESOLV_LIB@. + 2000-03-14 Ken Raeburn <raeburn@mit.edu> * configure.in: Check for gethostbyname2. diff --git a/src/lib/krb5/Makefile.in b/src/lib/krb5/Makefile.in index 0dab1f3..68e354c 100644 --- a/src/lib/krb5/Makefile.in +++ b/src/lib/krb5/Makefile.in @@ -32,8 +32,8 @@ LIBDONE= error_tables/DONE asn.1/DONE ccache/DONE ccache/stdio/DONE \ STLIBOBJS=krb5_libinit.o LIB=krb5 -LIBMAJOR=2 -LIBMINOR=2 +LIBMAJOR=3 +LIBMINOR=0 STOBJLISTS= \ OBJS.ST \ @@ -58,7 +58,7 @@ RELDIR=krb5 SHLIB_EXPDEPS = \ $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ $(TOPLIBD)/libcom_err$(SHLIBEXT) -SHLIB_EXPLIBS=-lk5crypto -lcom_err @GEN_LIB@ +SHLIB_EXPLIBS=-lk5crypto -lcom_err @GEN_LIB@ @RESOLV_LIB@ SHLIB_DIRS=-L$(TOPLIBD) SHLIB_RDIRS=$(KRB5_LIBDIR) diff --git a/src/lib/krb5/ccache/ChangeLog b/src/lib/krb5/ccache/ChangeLog index 2f74235..02aa294 100644 --- a/src/lib/krb5/ccache/ChangeLog +++ b/src/lib/krb5/ccache/ChangeLog @@ -1,3 +1,32 @@ +2000-5-31 Alexandra Ellwood <lxs@mit.edu> + + * ccdefault.c: Changed kerberosPrincipal_V5 to kerberosVersion_V5 to reflect + the new constant name. + +2000-5-19 Alexandra Ellwood <lxs@mit.edu> + + * ccdefault.c: Added krb5int_cc_default. This function + supports the Kerberos Login Library and pops up a dialog if the cache does + not contain valid tickets. This is used to automatically get a tgt before + obtaining service tickets. Note that this should be an internal function + because callers don't expect krb5_cc_default to pop up a dialog! + (We found this out the hard way :-) + +2000-4-26 Alexandra Ellwood <lxs@mit.edu> + + * ccdefault.c: Added version number to internal Kerberos Login Library + routine. + +2000-4-13 Alexandra Ellwood <lxs@mit.edu> + + * ccdefault.c: Added Kerberos Login library support (with ifdefs to control + whether or not it is on. Also added support to store a krb5_principal in the + os_context along with the default ccache name (if known, this principal is + the same as the last time we looked at the ccache. + * ccdefname.c: Added support to store a krb5_principal in the os_context + along with the default ccache name (if known, this principal is the same + as the last time we looked at the ccache. + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/lib/krb5/ccache/ccapi/ChangeLog b/src/lib/krb5/ccache/ccapi/ChangeLog index e4dac98..8074cdc 100644 --- a/src/lib/krb5/ccache/ccapi/ChangeLog +++ b/src/lib/krb5/ccache/ccapi/ChangeLog @@ -1,3 +1,60 @@ +2000-06-08 Alexandra Ellwood <lxs@mit.edu> + + * stdcc_util.c (dupCCtoK5, dupK5toCC): + Fixed code that stores times in localtime, not in kdc time. + +2000-05-18 Danilo Almeida <dalmeida@mit.edu> + + * stdcc_util.c (dupK5toCC): Remove unused variables. + + * stdcc_util.c: Reindent to krb5 coding style. Remove whitespace + at end of lines. Replace C++ comments with C comments. + + * stdcc_util.h: Replace C++ comments with C comments. + + * winccld.h: Define CC_API_VER2 for all Windows code using ccapi. + Update dynamic loading declarations to use CC_API_VER2. + + * winccld.h: Do not define or try to load cc_lock_request, which is + not actually used anywhere in the code. + + * stdcc.c: Define CC_API_VER2 if not defined rather than just if + not Windows. + + * winccld.c (LoadFuncs): Get error on DLL load failure even though + we do not use it in case we are doing source-level debugging. + +2000-05-04 Miro Jurisic <meeroh@mit.edu> + + * stdcc_util.c (dupCCtoK5, dupK5toCC): + Conditionalized local/KDC time conversions for Mac-only + until we figure out what to do about that + +2000-04-07 Jeffrey Altman <jaltman@columbia.edu> + + * stdcc_util.c (copyCCDataArrayToK5, copyCCDataArrayToK5): + * stdcc_util.c (dupCCtoK5, dupK5toCC): + + memory was being allocated as (sizeof(foo) * count + 1) + instead of (sizeof(foo) * (count + 1)) + +2000-04-03 Jeffrey Altman <jaltman@columbia.edu> + + * stdcc_util.c (copyCCDataArrayToK5, copyCCDataArrayToK5): + * stdcc_util.c (dupCCtoK5, dupK5toCC): + + Changed all references to the type UInt32 to unsigned int + since UInt32 is not a standard type on Unix or Win32 + +2000-03-24 Alexandra Ellwood <lxs@mit.edu> + + * stdcc_util.c (copyCCDataArrayToK5, copyCCDataArrayToK5): + Modified to copy authdata as well... this code may have + bugs since I couldn't get a good case where authdata != NULL + + * stdcc_util.c (dupCCtoK5, dupK5toCC): + Added code to store times in localtime, not in kdc time. + 2000-03-15 Danilo Almeida <dalmeida@mit.edu> * stdcc.c (krb5_stdcc_destroy): Do not mask KRB5_FCC_NOFILE error diff --git a/src/lib/krb5/ccache/ccapi/stdcc.c b/src/lib/krb5/ccache/ccapi/stdcc.c index a17cd02..849a906 100644 --- a/src/lib/krb5/ccache/ccapi/stdcc.c +++ b/src/lib/krb5/ccache/ccapi/stdcc.c @@ -40,7 +40,7 @@ apiCB *gCntrlBlock = NULL; #include "winccld.h" #endif -#if !defined(_MSDOS) && !defined(_WIN32) +#ifndef CC_API_VER2 #define CC_API_VER2 #endif diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.c b/src/lib/krb5/ccache/ccapi/stdcc_util.c index 4262eed..fb01506 100644 --- a/src/lib/krb5/ccache/ccapi/stdcc_util.c +++ b/src/lib/krb5/ccache/ccapi/stdcc_util.c @@ -23,112 +23,170 @@ * - copy and translate the null terminated arrays of data records * used in k5 tickets */ -int copyCCDataArrayToK5(cc_creds *cc, krb5_creds *kc, char whichArray) { - - cc_data *ccAdr, **cbase; - krb5_address *kAdr, **kbase, **constKBase; - int numRecords = 0; - - - if (whichArray == kAddressArray) { - /* check pointer */ - if (cc->addresses == NULL) { - kc->addresses = NULL; - return 0; - } - } else if (whichArray == kAuthDataArray) { - /* check pointer */ - if (cc->authdata == NULL) { - kc->authdata = NULL; - return 0; - } - } else - return -1; - - - cbase = (whichArray == kAddressArray) ? cc->addresses : cc->authdata; - /* calc number of records */ - while (*cbase++ != NULL) numRecords++; - /* allocate new array */ - constKBase = kbase = (krb5_address **)malloc((numRecords+1)*sizeof(char *)); - //reset base - cbase = (whichArray == kAddressArray) ? cc->addresses : cc->authdata; - - - //copy records - while (*cbase != NULL) { - *kbase = (krb5_address *)malloc(sizeof(krb5_address)); - kAdr = *kbase; - ccAdr = *cbase; - kAdr->magic = (whichArray == kAddressArray) ? KV5M_ADDRESS : KV5M_AUTHDATA; - kAdr->addrtype = ccAdr->type; - kAdr->length = ccAdr->length; - kAdr->contents = (krb5_octet *)malloc(kAdr->length); - memcpy(kAdr->contents, ccAdr->data, kAdr->length); - //next element please - kbase++; cbase++; +int copyCCDataArrayToK5(cc_creds *ccCreds, krb5_creds *v5Creds, char whichArray) { + + if (whichArray == kAddressArray) { + if (ccCreds->addresses == NULL) { + v5Creds->addresses = NULL; + } else { + + krb5_address **addrPtr, *addr; + cc_data **dataPtr, *data; + unsigned int numRecords = 0; + + /* Allocate the array of pointers: */ + for (dataPtr = ccCreds->addresses; *dataPtr != NULL; numRecords++, dataPtr++) {} + + v5Creds->addresses = (krb5_address **) malloc (sizeof(krb5_address *) * (numRecords + 1)); + if (v5Creds->addresses == NULL) + return ENOMEM; + + /* Fill in the array, allocating the address structures: */ + for (dataPtr = ccCreds->addresses, addrPtr = v5Creds->addresses; *dataPtr != NULL; addrPtr++, dataPtr++) { + + *addrPtr = (krb5_address *) malloc (sizeof(krb5_address)); + if (*addrPtr == NULL) + return ENOMEM; + data = *dataPtr; + addr = *addrPtr; + + addr->addrtype = data->type; + addr->magic = KV5M_ADDRESS; + addr->length = data->length; + addr->contents = (krb5_octet *) malloc (sizeof(krb5_octet) * addr->length); + if (addr->contents == NULL) + return ENOMEM; + memmove(addr->contents, data->data, addr->length); /* copy contents */ + } + + /* Write terminator: */ + *addrPtr = NULL; } - - //write terminator - *kbase = NULL; - if (whichArray == kAddressArray) kc->addresses = constKBase; - else kc->authdata = (krb5_authdata **)constKBase; + } - return 0; + if (whichArray == kAuthDataArray) { + if (ccCreds->authdata == NULL) { + v5Creds->authdata = NULL; + } else { + krb5_authdata **authPtr, *auth; + cc_data **dataPtr, *data; + unsigned int numRecords = 0; + + /* Allocate the array of pointers: */ + for (dataPtr = ccCreds->authdata; *dataPtr != NULL; numRecords++, dataPtr++) {} + + v5Creds->authdata = (krb5_authdata **) malloc (sizeof(krb5_authdata *) * (numRecords + 1)); + if (v5Creds->authdata == NULL) + return ENOMEM; + + /* Fill in the array, allocating the address structures: */ + for (dataPtr = ccCreds->authdata, authPtr = v5Creds->authdata; *dataPtr != NULL; authPtr++, dataPtr++) { + + *authPtr = (krb5_authdata *) malloc (sizeof(krb5_authdata)); + if (*authPtr == NULL) + return ENOMEM; + data = *dataPtr; + auth = *authPtr; + + auth->ad_type = data->type; + auth->magic = KV5M_AUTHDATA; + auth->length = data->length; + auth->contents = (krb5_octet *) malloc (sizeof(krb5_octet) * auth->length); + if (auth->contents == NULL) + return ENOMEM; + memmove(auth->contents, data->data, auth->length); /* copy contents */ + } + + /* Write terminator: */ + *authPtr = NULL; + } + } + + return 0; } /* * copyK5DataArrayToCC * - analagous to above, but in the other direction */ -int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray) { - - cc_data *ccAdr, **cbase, **constCBase; - krb5_address *kAdr, **kbase; - int numRecords = 0; - - - if (whichArray == kAddressArray) { - //check pointer - if (kc->addresses == NULL) { - cc->addresses = NULL; - return 0; } - } else if (whichArray == kAuthDataArray) { - //check pointer - if (kc->authdata == NULL) { - cc->authdata = NULL; - return 0; } - } else return -1; - - - kbase = (whichArray == kAddressArray) ? kc->addresses : (krb5_address **)kc->authdata; - //calc number of records - while (*kbase++ != NULL) numRecords++; - //allocate new array - constCBase = cbase = (cc_data **)malloc((numRecords+1)*sizeof(char *)); - //reset base - kbase = (whichArray == kAddressArray) ? kc->addresses : (krb5_address **)kc->authdata; - - - //copy records - while (*kbase != NULL) { - *cbase = (cc_data *)malloc(sizeof(krb5_address)); - kAdr = *kbase; - ccAdr = *cbase; - ccAdr->type = kAdr->addrtype; - ccAdr->length = kAdr->length; - ccAdr->data = (unsigned char *)malloc(ccAdr->length); - memcpy(ccAdr->data, kAdr->contents, kAdr->length); - //next element please - kbase++; cbase++; +int copyK5DataArrayToCC(krb5_creds *v5Creds, cc_creds *ccCreds, char whichArray) +{ + if (whichArray == kAddressArray) { + if (v5Creds->addresses == NULL) { + ccCreds->addresses = NULL; + } else { + + krb5_address **addrPtr, *addr; + cc_data **dataPtr, *data; + unsigned int numRecords = 0; + + /* Allocate the array of pointers: */ + for (addrPtr = v5Creds->addresses; *addrPtr != NULL; numRecords++, addrPtr++) {} + + ccCreds->addresses = (cc_data **) malloc (sizeof(cc_data *) * (numRecords + 1)); + if (ccCreds->addresses == NULL) + return ENOMEM; + + /* Fill in the array, allocating the address structures: */ + for (dataPtr = ccCreds->addresses, addrPtr = v5Creds->addresses; *addrPtr != NULL; addrPtr++, dataPtr++) { + + *dataPtr = (cc_data *) malloc (sizeof(cc_data)); + if (*dataPtr == NULL) + return ENOMEM; + data = *dataPtr; + addr = *addrPtr; + + data->type = addr->addrtype; + data->length = addr->length; + data->data = malloc (sizeof(char) * data->length); + if (data->data == NULL) + return ENOMEM; + memmove(data->data, addr->contents, data->length); /* copy contents */ + } + + /* Write terminator: */ + *dataPtr = NULL; + } + } + + if (whichArray == kAuthDataArray) { + if (v5Creds->authdata == NULL) { + ccCreds->authdata = NULL; + } else { + krb5_authdata **authPtr, *auth; + cc_data **dataPtr, *data; + unsigned int numRecords = 0; + + /* Allocate the array of pointers: */ + for (authPtr = v5Creds->authdata; *authPtr != NULL; numRecords++, authPtr++) {} + + ccCreds->authdata = (cc_data **) malloc (sizeof(cc_data *) * (numRecords + 1)); + if (ccCreds->authdata == NULL) + return ENOMEM; + + /* Fill in the array, allocating the address structures: */ + for (dataPtr = ccCreds->authdata, authPtr = v5Creds->authdata; *authPtr != NULL; authPtr++, dataPtr++) { + + *dataPtr = (cc_data *) malloc (sizeof(cc_data)); + if (*dataPtr == NULL) + return ENOMEM; + data = *dataPtr; + auth = *authPtr; + + data->type = auth->ad_type; + data->length = auth->length; + data->data = malloc (sizeof(char) * data->length); + if (data->data == NULL) + return ENOMEM; + memmove(data->data, auth->contents, data->length); /* copy contents */ + } + + /* Write terminator: */ + *dataPtr = NULL; } - - //write terminator - *cbase = NULL; - if (whichArray == kAddressArray) cc->addresses = (cc_data **)constCBase; - else cc->authdata = (cc_data **)constCBase; + } - return 0; + return 0; } /* @@ -136,52 +194,56 @@ int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray) { * - allocate an empty k5 style ticket and copy info from the cc_creds ticket */ -void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest) { - - int err; - - /* - * allocate and copy - * copy all of those damn fields back - */ - err = krb5_parse_name(context, src->client, &(dest->client)); - err = krb5_parse_name(context, src->server, &(dest->server)); - if (err) return; //parsename fails w/o krb5.ini for example - - /* copy keyblock */ - dest->keyblock.enctype = src->keyblock.type; - dest->keyblock.length = src->keyblock.length; - dest->keyblock.contents = (krb5_octet *)malloc(dest->keyblock.length); - memcpy(dest->keyblock.contents, src->keyblock.data, dest->keyblock.length); - - /* copy times */ - dest->times.authtime = src->authtime; - dest->times.starttime = src->starttime; - dest->times.endtime = src->endtime; - dest->times.renew_till = src->renew_till; - dest->is_skey = src->is_skey; - dest->ticket_flags = src->ticket_flags; - - /* more branching fields */ - copyCCDataArrayToK5(src, dest, kAddressArray); - dest->ticket.length = src->ticket.length; - dest->ticket.data = (char *)malloc(src->ticket.length); - memcpy(dest->ticket.data, src->ticket.data, src->ticket.length); - dest->second_ticket.length = src->second_ticket.length; - (dest->second_ticket).data = ( char *)malloc(src->second_ticket.length); - memcpy(dest->second_ticket.data, src->second_ticket.data, src->second_ticket.length); - - /* zero out magic number */ - dest->magic = 0; - /* - * later - * copyCCDataArrayToK5(src, dest, kAuthDataArray); - * krb5 docs say that authdata can be nulled out if we - * only want default behavior - */ - dest->authdata = NULL; - - return; +void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest) +{ + krb5_int32 offset_seconds = 0, offset_microseconds = 0; + int err; + + /* + * allocate and copy + * copy all of those damn fields back + */ + err = krb5_parse_name(context, src->client, &(dest->client)); + err = krb5_parse_name(context, src->server, &(dest->server)); + if (err) return; /* parsename fails w/o krb5.ini for example */ + + /* copy keyblock */ + dest->keyblock.enctype = src->keyblock.type; + dest->keyblock.length = src->keyblock.length; + dest->keyblock.contents = (krb5_octet *)malloc(dest->keyblock.length); + memcpy(dest->keyblock.contents, src->keyblock.data, dest->keyblock.length); + + /* copy times */ +#ifdef macintosh + err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds); + if (err) return; +#endif + dest->times.authtime = src->authtime + offset_seconds; + dest->times.starttime = src->starttime + offset_seconds; + dest->times.endtime = src->endtime + offset_seconds; + dest->times.renew_till = src->renew_till + offset_seconds; + dest->is_skey = src->is_skey; + dest->ticket_flags = src->ticket_flags; + + /* more branching fields */ + err = copyCCDataArrayToK5(src, dest, kAddressArray); + if (err) return; + + dest->ticket.length = src->ticket.length; + dest->ticket.data = (char *)malloc(src->ticket.length); + memcpy(dest->ticket.data, src->ticket.data, src->ticket.length); + dest->second_ticket.length = src->second_ticket.length; + (dest->second_ticket).data = ( char *)malloc(src->second_ticket.length); + memcpy(dest->second_ticket.data, src->second_ticket.data, src->second_ticket.length); + + /* zero out magic number */ + dest->magic = 0; + + /* authdata */ + err = copyCCDataArrayToK5(src, dest, kAuthDataArray); + if (err) return; + + return; } /* @@ -190,90 +252,97 @@ void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest) { */ void dupK5toCC(krb5_context context, krb5_creds *creds, cred_union **cu) { - cc_creds *c; - int err; + cc_creds *c; + int err; + krb5_int32 offset_seconds = 0, offset_microseconds = 0; #ifdef macintosh - char *tempname = NULL; + char *tempname = NULL; #endif - - if (cu == NULL) return; - - /* allocate the cred_union */ - *cu = (cred_union *)malloc(sizeof(cred_union)); - if ((*cu) == NULL) - return; - - (*cu)->cred_type = CC_CRED_V5; - - /* allocate creds structure (and install) */ - c = (cc_creds *)malloc(sizeof(cc_creds)); - if (c == NULL) return; - (*cu)->cred.pV5Cred = c; - - /* convert krb5 principals to flat principals */ + + if (cu == NULL) return; + + /* allocate the cred_union */ + *cu = (cred_union *)malloc(sizeof(cred_union)); + if ((*cu) == NULL) + return; + + (*cu)->cred_type = CC_CRED_V5; + + /* allocate creds structure (and install) */ + c = (cc_creds *)malloc(sizeof(cc_creds)); + if (c == NULL) return; + (*cu)->cred.pV5Cred = c; + + /* convert krb5 principals to flat principals */ #ifdef macintosh - /* - * and make sure the memory for c->client and c->server is on - * the system heap with NewPtr for the Mac (krb5_unparse_name - * puts it in appl heap with malloc) - */ - err = krb5_unparse_name(context, creds->client, &tempname); - c->client = malloc(strlen(tempname)+1); - if (c->client != NULL) - strcpy(c->client,tempname); - free(tempname); - tempname = NULL; - - err = krb5_unparse_name(context, creds->server, &tempname); - c->server = malloc(strlen(tempname)+1); - if (c->server != NULL) - strcpy(c->server,tempname); - free(tempname); + /* + * and make sure the memory for c->client and c->server is on + * the system heap with NewPtr for the Mac (krb5_unparse_name + * puts it in appl heap with malloc) + */ + err = krb5_unparse_name(context, creds->client, &tempname); + c->client = malloc(strlen(tempname)+1); + if (c->client != NULL) + strcpy(c->client,tempname); + free(tempname); + tempname = NULL; + + err = krb5_unparse_name(context, creds->server, &tempname); + c->server = malloc(strlen(tempname)+1); + if (c->server != NULL) + strcpy(c->server,tempname); + free(tempname); #else - err = krb5_unparse_name(context, creds->client, &(c->client)); - err = krb5_unparse_name(context, creds->server, &(c->server)); + err = krb5_unparse_name(context, creds->client, &(c->client)); + err = krb5_unparse_name(context, creds->server, &(c->server)); #endif - if (err) return; - - /* copy more fields */ - c->keyblock.type = creds->keyblock.enctype; - c->keyblock.length = creds->keyblock.length; - - if (creds->keyblock.contents != NULL) { - c->keyblock.data = (unsigned char *)malloc(creds->keyblock.length); - memcpy(c->keyblock.data, creds->keyblock.contents, creds->keyblock.length); - } else { - c->keyblock.data = NULL; - } - - c->authtime = creds->times.authtime; - c->starttime = creds->times.starttime; - c->endtime = creds->times.endtime; - c->renew_till = creds->times.renew_till; - c->is_skey = creds->is_skey; - c->ticket_flags = creds->ticket_flags; - - copyK5DataArrayToCC(creds, c, kAddressArray); - - c->ticket.length = creds->ticket.length; - if (creds->ticket.data != NULL) { - c->ticket.data = (unsigned char *)malloc(creds->ticket.length); - memcpy(c->ticket.data, creds->ticket.data, creds->ticket.length); - } else { - c->ticket.data = NULL; - } - - c->second_ticket.length = creds->second_ticket.length; - if (creds->second_ticket.data != NULL) { - c->second_ticket.data = (unsigned char *)malloc(creds->second_ticket.length); - memcpy(c->second_ticket.data, creds->second_ticket.data, creds->second_ticket.length); - } else { - c->second_ticket.data = NULL; - } - - c->authdata = NULL; - - return; + if (err) return; + + /* copy more fields */ + c->keyblock.type = creds->keyblock.enctype; + c->keyblock.length = creds->keyblock.length; + + if (creds->keyblock.contents != NULL) { + c->keyblock.data = (unsigned char *)malloc(creds->keyblock.length); + memcpy(c->keyblock.data, creds->keyblock.contents, creds->keyblock.length); + } else { + c->keyblock.data = NULL; + } + +#ifdef macintosh + err = krb5_get_time_offsets(context, &offset_seconds, &offset_microseconds); + if (err) return; +#endif + c->authtime = creds->times.authtime - offset_seconds; + c->starttime = creds->times.starttime - offset_seconds; + c->endtime = creds->times.endtime - offset_seconds; + c->renew_till = creds->times.renew_till - offset_seconds; + c->is_skey = creds->is_skey; + c->ticket_flags = creds->ticket_flags; + + err = copyK5DataArrayToCC(creds, c, kAddressArray); + if (err) return; + + c->ticket.length = creds->ticket.length; + if (creds->ticket.data != NULL) { + c->ticket.data = (unsigned char *)malloc(creds->ticket.length); + memcpy(c->ticket.data, creds->ticket.data, creds->ticket.length); + } else { + c->ticket.data = NULL; + } + + c->second_ticket.length = creds->second_ticket.length; + if (creds->second_ticket.data != NULL) { + c->second_ticket.data = (unsigned char *)malloc(creds->second_ticket.length); + memcpy(c->second_ticket.data, creds->second_ticket.data, creds->second_ticket.length); + } else { + c->second_ticket.data = NULL; + } + + err = copyK5DataArrayToCC(creds, c, kAuthDataArray); + if (err) return; + + return; } /* @@ -281,7 +350,7 @@ void dupK5toCC(krb5_context context, krb5_creds *creds, cred_union **cu) */ static krb5_boolean times_match(t1, t2) -register const krb5_ticket_times *t1; + register const krb5_ticket_times *t1; register const krb5_ticket_times *t2; { if (t1->renew_till) { @@ -308,7 +377,7 @@ times_match_exact (t1, t2) static krb5_boolean standard_fields_match(context, mcreds, creds) - krb5_context context; + krb5_context context; register const krb5_creds *mcreds, *creds; { return (krb5_principal_compare(context, mcreds->client,creds->client) && @@ -319,12 +388,12 @@ register const krb5_creds *mcreds, *creds; static krb5_boolean srvname_match(context, mcreds, creds) - krb5_context context; + krb5_context context; register const krb5_creds *mcreds, *creds; { krb5_boolean retval; krb5_principal_data p1, p2; - + retval = krb5_principal_compare(context, mcreds->client,creds->client); if (retval != TRUE) return retval; @@ -368,7 +437,7 @@ authdata_match(mdata, data) static krb5_boolean data_match(data1, data2) -register const krb5_data *data1, *data2; + register const krb5_data *data1, *data2; { if (!data1) { if (!data2) @@ -396,117 +465,113 @@ register const krb5_data *data1, *data2; int stdccCredsMatch(krb5_context context, krb5_creds *base, krb5_creds *match, int whichfields) { - krb5_ticket_times b, m; - krb5_authdata **bp, **mp; - krb5_boolean retval; - - if (((MATCH_SET(KRB5_TC_MATCH_SRV_NAMEONLY) && - srvname_match(context, match, base)) || - standard_fields_match(context, match, base)) - && - (! MATCH_SET(KRB5_TC_MATCH_IS_SKEY) || - match->is_skey == base->is_skey) - && - (! MATCH_SET(KRB5_TC_MATCH_FLAGS_EXACT) || - match->ticket_flags == base->ticket_flags) - && - (! MATCH_SET(KRB5_TC_MATCH_FLAGS) || - flags_match(match->ticket_flags, base->ticket_flags)) - && - (! MATCH_SET(KRB5_TC_MATCH_TIMES_EXACT) || - times_match_exact(&match->times, &base->times)) - && - (! MATCH_SET(KRB5_TC_MATCH_TIMES) || - times_match(&match->times, &base->times)) - && - (! MATCH_SET(KRB5_TC_MATCH_AUTHDATA) || - authdata_match (match->authdata, base->authdata)) - && - (! MATCH_SET(KRB5_TC_MATCH_2ND_TKT) || - data_match (&match->second_ticket, &base->second_ticket)) - && - ((! MATCH_SET(KRB5_TC_MATCH_KTYPE))|| - (match->keyblock.enctype == base->keyblock.enctype)) - ) - return TRUE; - return FALSE; - + if (((MATCH_SET(KRB5_TC_MATCH_SRV_NAMEONLY) && + srvname_match(context, match, base)) || + standard_fields_match(context, match, base)) + && + (! MATCH_SET(KRB5_TC_MATCH_IS_SKEY) || + match->is_skey == base->is_skey) + && + (! MATCH_SET(KRB5_TC_MATCH_FLAGS_EXACT) || + match->ticket_flags == base->ticket_flags) + && + (! MATCH_SET(KRB5_TC_MATCH_FLAGS) || + flags_match(match->ticket_flags, base->ticket_flags)) + && + (! MATCH_SET(KRB5_TC_MATCH_TIMES_EXACT) || + times_match_exact(&match->times, &base->times)) + && + (! MATCH_SET(KRB5_TC_MATCH_TIMES) || + times_match(&match->times, &base->times)) + && + (! MATCH_SET(KRB5_TC_MATCH_AUTHDATA) || + authdata_match (match->authdata, base->authdata)) + && + (! MATCH_SET(KRB5_TC_MATCH_2ND_TKT) || + data_match (&match->second_ticket, &base->second_ticket)) + && + ((! MATCH_SET(KRB5_TC_MATCH_KTYPE))|| + (match->keyblock.enctype == base->keyblock.enctype)) + ) + return TRUE; + return FALSE; } -// ----- free_cc_cred_union, etc -------------- +/* ----- free_cc_cred_union, etc -------------- */ /* - Since the Kerberos5 library allocates a credentials cache structure - (in dupK5toCC() above) with its own memory allocation routines - which - may be different than how the CCache allocates memory - the Kerb5 library - must have its own version of cc_free_creds() to deallocate it. These - functions do that. The top-level function to substitue for cc_free_creds() - is krb5_free_cc_cred_union(). - - If the CCache library wants to use a cred_union structure created by - the Kerb5 library, it should make a deep copy of it to "translate" to its - own memory allocation space. + Since the Kerberos5 library allocates a credentials cache structure + (in dupK5toCC() above) with its own memory allocation routines - which + may be different than how the CCache allocates memory - the Kerb5 library + must have its own version of cc_free_creds() to deallocate it. These + functions do that. The top-level function to substitue for cc_free_creds() + is krb5_free_cc_cred_union(). + + If the CCache library wants to use a cred_union structure created by + the Kerb5 library, it should make a deep copy of it to "translate" to its + own memory allocation space. */ -static void deep_free_cc_data (cc_data data) { - - if (data.data != NULL) - free (data.data); +static void deep_free_cc_data (cc_data data) +{ + if (data.data != NULL) + free (data.data); } static void deep_free_cc_data_array (cc_data** data) { - - unsigned int index; - - if (data == NULL) - return; - - for (index = 0; data [index] != NULL; index++) { - deep_free_cc_data (*(data [index])); - free (data [index]); - } - - free (data); + + unsigned int index; + + if (data == NULL) + return; + + for (index = 0; data [index] != NULL; index++) { + deep_free_cc_data (*(data [index])); + free (data [index]); + } + + free (data); } -static void deep_free_cc_v5_creds (cc_creds* creds) { - - if (creds == NULL) - return; - - if (creds -> client != NULL) - free (creds -> client); - if (creds -> server != NULL) - free (creds -> server); - - deep_free_cc_data (creds -> keyblock); - deep_free_cc_data (creds -> ticket); - deep_free_cc_data (creds -> second_ticket); - - deep_free_cc_data_array (creds -> addresses); - deep_free_cc_data_array (creds -> authdata); - - free(creds); +static void deep_free_cc_v5_creds (cc_creds* creds) +{ + if (creds == NULL) + return; + + if (creds -> client != NULL) + free (creds -> client); + if (creds -> server != NULL) + free (creds -> server); + + deep_free_cc_data (creds -> keyblock); + deep_free_cc_data (creds -> ticket); + deep_free_cc_data (creds -> second_ticket); + + deep_free_cc_data_array (creds -> addresses); + deep_free_cc_data_array (creds -> authdata); + + free(creds); } -static void deep_free_cc_creds (cred_union creds) { - - if (creds.cred_type == CC_CRED_V4) { // we shouldn't get this, of course - free (creds.cred.pV4Cred); - } else if (creds.cred_type == CC_CRED_V5) { - deep_free_cc_v5_creds (creds.cred.pV5Cred); - } +static void deep_free_cc_creds (cred_union creds) +{ + if (creds.cred_type == CC_CRED_V4) { + /* we shouldn't get this, of course */ + free (creds.cred.pV4Cred); + } else if (creds.cred_type == CC_CRED_V5) { + deep_free_cc_v5_creds (creds.cred.pV5Cred); + } } -// top-level exported function -cc_int32 krb5_free_cc_cred_union (cred_union** creds) { - - if (creds == NULL) - return CC_BAD_PARM; - - if (*creds != NULL) { - deep_free_cc_creds (**creds); - free (*creds); - *creds = NULL; - } - - return CC_NOERROR; +/* top-level exported function */ +cc_int32 krb5_free_cc_cred_union (cred_union** creds) +{ + if (creds == NULL) + return CC_BAD_PARM; + + if (*creds != NULL) { + deep_free_cc_creds (**creds); + free (*creds); + *creds = NULL; + } + + return CC_NOERROR; } diff --git a/src/lib/krb5/ccache/ccapi/stdcc_util.h b/src/lib/krb5/ccache/ccapi/stdcc_util.h index 93538bf..7d3bc93 100644 --- a/src/lib/krb5/ccache/ccapi/stdcc_util.h +++ b/src/lib/krb5/ccache/ccapi/stdcc_util.h @@ -1,6 +1,7 @@ -//stdcc_util.h -// -// Frank Dabek, July 1998 +/* stdcc_util.h + * + * Frank Dabek, July 1998 + */ #if defined(macintosh) #include "CCache2.h" @@ -12,7 +13,7 @@ #include "krb5.h" -//protoypes for private functions declared in stdcc_util.c +/* protoypes for private functions declared in stdcc_util.c */ int copyCCDataArrayToK5(cc_creds *cc, krb5_creds *kc, char whichArray); int copyK5DataArrayToCC(krb5_creds *kc, cc_creds *cc, char whichArray); void dupCCtoK5(krb5_context context, cc_creds *src, krb5_creds *dest); diff --git a/src/lib/krb5/ccache/ccapi/winccld.c b/src/lib/krb5/ccache/ccapi/winccld.c index 2792cee..4fded76 100644 --- a/src/lib/krb5/ccache/ccapi/winccld.c +++ b/src/lib/krb5/ccache/ccapi/winccld.c @@ -45,6 +45,8 @@ static int LoadFuncs(const char* dll_name, FUNC_INFO fi[], } if (!(h = LoadLibrary(dll_name))) { + /* Get error for source debugging purposes. */ + error = (int)GetLastError(); return LF_NODLL; } diff --git a/src/lib/krb5/ccache/ccapi/winccld.h b/src/lib/krb5/ccache/ccapi/winccld.h index 09a7ef5..e285d1f 100644 --- a/src/lib/krb5/ccache/ccapi/winccld.h +++ b/src/lib/krb5/ccache/ccapi/winccld.h @@ -6,6 +6,10 @@ #ifndef KRB5_WINCCLD_H_ #define KRB5_WINCCLD_H_ +#ifndef CC_API_VER2 +#define CC_API_VER2 +#endif + #include "cacheapi.h" typedef cc_int32 (*FP_cc_initialize)(apiCB**, const cc_int32, @@ -19,6 +23,9 @@ typedef cc_int32 (*FP_cc_open)(apiCB*, const char*, const enum cc_cred_vers, typedef cc_int32 (*FP_cc_close)(apiCB*, ccache_p**); typedef cc_int32 (*FP_cc_destroy)(apiCB*, ccache_p**); typedef cc_int32 (*FP_cc_seq_fetch_NCs)(apiCB*, ccache_p**, ccache_cit**); +typedef cc_int32 (*FP_cc_seq_fetch_NCs_begin)(apiCB*, ccache_cit**); +typedef cc_int32 (*FP_cc_seq_fetch_NCs_next)(apiCB*, ccache_p**, ccache_cit*); +typedef cc_int32 (*FP_cc_seq_fetch_NCs_end)(apiCB*, ccache_cit**); typedef cc_int32 (*FP_cc_get_NC_info)(apiCB*, struct _infoNC***); typedef cc_int32 (*FP_cc_free_NC_info)(apiCB*, struct _infoNC***); typedef cc_int32 (*FP_cc_get_name)(apiCB*, const ccache_p*, char**); @@ -34,6 +41,11 @@ typedef cc_int32 (*FP_cc_remove_cred)(apiCB*, const ccache_p*, const cred_union); typedef cc_int32 (*FP_cc_seq_fetch_creds)(apiCB*, const ccache_p*, cred_union**, ccache_cit**); +typedef cc_int32 (*FP_cc_seq_fetch_creds_begin)(apiCB*, const ccache_p*, + ccache_cit**); +typedef cc_int32 (*FP_cc_seq_fetch_creds_next)(apiCB*, cred_union**, + ccache_cit*); +typedef cc_int32 (*FP_cc_seq_fetch_creds_end)(apiCB*, ccache_cit**); typedef cc_int32 (*FP_cc_free_principal)(apiCB*, char**); typedef cc_int32 (*FP_cc_free_name)(apiCB*, char** name); typedef cc_int32 (*FP_cc_free_creds)(apiCB*, cred_union** pCred); @@ -58,17 +70,33 @@ DECL_FUNC_PTR(cc_create); DECL_FUNC_PTR(cc_open); DECL_FUNC_PTR(cc_close); DECL_FUNC_PTR(cc_destroy); +#if 0 /* Not used */ +#ifdef CC_API_VER2 +DECL_FUNC_PTR(cc_seq_fetch_NCs_begin); +DECL_FUNC_PTR(cc_seq_fetch_NCs_next); +DECL_FUNC_PTR(cc_seq_fetch_NCs_end); +#else DECL_FUNC_PTR(cc_seq_fetch_NCs); +#endif DECL_FUNC_PTR(cc_get_NC_info); DECL_FUNC_PTR(cc_free_NC_info); +#endif DECL_FUNC_PTR(cc_get_name); DECL_FUNC_PTR(cc_set_principal); DECL_FUNC_PTR(cc_get_principal); DECL_FUNC_PTR(cc_get_cred_version); +#if 0 /* Not used */ DECL_FUNC_PTR(cc_lock_request); +#endif DECL_FUNC_PTR(cc_store); DECL_FUNC_PTR(cc_remove_cred); +#ifdef CC_API_VER2 +DECL_FUNC_PTR(cc_seq_fetch_creds_begin); +DECL_FUNC_PTR(cc_seq_fetch_creds_next); +DECL_FUNC_PTR(cc_seq_fetch_creds_end); +#else DECL_FUNC_PTR(cc_seq_fetch_creds); +#endif DECL_FUNC_PTR(cc_free_principal); DECL_FUNC_PTR(cc_free_name); DECL_FUNC_PTR(cc_free_creds); @@ -82,17 +110,27 @@ FUNC_INFO krbcc_fi[] = { MAKE_FUNC_INFO(cc_open), MAKE_FUNC_INFO(cc_close), MAKE_FUNC_INFO(cc_destroy), +#if 0 /* Not used */ MAKE_FUNC_INFO(cc_seq_fetch_NCs), MAKE_FUNC_INFO(cc_get_NC_info), MAKE_FUNC_INFO(cc_free_NC_info), +#endif MAKE_FUNC_INFO(cc_get_name), MAKE_FUNC_INFO(cc_set_principal), MAKE_FUNC_INFO(cc_get_principal), MAKE_FUNC_INFO(cc_get_cred_version), +#if 0 /* Not used */ MAKE_FUNC_INFO(cc_lock_request), +#endif MAKE_FUNC_INFO(cc_store), MAKE_FUNC_INFO(cc_remove_cred), +#ifdef CC_API_VER2 + MAKE_FUNC_INFO(cc_seq_fetch_creds_begin), + MAKE_FUNC_INFO(cc_seq_fetch_creds_next), + MAKE_FUNC_INFO(cc_seq_fetch_creds_end), +#else MAKE_FUNC_INFO(cc_seq_fetch_creds), +#endif MAKE_FUNC_INFO(cc_free_principal), MAKE_FUNC_INFO(cc_free_name), MAKE_FUNC_INFO(cc_free_creds), @@ -109,17 +147,33 @@ FUNC_INFO krbcc_fi[] = { #define cc_open pcc_open #define cc_close pcc_close #define cc_destroy pcc_destroy +#if 0 /* Not used */ +#ifdef CC_API_VER2 +#define cc_seq_fetch_NCs_begin pcc_seq_fetch_NCs_begin +#define cc_seq_fetch_NCs_next pcc_seq_fetch_NCs_next +#define cc_seq_fetch_NCs_end pcc_seq_fetch_NCs_end +#else #define cc_seq_fetch_NCs pcc_seq_fetch_NCs +#endif #define cc_get_NC_info pcc_get_NC_info #define cc_free_NC_info pcc_free_NC_info +#endif /* End of Not used */ #define cc_get_name pcc_get_name #define cc_set_principal pcc_set_principal #define cc_get_principal pcc_get_principal #define cc_get_cred_version pcc_get_cred_version +#if 0 /* Not used */ #define cc_lock_request pcc_lock_request +#endif #define cc_store pcc_store #define cc_remove_cred pcc_remove_cred +#ifdef CC_API_VER2 +#define cc_seq_fetch_creds_begin pcc_seq_fetch_creds_begin +#define cc_seq_fetch_creds_next pcc_seq_fetch_creds_next +#define cc_seq_fetch_creds_end pcc_seq_fetch_creds_end +#else #define cc_seq_fetch_creds pcc_seq_fetch_creds +#endif #define cc_free_principal pcc_free_principal #define cc_free_name pcc_free_name #define cc_free_creds pcc_free_creds diff --git a/src/lib/krb5/ccache/ccdefault.c b/src/lib/krb5/ccache/ccdefault.c index 3e2699c..964f6f9 100644 --- a/src/lib/krb5/ccache/ccdefault.c +++ b/src/lib/krb5/ccache/ccdefault.c @@ -29,10 +29,91 @@ #include "k5-int.h" +#ifdef USE_LOGIN_LIBRARY +#include <KerberosLoginInternal.h> +#endif + KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_cc_default(context, ccache) krb5_context context; krb5_ccache FAR *ccache; { - return krb5_cc_resolve(context, krb5_cc_default_name(context), ccache); + krb5_error_code retval; + krb5_os_context os_ctx; + + if (!context || context->magic != KV5M_CONTEXT) + return KV5M_CONTEXT; + + os_ctx = context->os_context; + + retval = krb5_cc_resolve(context, krb5_cc_default_name(context), ccache); + if (!retval && ccache && !os_ctx->default_ccprincipal) { + /* We got a ccache... remember what principal is associated with it */ + if (krb5_cc_get_principal (context, *ccache, &os_ctx->default_ccprincipal) != 0) + os_ctx->default_ccprincipal = 0; + } + return retval; } + +/* This is the internal function which opens the default ccache. On platforms supporting + the login library's automatic popup dialog to get tickets, this function also updated the + library's internal view of the current principal associated with this cache. + + All krb5 and GSS functions which need to open a cache to get a tgt to obtain service tickets + should call this function, not krb5_cc_default() */ + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5int_cc_default(context, ccache) + krb5_context context; + krb5_ccache FAR *ccache; +{ +#ifdef USE_LOGIN_LIBRARY + { + /* make sure the default cache has tix before you open it */ + char *outCacheName; + KLPrincipal desiredPrincipal = nil; + krb5_principal desiredKrb5Principal; + krb5_error_code err; + krb5_os_context os_ctx; + + if (!context || context->magic != KV5M_CONTEXT) + return KV5M_CONTEXT; + + os_ctx = context->os_context; + + desiredKrb5Principal = os_ctx->default_ccprincipal; + + /* do we want a specific client principal? */ + if (desiredKrb5Principal != NULL) { + char *desiredName; + + err = krb5_unparse_name (context, desiredKrb5Principal, &desiredName); + if (!err) { + err = KLCreatePrincipalFromString (desiredName, + kerberosVersion_V5, &desiredPrincipal); + krb5_free_unparsed_name (context, desiredName); + if (err != klNoErr) + desiredPrincipal = nil; + } + } + + /* Try to make sure a krb5 tgt is in the cache */ + err = __KLInternalAcquireTicketsForCache (desiredPrincipal, krb5_cc_default_name(context), + kerberosVersion_V5, nil, &outCacheName); + if (err == klNoErr) { + /* This function tries to get tickets and put them in the specified + cache, however, if the cache does not exist, it may choose to put + them elsewhere (ie: the system default) so we set that here */ + if (strcmp (krb5_cc_default_name (context), outCacheName) != 0) { + krb5_cc_set_default_name (context, outCacheName); + } + KLDisposeString (outCacheName); + } + + if (desiredPrincipal != nil) + KLDisposePrincipal (desiredPrincipal); + } +#endif + + return krb5_cc_default (context, ccache); +}
\ No newline at end of file diff --git a/src/lib/krb5/krb/ChangeLog b/src/lib/krb5/krb/ChangeLog index 59d8765..1a6e726 100644 --- a/src/lib/krb5/krb/ChangeLog +++ b/src/lib/krb5/krb/ChangeLog @@ -1,3 +1,145 @@ +2000-06-07 Tom Yu <tlyu@mit.edu> + + * get_creds.c (krb5_get_credentials): Translate KRB5_CC_NOTFOUND + returned from krb5_get_cred_from_kdc() if a prior call to + krb5_cc_retrieve_cred() returned KRB5_CC_NOT_KTYPE. + +2000-06-03 Tom Yu <tlyu@mit.edu> + + * rd_priv.c (krb5_rd_priv_basic): Delete code that was incorrectly + doing explicit ivec chaining; c_decrypt() does it now. + + * mk_priv.c (krb5_mk_priv_basic): Delete code that was incorrectly + doing explicit ivec chaining; c_encrypt() does it now. + +2000-06-03 Ken Raeburn <raeburn@mit.edu> + + * get_in_tkt.c (krb5_get_in_tkt): If enctypes are specified, send + the server the intersection of that list and the supported types, + in the order requested. + +2000-06-02 Danilo Almeida <dalmeida@mit.edu> + + * init_ctx.c (krb5_get_tgs_ktypes, krb5_free_ktypes): Fix linkage to + be KRB5_CALLCONV. + +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * recvauth.c (krb5_recvauth_version): New routine, takes a + krb5_data in which to store the client's application version + string. + (recvauth_common): Renamed from krb5_recvauth, added above + functionality depending on extra argument values. + (krb5_recvauth): New stub, calls above routine with extra dummy + values. + +2000-5-19 Alexandra Ellwood <lxs@mit.edu> + + * sendauth.c, fwd_tgt.c: Changed to use krb5int_cc_default. This function + supports the Kerberos Login Library and pops up a dialog if the cache does + not contain valid tickets. This is used to automatically get a tgt before + obtaining service tickets. Note that this should be an internal function + because callers don't expect krb5_cc_default to pop up a dialog! + (We found this out the hard way :-) + +2000-05-16 Ken Raeburn <raeburn@mit.edu> + Nalin Dahyabhai <nalin@redhat.com> + + * conv_princ.c (krb5_524_conv_principal): Return an error if name + is too long. Use memcpy for character data since we already know + the length. + +2000-05-16 Ken Raeburn <raeburn@mit.edu> + + * kfree.c: Remove unneeded "return" statements at the end of many + functions. + (krb5_free_*_content, krb5_free_*_contents, + krb5_free_cred_enc_part, krb5_free_pwd_sequences): Set freed + pointer members to null when containing structure isn't being + freed. + +2000-05-16 Tom Yu <tlyu@mit.edu> + + * conv_princ.c (krb5_524_conv_principal): Make a copy of the krb5 + realm that is nul-terminated to avoid falling off the end of the + krb5 realm, which is not necessarily nul-terminated. + +2000-05-16 Nalin Dahyabhai <nalin@redhat.com> + + * kfree.c (krb5_free_keyblock_contents): Set contents pointer to + null after freeing. + +2000-05-15 Jeffrey Altman <jaltman@columbia.edu> + + * Added new source file appdefault.c + Implements new public functions + + krb5_appdefault_string + krb5_appdefault_boolean + +2000-05-12 Ken Raeburn <raeburn@mit.edu> + + * t_kerb.c (test_524_conv_principal): New test code, to exercise + yesterday's code addition. + (main, usage): Updated. + * t_krb5.conf: Added stanford.edu->IR.STANFORD.EDU mapping, and a + test case for improperly long v4 realm names. + * Makefile.in (check-unix): Run 524 conversion test for some test + Athena and Stanford names. + * t_ref_kerb.out: Updated. + + * init_ctx.c (init_common): Feed current-microsecond time and + process-id into PRNG, instead of just current-second time. + * mk_req_ext.c (krb5_mk_req_extended): Feed current time into + PRNG if a subkey will be generated. + * sendauth.c (krb5_sendauth): Feed local and remote addresses of + socket, if they can be determined, into the PRNG if a subkey will + be used. + +2000-05-11 Ken Raeburn <raeburn@mit.edu> + Booker C. Bense <bbense@networking.stanford.edu> + + * conv_princ.c (krb5_524_conv_principal): Look up v4_realm in + config file, in case site's krb4 realm name isn't the same as the + krb5 realm name. + +2000-04-28 Nalin Dahyabhai <nalin@redhat.com> + + * chk_trans.c (krb5_check_transited_list): Don't overflow buffers + "prev" and "next". + * conv_princ.c (krb5_425_conv_principal): Don't overflow buffer + "buf". + +2000-04-28 Alexandra Ellwood <lxs@mit.edu> + + * gic_pwd.c (krb5_init_creds_password) added code to return to + login library if the password is expired (login library handles + this error appropriately). + +2000-04-18 Ken Raeburn <raeburn@mit.edu> + + * init_ctx.c (krb5_free_ktypes): New routine, to free values + returned by krb5_get_tgs_ktypes, krb5_get_permitted_enctypes, and + krb5_get_default_in_tkt_ktypes. + (krb5_set_default_tgs_ktypes, krb5_is_permitted_enctype): Use it. + (get_profile_etype_list): Use passed-in enctype list if the + passed-in count is non-zero, instead of checking the + in_tkt_ktype_count value in the context. + +2000-04-08 Tom Yu <tlyu@mit.edu> + + * vfy_increds.c (krb5_verify_init_creds): appdefault_boolean -> + libdefault_boolean; it somehow got missed earlier. + +2000-04-07 Jeffrey Altman <jaltman@columbia.edu> + + * gic_pwd.c (krb5_get_init_creds_keytab), gic_pwd.c + (krb5_get_init_creds_password) when determining whether or not to + retry with a "master kdc" do not retry if the return value from + the first attempt was KRB5_REALM_CANT_RESOLV. Also, do not + overwrite the return code if the return value from the access to + the "master kdc" was KRB5_REALM_CANT_RESOLV. + 2000-03-15 Danilo Almeida <dalmeida@mit.edu> * init_ctx.c (init_common), gic_pwd.c (krb5_get_as_key_password, diff --git a/src/lib/krb5/krb/Makefile.in b/src/lib/krb5/krb/Makefile.in index ba76662..19c1da4 100644 --- a/src/lib/krb5/krb/Makefile.in +++ b/src/lib/krb5/krb/Makefile.in @@ -15,6 +15,7 @@ STLIBOBJS= \ addr_comp.o \ addr_order.o \ addr_srch.o \ + appdefault.o \ auth_con.o \ bld_pr_ext.o \ bld_princ.o \ @@ -99,6 +100,7 @@ STLIBOBJS= \ OBJS= $(OUTPRE)addr_comp.$(OBJEXT) \ $(OUTPRE)addr_order.$(OBJEXT) \ $(OUTPRE)addr_srch.$(OBJEXT) \ + $(OUTPRE)appdefault.$(OBJEXT) \ $(OUTPRE)auth_con.$(OBJEXT) \ $(OUTPRE)bld_pr_ext.$(OBJEXT) \ $(OUTPRE)bld_princ.$(OBJEXT) \ @@ -183,6 +185,7 @@ OBJS= $(OUTPRE)addr_comp.$(OBJEXT) \ SRCS= $(srcdir)/addr_comp.c \ $(srcdir)/addr_order.c \ $(srcdir)/addr_srch.c \ + $(srcdir)/appdefault.c \ $(srcdir)/auth_con.c \ $(srcdir)/bld_pr_ext.c \ $(srcdir)/bld_princ.c \ @@ -324,6 +327,8 @@ check-unix:: $(TEST_PROGS) 425_conv_principal rcmd uunet UU.NET \ 425_conv_principal zephyr zephyr ATHENA.MIT.EDU \ 425_conv_principal kadmin ATHENA.MIT.EDU ATHENA.MIT.EDU \ + 524_conv_principal host/e40-po.mit.edu@ATHENA.MIT.EDU \ + 524_conv_principal host/foobar.stanford.edu@stanford.edu \ set_realm marc@MIT.EDU CYGNUS.COM \ > test.out cmp test.out $(srcdir)/t_ref_kerb.out diff --git a/src/lib/krb5/krb/appdefault.c b/src/lib/krb5/krb/appdefault.c new file mode 100644 index 0000000..17183d8 --- /dev/null +++ b/src/lib/krb5/krb/appdefault.c @@ -0,0 +1,183 @@ +/* + * appdefault - routines designed to be called from applications to + * handle the [appdefaults] profile section + */ + +#include <stdio.h> +#include <string.h> +#include <k5-int.h> + + + + /*xxx Duplicating this is annoying; try to work on a better way.*/ +static char *conf_yes[] = { + "y", "yes", "true", "t", "1", "on", + 0, +}; + +static char *conf_no[] = { + "n", "no", "false", "nil", "0", "off", + 0, +}; + +static int conf_boolean(s) + char *s; +{ + char **p; + for(p=conf_yes; *p; p++) { + if (!strcasecmp(*p,s)) + return 1; + } + for(p=conf_no; *p; p++) { + if (!strcasecmp(*p,s)) + return 0; + } + /* Default to "no" */ + return 0; +} + +static krb5_error_code appdefault_get(context, appname, realm, option, + ret_value) + krb5_context context; + const char *appname, *option; + const krb5_data *realm; + char **ret_value; +{ + profile_t profile; + const char *names[5]; + char **nameval = NULL; + krb5_error_code retval; + const char * realmstr = realm?realm->data:NULL; + + if (!context || (context->magic != KV5M_CONTEXT)) + return KV5M_CONTEXT; + + profile = context->profile; + + /* + * Try number one: + * + * [appdefaults] + * app = { + * SOME.REALM = { + * option = <boolean> + * } + * } + */ + + names[0] = "appdefaults"; + names[1] = appname; + + if (realmstr) { + names[2] = realmstr; + names[3] = option; + names[4] = 0; + retval = profile_get_values(profile, names, &nameval); + if (retval == 0 && nameval && nameval[0]) { + *ret_value = strdup(nameval[0]); + goto goodbye; + } + } + + /* + * Try number two: + * + * [appdefaults] + * app = { + * option = <boolean> + * } + */ + + names[2] = option; + names[3] = 0; + retval = profile_get_values(profile, names, &nameval); + if (retval == 0 && nameval && nameval[0]) { + *ret_value = strdup(nameval[0]); + goto goodbye; + } + + /* + * Try number three: + * + * [appdefaults] + * realm = { + * option = <boolean> + */ + + if (realmstr) { + names[1] = realmstr; + names[2] = option; + names[3] = 0; + retval = profile_get_values(profile, names, &nameval); + if (retval == 0 && nameval && nameval[0]) { + *ret_value = strdup(nameval[0]); + goto goodbye; + } + } + + /* + * Try number four: + * + * [appdefaults] + * option = <boolean> + */ + + names[1] = option; + names[2] = 0; + retval = profile_get_values(profile, names, &nameval); + if (retval == 0 && nameval && nameval[0]) { + *ret_value = strdup(nameval[0]); + } else { + return retval; + } + +goodbye: + if (nameval) { + char **cpp; + for (cpp = nameval; *cpp; cpp++) + free(*cpp); + free(nameval); + } + return 0; +} + +KRB5_DLLIMP void KRB5_CALLCONV +krb5_appdefault_boolean(context, appname, realm, option, + default_value, ret_value) + krb5_context context; + const char *appname, *option; + const krb5_data *realm; + int default_value; + int *ret_value; +{ + char *string = NULL; + krb5_error_code retval; + + retval = appdefault_get(context, appname, realm, option, &string); + + if (! retval && string) { + *ret_value = conf_boolean(string); + free(string); + } else + *ret_value = default_value; +} + +KRB5_DLLIMP void KRB5_CALLCONV +krb5_appdefault_string(context, appname, realm, option, default_value, + ret_value) + krb5_context context; + const char *appname, *option, *default_value; + char **ret_value; + const krb5_data *realm; + { + krb5_error_code retval; + char *string; + + retval = appdefault_get(context, appname, realm, option, &string); + + if (! retval && string) { + *ret_value = string; + } else { + *ret_value = strdup(default_value); + } +} diff --git a/src/lib/krb5/krb/chk_trans.c b/src/lib/krb5/krb/chk_trans.c index c2ac716..eee55c8 100644 --- a/src/lib/krb5/krb/chk_trans.c +++ b/src/lib/krb5/krb/chk_trans.c @@ -56,13 +56,13 @@ krb5_data *realm2; return(retval); } - memset(prev, 0, MAX_REALM_LN + 1); - memset(next, 0, MAX_REALM_LN + 1), nextp = next; + memset(prev, 0, sizeof(prev)); + memset(next, 0, sizeof(next)), nextp = next; for (i = 0; i < trans_length; i++) { if (i < trans_length-1 && trans->data[i] == '\\') { i++; *nextp++ = trans->data[i]; - if (nextp - next > MAX_REALM_LN) { + if (nextp - next >= sizeof(next)) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto finish; } @@ -70,16 +70,17 @@ krb5_data *realm2; } if (i < trans_length && trans->data[i] != ',') { *nextp++ = trans->data[i]; - if (nextp - next > MAX_REALM_LN) { + if (nextp - next >= sizeof(next)) { retval = KRB5KRB_AP_ERR_ILL_CR_TKT; goto finish; } continue; } + next[sizeof(next) - 1] = '\0'; if (strlen(next) > 0) { if (next[0] != '/') { if (*(nextp-1) == '.' && strlen(next) + strlen(prev) <= MAX_REALM_LN) - strcat(next, prev); + strncat(next, prev, sizeof(next) - 1 - strlen(next)); retval = KRB5KRB_AP_ERR_ILL_CR_TKT; for (j = 0; tgs_list[j]; j++) { if (strlen(next) == (size_t) krb5_princ_realm(context, tgs_list[j])->length && @@ -93,12 +94,12 @@ krb5_data *realm2; } if (i+1 < trans_length && trans->data[i+1] == ' ') { i++; - memset(next, 0, MAX_REALM_LN + 1), nextp = next; + memset(next, 0, sizeof(next)), nextp = next; continue; } if (i+1 < trans_length && trans->data[i+1] != '/') { - strcpy(prev, next); - memset(next, 0, MAX_REALM_LN + 1), nextp = next; + strncpy(prev, next, sizeof(prev) - 1); + memset(next, 0, sizeof(next)), nextp = next; continue; } } diff --git a/src/lib/krb5/krb/conv_princ.c b/src/lib/krb5/krb/conv_princ.c index b90289a..1e141ca 100644 --- a/src/lib/krb5/krb/conv_princ.c +++ b/src/lib/krb5/krb/conv_princ.c @@ -137,7 +137,8 @@ krb5_524_conv_principal(context, princ, name, inst, realm) { const struct krb_convert *p; krb5_data *compo; - char *c; + char *c, *tmp_realm, *tmp_prealm; + int tmp_realm_len, retval; *name = *inst = '\0'; switch (krb5_princ_size(context, princ)) { @@ -147,18 +148,22 @@ krb5_524_conv_principal(context, princ, name, inst, realm) p = sconv_list; while (p->v4_str) { if (strncmp(p->v5_str, compo->data, compo->length) == 0) { - /* It is, so set the new name now, and chop off */ - /* instance's domain name if requested */ - strcpy(name, p->v4_str); - if (p->flags & DO_REALM_CONVERSION) { - compo = krb5_princ_component(context, princ, 1); - c = strnchr(compo->data, '.', compo->length); - if (!c || (c - compo->data) > INST_SZ - 1) - return KRB5_INVALID_PRINCIPAL; - strncpy(inst, compo->data, c - compo->data); - inst[c - compo->data] = '\0'; - } - break; + /* + * It is, so set the new name now, and chop off + * instance's domain name if requested. + */ + if (strlen (p->v4_str) > ANAME_SZ - 1) + return KRB5_INVALID_PRINCIPAL; + strcpy(name, p->v4_str); + if (p->flags & DO_REALM_CONVERSION) { + compo = krb5_princ_component(context, princ, 1); + c = strnchr(compo->data, '.', compo->length); + if (!c || (c - compo->data) >= INST_SZ - 1) + return KRB5_INVALID_PRINCIPAL; + memcpy(inst, compo->data, c - compo->data); + inst[c - compo->data] = '\0'; + } + break; } p++; } @@ -168,7 +173,7 @@ krb5_524_conv_principal(context, princ, name, inst, realm) compo = krb5_princ_component(context, princ, 1); if (compo->length >= INST_SZ - 1) return KRB5_INVALID_PRINCIPAL; - strncpy(inst, compo->data, compo->length); + memcpy(inst, compo->data, compo->length); inst[compo->length] = '\0'; } /* fall through */ @@ -178,7 +183,7 @@ krb5_524_conv_principal(context, princ, name, inst, realm) compo = krb5_princ_component(context, princ, 0); if (compo->length >= ANAME_SZ) return KRB5_INVALID_PRINCIPAL; - strncpy(name, compo->data, compo->length); + memcpy(name, compo->data, compo->length); name[compo->length] = '\0'; } break; @@ -187,11 +192,39 @@ krb5_524_conv_principal(context, princ, name, inst, realm) } compo = krb5_princ_realm(context, princ); - if (compo->length > REALM_SZ - 1) - return KRB5_INVALID_PRINCIPAL; - strncpy(realm, compo->data, compo->length); - realm[compo->length] = '\0'; + tmp_prealm = malloc(compo->length + 1); + if (tmp_prealm == NULL) + return ENOMEM; + strncpy(tmp_prealm, compo->data, compo->length); + tmp_prealm[compo->length] = '\0'; + + /* Ask for v4_realm corresponding to + krb5 principal realm from krb5.conf realms stanza */ + + if (context->profile == 0) + return KRB5_CONFIG_CANTOPEN; + retval = profile_get_string(context->profile, "realms", + tmp_prealm, "v4_realm", 0, + &tmp_realm); + free(tmp_prealm); + if (retval) { + return retval; + } else { + if (tmp_realm == 0) { + if (compo->length > REALM_SZ - 1) + return KRB5_INVALID_PRINCIPAL; + strncpy(realm, compo->data, compo->length); + realm[compo->length] = '\0'; + } else { + tmp_realm_len = strlen(tmp_realm); + if (tmp_realm_len > REALM_SZ - 1) + return KRB5_INVALID_PRINCIPAL; + strncpy(realm, tmp_realm, tmp_realm_len); + realm[tmp_realm_len] = '\0'; + profile_release_string(tmp_realm); + } + } return 0; } @@ -234,7 +267,8 @@ krb5_425_conv_principal(context, name, instance, realm, princ) if (retval == 0 && full_name && full_name[0]) { instance = full_name[0]; } else { - strcpy(buf, instance); + strncpy(buf, instance, sizeof(buf)); + buf[sizeof(buf) - 1] = '\0'; retval = krb5_get_realm_domain(context, realm, &domain); if (retval) return retval; @@ -242,8 +276,8 @@ krb5_425_conv_principal(context, name, instance, realm, princ) for (cp = domain; *cp; cp++) if (isupper(*cp)) *cp = tolower(*cp); - strcat(buf, "."); - strcat(buf, domain); + strncat(buf, ".", sizeof(buf) - 1 - strlen(buf)); + strncat(buf, domain, sizeof(buf) - 1 - strlen(buf)); krb5_xfree(domain); } instance = buf; diff --git a/src/lib/krb5/krb/fwd_tgt.c b/src/lib/krb5/krb/fwd_tgt.c index 814195a..769b20b 100644 --- a/src/lib/krb5/krb/fwd_tgt.c +++ b/src/lib/krb5/krb/fwd_tgt.c @@ -90,7 +90,7 @@ krb5_fwd_tgt_creds(context, auth_context, rhost, client, server, cc, goto errout; if (cc == 0) { - if ((retval = krb5_cc_default(context, &cc))) + if ((retval = krb5int_cc_default(context, &cc))) goto errout; close_cc = 1; } diff --git a/src/lib/krb5/krb/get_creds.c b/src/lib/krb5/krb/get_creds.c index 3bcaa0b..6d764d3 100644 --- a/src/lib/krb5/krb/get_creds.c +++ b/src/lib/krb5/krb/get_creds.c @@ -102,6 +102,7 @@ krb5_get_credentials(context, options, ccache, in_creds, out_creds) krb5_creds *ncreds; krb5_creds **tgts; krb5_flags fields; + int not_ktype; retval = krb5_get_credentials_core(context, options, ccache, in_creds, out_creds, @@ -128,6 +129,11 @@ krb5_get_credentials(context, options, ccache, in_creds, out_creds) || options & KRB5_GC_CACHED) return retval; + if (retval == KRB5_CC_NOT_KTYPE) + not_ktype = 1; + else + not_ktype = 0; + retval = krb5_get_cred_from_kdc(context, ccache, ncreds, out_creds, &tgts); if (tgts) { register int i = 0; @@ -141,6 +147,21 @@ krb5_get_credentials(context, options, ccache, in_creds, out_creds) } krb5_free_tgt_creds(context, tgts); } + /* + * Translate KRB5_CC_NOTFOUND if we previously got + * KRB5_CC_NOT_KTYPE from krb5_cc_retrieve_cred(), in order to + * handle the case where there is no TGT in the ccache and the + * input enctype didn't match. This handling is necessary because + * some callers, such as GSSAPI, iterate through enctypes and + * KRB5_CC_NOTFOUND passed through from the + * krb5_get_cred_from_kdc() is semantically incorrect, since the + * actual failure was the non-existence of a ticket of the correct + * enctype rather than the missing TGT. + */ + if ((retval == KRB5_CC_NOTFOUND || retval == KRB5_CC_NOT_KTYPE) + && not_ktype) + retval = KRB5_CC_NOT_KTYPE; + if (!retval) retval = krb5_cc_store_cred(context, ccache, *out_creds); return retval; diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c index c1c6df1..298f152 100644 --- a/src/lib/krb5/krb/get_in_tkt.c +++ b/src/lib/krb5/krb/get_in_tkt.c @@ -84,13 +84,13 @@ static krb5_error_code make_preauth_list PROTOTYPE((krb5_context, */ static krb5_error_code send_as_request(context, request, time_now, ret_err_reply, ret_as_reply, - master) + use_master) krb5_context context; krb5_kdc_req *request; krb5_timestamp *time_now; krb5_error ** ret_err_reply; krb5_kdc_rep ** ret_as_reply; - int * master; + int use_master; { krb5_kdc_rep *as_reply = 0; krb5_error_code retval; @@ -116,7 +116,7 @@ send_as_request(context, request, time_now, ret_err_reply, ret_as_reply, k4_version = packet->data[0]; retval = krb5_sendto_kdc(context, packet, krb5_princ_realm(context, request->client), - &reply, master); + &reply, use_master); krb5_free_data(context, packet); if (retval) goto cleanup; @@ -457,12 +457,35 @@ krb5_get_in_tkt(context, options, addrs, ktypes, ptypes, key_proc, keyseed, request.from = creds->times.starttime; request.till = creds->times.endtime; request.rtime = creds->times.renew_till; - if (ktypes) - request.ktype = ktypes; - else - if ((retval = krb5_get_default_in_tkt_ktypes(context, &request.ktype))) - goto cleanup; + if ((retval = krb5_get_default_in_tkt_ktypes(context, &request.ktype))) + goto cleanup; for (request.nktypes = 0;request.ktype[request.nktypes];request.nktypes++); + if (ktypes) { + int i, req, next = 0; + for (req = 0; ktypes[req]; req++) { + if (ktypes[req] == request.ktype[next]) { + next++; + continue; + } + for (i = next + 1; i < request.nktypes; i++) + if (ktypes[req] == request.ktype[i]) { + /* Found the enctype we want, but not in the + position we want. Move it, but keep the old + one from the desired slot around in case it's + later in our requested-ktypes list. */ + krb5_enctype t; + t = request.ktype[next]; + request.ktype[next] = request.ktype[i]; + request.ktype[i] = t; + next++; + break; + } + /* If we didn't find it, don't do anything special, just + drop it. */ + } + request.ktype[next] = 0; + request.nktypes = next; + } request.authorization_data.ciphertext.length = 0; request.authorization_data.ciphertext.data = 0; request.unenc_authdata = 0; @@ -538,7 +561,7 @@ krb5_get_in_tkt(context, options, addrs, ktypes, ptypes, key_proc, keyseed, goto cleanup; cleanup: - if (!ktypes && request.ktype) + if (request.ktype) free(request.ktype); if (!addrs && request.addresses) krb5_free_addresses(context, request.addresses); @@ -559,7 +582,7 @@ cleanup: return (retval); } -/* begin appdefaults parsing code. This should almost certainly move +/* begin libdefaults parsing code. This should almost certainly move somewhere else, but I don't know where the correct somewhere else is yet. */ @@ -595,7 +618,7 @@ _krb5_conf_boolean(s) } static krb5_error_code -krb5_appdefault_string(context, realm, option, ret_value) +krb5_libdefault_string(context, realm, option, ret_value) krb5_context context; const krb5_data *realm; const char *option; @@ -673,7 +696,7 @@ goodbye: /* as well as the DNS code */ krb5_error_code -krb5_appdefault_boolean(context, realm, option, ret_value) +krb5_libdefault_boolean(context, realm, option, ret_value) krb5_context context; const char *option; const krb5_data *realm; @@ -682,7 +705,7 @@ krb5_appdefault_boolean(context, realm, option, ret_value) char *string = NULL; krb5_error_code retval; - retval = krb5_appdefault_string(context, realm, option, &string); + retval = krb5_libdefault_string(context, realm, option, &string); if (retval) return(retval); @@ -696,7 +719,7 @@ krb5_appdefault_boolean(context, realm, option, ret_value) KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_init_creds(context, creds, client, prompter, prompter_data, start_time, in_tkt_service, options, gak_fct, gak_data, - master, as_reply) + use_master, as_reply) krb5_context context; krb5_creds *creds; krb5_principal client; @@ -707,7 +730,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, krb5_get_init_creds_opt *options; krb5_gic_get_as_key_fct gak_fct; void *gak_data; - int *master; + int use_master; krb5_kdc_rep **as_reply; { krb5_error_code ret; @@ -751,7 +774,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE)) tempint = options->forwardable; - else if ((ret = krb5_appdefault_boolean(context, &client->realm, + else if ((ret = krb5_libdefault_boolean(context, &client->realm, "forwardable", &tempint)) == 0) ; else @@ -763,7 +786,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE)) tempint = options->proxiable; - else if ((ret = krb5_appdefault_boolean(context, &client->realm, + else if ((ret = krb5_libdefault_boolean(context, &client->realm, "proxiable", &tempint)) == 0) ; else @@ -775,7 +798,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, if (options && (options->flags & KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE)) { renew_life = options->renew_life; - } else if ((ret = krb5_appdefault_string(context, &client->realm, + } else if ((ret = krb5_libdefault_string(context, &client->realm, "renew_lifetime", &tempstr)) == 0) { if (ret = krb5_string_to_deltat(tempstr, &renew_life)) { @@ -868,7 +891,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, } /* it would be nice if this parsed out an address list, but that would be work. */ - else if (((ret = krb5_appdefault_boolean(context, &client->realm, + else if (((ret = krb5_libdefault_boolean(context, &client->realm, "noaddresses", &tempint)) == 0) && tempint) { ; @@ -923,7 +946,7 @@ krb5_get_init_creds(context, creds, client, prompter, prompter_data, err_reply = 0; local_as_reply = 0; if ((ret = send_as_request(context, &request, &time_now, &err_reply, - &local_as_reply, master))) + &local_as_reply, use_master))) goto cleanup; if (err_reply) { diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c index 8b6f231..98bbbd0 100644 --- a/src/lib/krb5/krb/gic_keytab.c +++ b/src/lib/krb5/krb/gic_keytab.c @@ -61,7 +61,7 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab, krb5_get_init_creds_opt *options; { krb5_error_code ret, ret2; - int master; + int use_master; krb5_keytab keytab; if (arg_keytab == NULL) { @@ -71,14 +71,14 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab, keytab = arg_keytab; } - master = 0; + use_master = 0; /* first try: get the requested tkt from any kdc */ ret = krb5_get_init_creds(context, creds, client, NULL, NULL, start_time, in_tkt_service, options, krb5_get_as_key_keytab, (void *) keytab, - &master, NULL); + use_master,NULL); /* check for success */ @@ -87,19 +87,19 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab, /* If all the kdc's are unavailable fail */ - if (ret == KRB5_KDC_UNREACH) + if ((ret == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE)) goto cleanup; /* if the reply did not come from the master kdc, try again with the master kdc */ - if (!master) { - master = 1; + if (!use_master) { + use_master = 1; ret2 = krb5_get_init_creds(context, creds, client, NULL, NULL, start_time, in_tkt_service, options, krb5_get_as_key_keytab, (void *) keytab, - &master, NULL); + use_master, NULL); if (ret2 == 0) { ret = 0; @@ -109,7 +109,7 @@ krb5_get_init_creds_keytab(context, creds, client, arg_keytab, /* if the master is unreachable, return the error from the slave we were able to contact */ - if (ret2 == KRB5_KDC_UNREACH) + if ((ret2 == KRB5_KDC_UNREACH) || (ret == KRB5_REALM_CANT_RESOLVE)) goto cleanup; ret = ret2; diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c index 7ca4343..eeb3f03 100644 --- a/src/lib/krb5/krb/gic_pwd.c +++ b/src/lib/krb5/krb/gic_pwd.c @@ -97,7 +97,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, krb5_get_init_creds_opt *options; { krb5_error_code ret, ret2; - int master; + int use_master; krb5_kdc_rep *as_reply; int tries; krb5_creds chpw_creds; @@ -107,7 +107,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, krb5_prompt prompt[2]; krb5_prompt_type prompt_types[sizeof(prompt)/sizeof(prompt[0])]; - master = 0; + use_master = 0; as_reply = NULL; memset(&chpw_creds, 0, sizeof(chpw_creds)); @@ -133,7 +133,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, ret = krb5_get_init_creds(context, creds, client, prompter, data, start_time, in_tkt_service, options, krb5_get_as_key_password, (void *) &pw0, - &master, &as_reply); + use_master, &as_reply); /* check for success */ @@ -144,19 +144,20 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, user interrupt, fail */ if ((ret == KRB5_KDC_UNREACH) || - (ret == KRB5_LIBOS_PWDINTR)) + (ret == KRB5_LIBOS_PWDINTR) || + (ret == KRB5_REALM_CANT_RESOLVE)) goto cleanup; /* if the reply did not come from the master kdc, try again with the master kdc */ - if (!master) { - master = 1; + if (!use_master) { + use_master = 1; ret2 = krb5_get_init_creds(context, creds, client, prompter, data, start_time, in_tkt_service, options, krb5_get_as_key_password, (void *) &pw0, - &master, &as_reply); + use_master, &as_reply); if (ret2 == 0) { ret = 0; @@ -166,12 +167,18 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, /* if the master is unreachable, return the error from the slave we were able to contact */ - if (ret2 == KRB5_KDC_UNREACH) + if ((ret2 == KRB5_KDC_UNREACH) || + (ret2 == KRB5_REALM_CANT_RESOLVE)) goto cleanup; ret = ret2; } +#ifdef USE_LOGIN_LIBRARY + if (ret == KRB5KDC_ERR_KEY_EXP) + goto cleanup; /* Login library will deal appropriately with this error */ +#endif + /* at this point, we have an error from the master. if the error is not password expired, or if it is but there's no prompter, return this error */ @@ -195,7 +202,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, prompter, data, start_time, "kadmin/changepw", &chpw_opts, krb5_get_as_key_password, (void *) &pw0, - &master, NULL))) + use_master, NULL))) goto cleanup; prompt[0].prompt = "Enter new password"; @@ -282,7 +289,7 @@ krb5_get_init_creds_password(context, creds, client, password, prompter, data, ret = krb5_get_init_creds(context, creds, client, prompter, data, start_time, in_tkt_service, options, krb5_get_as_key_password, (void *) &pw0, - &master, &as_reply); + use_master, &as_reply); cleanup: krb5int_set_prompt_types(context, 0); diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c index e2eccc4..c10c6f7 100644 --- a/src/lib/krb5/krb/init_ctx.c +++ b/src/lib/krb5/krb/init_ctx.c @@ -1,7 +1,7 @@ /* * lib/krb5/krb/init_ctx.c * - * Copyright 1994 by the Massachusetts Institute of Technology. + * Copyright 1994,1999,2000 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -84,7 +84,10 @@ init_common (context, secure) { krb5_context ctx = 0; krb5_error_code retval; - krb5_timestamp now; + struct { + krb5_int32 now, now_usec; + long pid; + } seed_data; krb5_data seed; int tmp; @@ -129,10 +132,11 @@ init_common (context, secure) goto cleanup; /* initialize the prng (not well, but passable) */ - if ((retval = krb5_timeofday(ctx, &now))) + if ((retval = krb5_crypto_us_timeofday(&seed_data.now, &seed_data.now_usec))) goto cleanup; - seed.length = sizeof(now); - seed.data = (char *) &now; + seed_data.pid = getpid (); + seed.length = sizeof(seed_data); + seed.data = (char *) &seed_data; if ((retval = krb5_c_random_seed(ctx, &seed))) goto cleanup; @@ -281,7 +285,7 @@ get_profile_etype_list(context, ktypes, profstr, ctx_count, ctx_list) { krb5_enctype *old_ktypes; - if (context->in_tkt_ktype_count) { + if (ctx_count) { /* application-set defaults */ if ((old_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * @@ -396,13 +400,23 @@ krb5_set_default_tgs_ktypes(context, ktypes) } if (context->tgs_ktypes) - free(context->tgs_ktypes); + krb5_free_ktypes(context, context->tgs_ktypes); context->tgs_ktypes = new_ktypes; context->tgs_ktype_count = i; return 0; } +void +KRB5_CALLCONV +krb5_free_ktypes (context, val) + krb5_context context; + krb5_enctype FAR *val; +{ + free (val); +} + krb5_error_code +KRB5_CALLCONV krb5_get_tgs_ktypes(context, princ, ktypes) krb5_context context; krb5_const_principal princ; @@ -441,7 +455,7 @@ krb5_is_permitted_enctype(context, etype) if (*ptr == etype) ret = 1; - krb5_xfree(list); + krb5_free_ktypes (context, list); return(ret); } diff --git a/src/lib/krb5/krb/kfree.c b/src/lib/krb5/krb/kfree.c index 24d8aaf..8e57f83 100644 --- a/src/lib/krb5/krb/kfree.c +++ b/src/lib/krb5/krb/kfree.c @@ -36,7 +36,6 @@ krb5_free_address(context, val) if (val->contents) krb5_xfree(val->contents); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -52,7 +51,6 @@ krb5_free_addresses(context, val) krb5_xfree(*temp); } krb5_xfree(val); - return; } @@ -64,7 +62,6 @@ krb5_free_ap_rep(context, val) if (val->enc_part.ciphertext.data) krb5_xfree(val->enc_part.ciphertext.data); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -77,7 +74,6 @@ krb5_free_ap_req(context, val) if (val->authenticator.ciphertext.data) krb5_xfree(val->authenticator.ciphertext.data); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -88,7 +84,6 @@ krb5_free_ap_rep_enc_part(context, val) if (val->subkey) krb5_free_keyblock(context, val->subkey); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -96,15 +91,22 @@ krb5_free_authenticator_contents(context, val) krb5_context context; krb5_authenticator FAR *val; { - if (val->checksum) + if (val->checksum) { krb5_free_checksum(context, val->checksum); - if (val->client) + val->checksum = 0; + } + if (val->client) { krb5_free_principal(context, val->client); - if (val->subkey) + val->client = 0; + } + if (val->subkey) { krb5_free_keyblock(context, val->subkey); - if (val->authorization_data) - krb5_free_authdata(context, val->authorization_data); - return; + val->subkey = 0; + } + if (val->authorization_data) { + krb5_free_authdata(context, val->authorization_data); + val->authorization_data = 0; + } } KRB5_DLLIMP void KRB5_CALLCONV @@ -120,7 +122,6 @@ krb5_free_authdata(context, val) krb5_xfree(*temp); } krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -128,16 +129,8 @@ krb5_free_authenticator(context, val) krb5_context context; krb5_authenticator FAR *val; { - if (val->checksum) - krb5_free_checksum(context, val->checksum); - if (val->client) - krb5_free_principal(context, val->client); - if (val->subkey) - krb5_free_keyblock(context, val->subkey); - if (val->authorization_data) - krb5_free_authdata(context, val->authorization_data); + krb5_free_authenticator_contents(context, val); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -145,10 +138,8 @@ krb5_free_checksum(context, val) krb5_context context; register krb5_checksum *val; { - if (val->contents) - krb5_xfree(val->contents); + krb5_free_checksum_contents(context, val); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -156,9 +147,10 @@ krb5_free_checksum_contents(context, val) krb5_context context; register krb5_checksum *val; { - if (val->contents) + if (val->contents) { krb5_xfree(val->contents); - return; + val->contents = 0; + } } KRB5_DLLIMP void KRB5_CALLCONV @@ -171,7 +163,6 @@ krb5_free_cred(context, val) if (val->enc_part.ciphertext.data) krb5_xfree(val->enc_part.ciphertext.data); krb5_xfree(val); - return; } /* @@ -184,23 +175,35 @@ krb5_free_cred_contents(context, val) krb5_context context; krb5_creds FAR *val; { - if (val->client) + if (val->client) { krb5_free_principal(context, val->client); - if (val->server) + val->client = 0; + } + if (val->server) { krb5_free_principal(context, val->server); + val->server = 0; + } if (val->keyblock.contents) { memset((char *)val->keyblock.contents, 0, val->keyblock.length); krb5_xfree(val->keyblock.contents); + val->keyblock.contents = 0; } - if (val->ticket.data) + if (val->ticket.data) { krb5_xfree(val->ticket.data); - if (val->second_ticket.data) + val->ticket.data = 0; + } + if (val->second_ticket.data) { krb5_xfree(val->second_ticket.data); - if (val->addresses) + val->second_ticket.data = 0; + } + if (val->addresses) { krb5_free_addresses(context, val->addresses); - if (val->authdata) + val->addresses = 0; + } + if (val->authdata) { krb5_free_authdata(context, val->authdata); - return; + val->authdata = 0; + } } KRB5_DLLIMP void KRB5_CALLCONV @@ -210,10 +213,14 @@ krb5_free_cred_enc_part(context, val) { register krb5_cred_info **temp; - if (val->r_address) - krb5_free_address(context, val->r_address); - if (val->s_address) - krb5_free_address(context, val->s_address); + if (val->r_address) { + krb5_free_address(context, val->r_address); + val->r_address = 0; + } + if (val->s_address) { + krb5_free_address(context, val->s_address); + val->s_address = 0; + } if (val->ticket_info) { for (temp = val->ticket_info; *temp; temp++) { @@ -228,8 +235,8 @@ krb5_free_cred_enc_part(context, val) krb5_xfree((*temp)); } krb5_xfree(val->ticket_info); + val->ticket_info = 0; } - return; } @@ -240,7 +247,6 @@ krb5_free_creds(context, val) { krb5_free_cred_contents(context, val); krb5_xfree(val); - return; } @@ -252,7 +258,6 @@ krb5_free_data(context, val) if (val->data) krb5_xfree(val->data); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -260,9 +265,10 @@ krb5_free_data_contents(context, val) krb5_context context; krb5_data FAR * val; { - if (val->data) + if (val->data) { krb5_xfree(val->data); - return; + val->data = 0; + } } void krb5_free_etype_info(context, info) @@ -294,7 +300,6 @@ krb5_free_enc_kdc_rep_part(context, val) if (val->caddrs) krb5_free_addresses(context, val->caddrs); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -313,7 +318,6 @@ krb5_free_enc_tkt_part(context, val) if (val->authorization_data) krb5_free_authdata(context, val->authorization_data); krb5_xfree(val); - return; } @@ -331,7 +335,6 @@ krb5_free_error(context, val) if (val->e_data.data) krb5_xfree(val->e_data.data); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -350,7 +353,6 @@ krb5_free_kdc_rep(context, val) if (val->enc_part2) krb5_free_enc_kdc_rep_part(context, val->enc_part2); krb5_xfree(val); - return; } @@ -376,7 +378,6 @@ krb5_free_kdc_req(context, val) if (val->second_ticket) krb5_free_tickets(context, val->second_ticket); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -387,8 +388,8 @@ krb5_free_keyblock_contents(context, key) if (key->contents) { memset(key->contents, 0, key->length); krb5_xfree(key->contents); + key->contents = 0; } - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -398,7 +399,6 @@ krb5_free_keyblock(context, val) { krb5_free_keyblock_contents(context, val); krb5_xfree(val); - return; } @@ -413,7 +413,6 @@ krb5_free_last_req(context, val) for (temp = val; *temp; temp++) krb5_xfree(*temp); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -429,7 +428,6 @@ krb5_free_pa_data(context, val) krb5_xfree(*temp); } krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -451,7 +449,6 @@ krb5_free_principal(context, val) if (val->realm.data) krb5_xfree(val->realm.data); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -462,7 +459,6 @@ krb5_free_priv(context, val) if (val->enc_part.ciphertext.data) krb5_xfree(val->enc_part.ciphertext.data); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -477,7 +473,6 @@ krb5_free_priv_enc_part(context, val) if (val->s_address) krb5_free_address(context, val->s_address); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -488,7 +483,6 @@ krb5_free_pwd_data(context, val) if (val->element) krb5_free_pwd_sequences(context, val->element); krb5_xfree(val); - return; } @@ -497,11 +491,14 @@ krb5_free_pwd_sequences(context, val) krb5_context context; passwd_phrase_element FAR * FAR *val; { - if ((*val)->passwd) + if ((*val)->passwd) { krb5_xfree((*val)->passwd); - if ((*val)->phrase) + (*val)->passwd = 0; + } + if ((*val)->phrase) { krb5_xfree((*val)->phrase); - return; + (*val)->phrase = 0; + } } @@ -519,7 +516,6 @@ krb5_free_safe(context, val) if (val->checksum) krb5_free_checksum(context, val->checksum); krb5_xfree(val); - return; } @@ -535,7 +531,6 @@ krb5_free_ticket(context, val) if (val->enc_part2) krb5_free_enc_tkt_part(context, val->enc_part2); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -548,7 +543,6 @@ krb5_free_tickets(context, val) for (temp = val; *temp; temp++) krb5_free_ticket(context, *temp); krb5_xfree(val); - return; } @@ -573,7 +567,6 @@ krb5_free_tkt_authent(context, val) if (val->authenticator) krb5_free_authenticator(context, val->authenticator); krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -583,7 +576,6 @@ krb5_free_unparsed_name(context, val) { if (val) krb5_xfree(val); - return; } KRB5_DLLIMP void KRB5_CALLCONV @@ -612,8 +604,10 @@ krb5_free_sam_challenge_contents(krb5_context ctx, krb5_sam_challenge FAR *sc) krb5_free_data_contents(ctx, &sc->sam_response_prompt); if (sc->sam_pk_for_sad.data) krb5_free_data_contents(ctx, &sc->sam_pk_for_sad); - if (sc->sam_cksum.contents) + if (sc->sam_cksum.contents) { krb5_xfree(sc->sam_cksum.contents); + sc->sam_cksum.contents = 0; + } } KRB5_DLLIMP void KRB5_CALLCONV @@ -656,8 +650,10 @@ krb5_free_predicted_sam_response_contents(krb5_context ctx, return; if (psr->sam_key.contents) krb5_free_keyblock_contents(ctx, &psr->sam_key); - if (psr->client) + if (psr->client) { krb5_free_principal(ctx, psr->client); + psr->client = 0; + } if (psr->msd.data) krb5_free_data_contents(ctx, &psr->msd); } @@ -689,4 +685,3 @@ krb5_free_pa_enc_ts(krb5_context ctx, krb5_pa_enc_ts FAR *pa_enc_ts) return; krb5_xfree(pa_enc_ts); } - diff --git a/src/lib/krb5/krb/mk_priv.c b/src/lib/krb5/krb/mk_priv.c index 7685817..d72f6b2 100644 --- a/src/lib/krb5/krb/mk_priv.c +++ b/src/lib/krb5/krb/mk_priv.c @@ -93,14 +93,6 @@ krb5_mk_priv_basic(context, userdata, keyblock, replaydata, local_addr, scratch1, &privmsg.enc_part))) goto clean_encpart; - /* put last block into the i_vector */ - - if (i_vector) - memcpy(i_vector, - privmsg.enc_part.ciphertext.data + - (privmsg.enc_part.ciphertext.length - blocksize), - blocksize); - if ((retval = encode_krb5_priv(&privmsg, &scratch2))) goto clean_encpart; diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c index a8b20eb..88daab5 100644 --- a/src/lib/krb5/krb/mk_req_ext.c +++ b/src/lib/krb5/krb/mk_req_ext.c @@ -126,10 +126,24 @@ krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds, /* generate subkey if needed */ - if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey)) + if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey)) { + /* Provide some more fodder for random number code. + This isn't strong cryptographically; the point here is not + to guarantee randomness, but to make it less likely that multiple + sessions could pick the same subkey. */ + struct { + krb5_int32 sec, usec; + } rnd_data; + krb5_data d; + krb5_crypto_us_timeofday (&rnd_data.sec, &rnd_data.usec); + d.length = sizeof (rnd_data); + d.data = (char *) &rnd_data; + (void) krb5_c_random_seed (context, &d); + if ((retval = krb5_generate_subkey(context, &(in_creds)->keyblock, &(*auth_context)->local_subkey))) goto cleanup; + } if (in_data) { if ((*auth_context)->req_cksumtype == 0x8003) { diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c index 9629b0c..ab6a531 100644 --- a/src/lib/krb5/krb/rd_priv.c +++ b/src/lib/krb5/krb/rd_priv.c @@ -101,13 +101,6 @@ krb5_rd_priv_basic(context, inbuf, keyblock, local_addr, remote_addr, &privmsg->enc_part, &scratch))) goto cleanup_scratch; - /* if i_vector is set, put last block into the i_vector */ - if (i_vector) - memcpy(i_vector, - privmsg->enc_part.ciphertext.data + - (privmsg->enc_part.ciphertext.length - blocksize), - blocksize); - /* now decode the decrypted stuff */ if ((retval = decode_krb5_enc_priv_part(&scratch, &privmsg_enc_part))) goto cleanup_scratch; diff --git a/src/lib/krb5/krb/recvauth.c b/src/lib/krb5/krb/recvauth.c index 3d5bce4..f74041c 100644 --- a/src/lib/krb5/krb/recvauth.c +++ b/src/lib/krb5/krb/recvauth.c @@ -37,20 +37,18 @@ static char *sendauth_version = "KRB5_SENDAUTH_V1.0"; -KRB5_DLLIMP krb5_error_code KRB5_CALLCONV -krb5_recvauth(context, auth_context, - /* IN */ - fd, appl_version, server, flags, keytab, - /* OUT */ - ticket) - krb5_context context; - krb5_auth_context FAR * auth_context; - krb5_pointer fd; - char FAR * appl_version; - krb5_principal server; - krb5_int32 flags; - krb5_keytab keytab; - krb5_ticket FAR * FAR * ticket; +krb5_error_code +recvauth_common(krb5_context context, + krb5_auth_context FAR * auth_context, + /* IN */ + krb5_pointer fd, + char FAR *appl_version, + krb5_principal server, + krb5_int32 flags, + krb5_keytab keytab, + /* OUT */ + krb5_ticket FAR * FAR * ticket, + krb5_data FAR *version) { krb5_auth_context new_auth_context; krb5_flags ap_option; @@ -91,12 +89,15 @@ krb5_recvauth(context, auth_context, */ if ((retval = krb5_read_message(context, fd, &inbuf))) return(retval); - if (strcmp(inbuf.data, appl_version)) { + if (appl_version && strcmp(inbuf.data, appl_version)) { krb5_xfree(inbuf.data); if (!problem) problem = KRB5_SENDAUTH_BADAPPLVERS; } - krb5_xfree(inbuf.data); + if (version && !problem) + *version = inbuf; + else + krb5_xfree(inbuf.data); /* * OK, now check the problem variable. If it's zero, we're * fine and we can continue. Otherwise, we have to signal an @@ -243,3 +244,38 @@ cleanup:; } return retval; } + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_recvauth(context, auth_context, + /* IN */ + fd, appl_version, server, flags, keytab, + /* OUT */ + ticket) + krb5_context context; + krb5_auth_context FAR * auth_context; + krb5_pointer fd; + char FAR * appl_version; + krb5_principal server; + krb5_int32 flags; + krb5_keytab keytab; + krb5_ticket FAR * FAR * ticket; +{ + return recvauth_common (context, auth_context, fd, appl_version, + server, flags, keytab, ticket, 0); +} + +KRB5_DLLIMP krb5_error_code KRB5_CALLCONV +krb5_recvauth_version(krb5_context context, + krb5_auth_context FAR *auth_context, + /* IN */ + krb5_pointer fd, + krb5_principal server, + krb5_int32 flags, + krb5_keytab keytab, + /* OUT */ + krb5_ticket FAR * FAR *ticket, + krb5_data FAR *version) +{ + return recvauth_common (context, auth_context, fd, 0, + server, flags, keytab, ticket, version); +} diff --git a/src/lib/krb5/krb/sendauth.c b/src/lib/krb5/krb/sendauth.c index 4e7c3a7..b19afdb 100644 --- a/src/lib/krb5/krb/sendauth.c +++ b/src/lib/krb5/krb/sendauth.c @@ -119,7 +119,7 @@ krb5_sendauth(context, auth_context, if (!in_creds || !in_creds->ticket.length) { if (ccache) use_ccache = ccache; - else if ((retval = krb5_cc_default(context, &use_ccache))) + else if ((retval = krb5int_cc_default(context, &use_ccache))) goto error_return; } if (!in_creds) { @@ -152,9 +152,32 @@ krb5_sendauth(context, auth_context, credsp = in_creds; } - if ((retval = krb5_mk_req_extended(context, auth_context, ap_req_options, - in_data, credsp, &outbuf))) - goto error_return; + if (ap_req_options & AP_OPTS_USE_SUBKEY) { + /* Provide some more fodder for random number code. + This isn't strong cryptographically; the point here is + not to guarantee randomness, but to make it less likely + that multiple sessions could pick the same subkey. */ + char rnd_data[1024]; + size_t len; + krb5_data d; + d.length = sizeof (rnd_data); + d.data = rnd_data; + len = sizeof (rnd_data); + if (getpeername (*(int*)fd, (struct sockaddr *) rnd_data, &len) == 0) { + d.length = len; + (void) krb5_c_random_seed (context, &d); + } + len = sizeof (rnd_data); + if (getsockname (*(int*)fd, (struct sockaddr *) rnd_data, &len) == 0) { + d.length = len; + (void) krb5_c_random_seed (context, &d); + } + } + + if ((retval = krb5_mk_req_extended(context, auth_context, + ap_req_options, in_data, credsp, + &outbuf))) + goto error_return; /* * First write the length of the AP_REQ message, then write diff --git a/src/lib/krb5/krb/t_kerb.c b/src/lib/krb5/krb/t_kerb.c index 2feef39..458015d 100644 --- a/src/lib/krb5/krb/t_kerb.c +++ b/src/lib/krb5/krb/t_kerb.c @@ -4,6 +4,7 @@ */ #include "krb5.h" +#include "kerberosIV/krb.h" #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -56,6 +57,32 @@ void test_425_conv_principal(ctx, name, inst, realm) krb5_free_principal(ctx, princ); } +void test_524_conv_principal(ctx, name) + krb5_context ctx; + char *name; +{ + krb5_principal princ = 0; + krb5_error_code retval; + char aname[ANAME_SZ+1], inst[INST_SZ+1], realm[REALM_SZ+1]; + + aname[ANAME_SZ] = inst[INST_SZ] = realm[REALM_SZ] = 0; + retval = krb5_parse_name(ctx, name, &princ); + if (retval) { + com_err("krb5_parse_name", retval, 0); + goto fail; + } + retval = krb5_524_conv_principal(ctx, princ, aname, inst, realm); + if (retval) { + com_err("krb5_524_conv_principal", retval, 0); + goto fail; + } + printf("524_converted_principal(%s): '%s' '%s' '%s'\n", + name, aname, inst, realm); + fail: + if (princ) + krb5_free_principal (ctx, princ); +} + void test_parse_name(ctx, name) krb5_context ctx; const char *name; @@ -131,6 +158,7 @@ void usage(progname) { fprintf(stderr, "%s: Usage: %s 425_conv_principal <name> <inst> <realm\n", progname, progname); + fprintf(stderr, "\t%s 524_conv_principal <name>\n", progname); fprintf(stderr, "\t%s parse_name <name>\n", progname); fprintf(stderr, "\t%s set_realm <name> <realm>\n", progname); fprintf(stderr, "\t%s string_to_timestamp <time>\n", progname); @@ -186,6 +214,10 @@ main(argc, argv) argc--; argv++; if (!argc) usage(progname); test_string_to_timestamp(ctx, *argv); + } else if (strcmp(*argv, "524_conv_principal") == 0) { + argc--; argv++; + if (!argc) usage(progname); + test_524_conv_principal(ctx, *argv); } else usage(progname); diff --git a/src/lib/krb5/krb/t_krb5.conf b/src/lib/krb5/krb/t_krb5.conf index 5882d97..8d7a4d9 100644 --- a/src/lib/krb5/krb/t_krb5.conf +++ b/src/lib/krb5/krb/t_krb5.conf @@ -19,6 +19,12 @@ kdc = KERBEROS.CYGNUS.COM admin_server = KERBEROS.MIT.EDU } + stanford.edu = { + v4_realm = IR.STANFORD.EDU + } + LONGNAMES.COM = { + v4_realm = SOME-REALLY-LONG-REALM-NAME-V4-CANNOT-HANDLE.COM + } [domain_realm] .mit.edu = ATHENA.MIT.EDU diff --git a/src/lib/krb5/krb/t_ref_kerb.out b/src/lib/krb5/krb/t_ref_kerb.out index 9423944..08a5334 100644 --- a/src/lib/krb5/krb/t_ref_kerb.out +++ b/src/lib/krb5/krb/t_ref_kerb.out @@ -14,4 +14,6 @@ parsed (and unparsed) principal(\/slash/\@atsign/octa\/thorpe@\/slash\@at\/sign) 425_converted principal(rcmd, uunet, UU.NET): 'host/uunet.uu.net@UU.NET' 425_converted principal(zephyr, zephyr, ATHENA.MIT.EDU): 'zephyr/zephyr@ATHENA.MIT.EDU' 425_converted principal(kadmin, ATHENA.MIT.EDU, ATHENA.MIT.EDU): 'kadmin/ATHENA.MIT.EDU@ATHENA.MIT.EDU' +524_converted_principal(host/e40-po.mit.edu@ATHENA.MIT.EDU): 'rcmd' 'e40-po' 'ATHENA.MIT.EDU' +524_converted_principal(host/foobar.stanford.edu@stanford.edu): 'rcmd' 'foobar' 'IR.STANFORD.EDU' old principal: marc@MIT.EDU, modified principal: marc@CYGNUS.COM diff --git a/src/lib/krb5/krb/vfy_increds.c b/src/lib/krb5/krb/vfy_increds.c index 85a8465..f046ab5 100644 --- a/src/lib/krb5/krb/vfy_increds.c +++ b/src/lib/krb5/krb/vfy_increds.c @@ -109,7 +109,7 @@ krb5_verify_init_creds(krb5_context context, (options->flags & KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL)) { if (options->ap_req_nofail) goto cleanup; - } else if ((ret2 = krb5_appdefault_boolean(context, + } else if ((ret2 = krb5_libdefault_boolean(context, &creds->client->realm, "verify_ap_req_nofail", &nofail)) diff --git a/src/lib/krb5/os/ChangeLog b/src/lib/krb5/os/ChangeLog index 8f8c018..b42547c 100644 --- a/src/lib/krb5/os/ChangeLog +++ b/src/lib/krb5/os/ChangeLog @@ -1,3 +1,78 @@ +2000-06-09 Miro Jurisic <meeroh@mit.edu> + + * init_os_ctx.c (os_get_default_config_files): + Eliminated some dead code + +2000-06-09 Miro Jurisic <meeroh@mit.edu> + + * init_os_ctx.c (os_get_default_config_files): Use Kerberos + Preferences library to locate the config files on Mac OS + +2000-05-17 Nalin Dahyabhai <nalin@redhat.com> + + * an_to_ln.c (do_replacement): Don't overflow buffers "in" or "out". + * hst_realm.c (krb5_try_realm_txt_rr): Don't overfill "host" when + malformed DNS responses are received. + +2000-05-15 Jeffrey Altman <jaltman@columbia.edu> + + * hst_realm.c (krb5_get_host_realm) + remove the searchlist and defaultrealm _kerberos queries + +2000-05-09 Alexandra Ellwood <lxs@mit.edu> + + *localaddr.c: Fixed the local_addr_fallback_kludge so that it actually does something. + Before that the error code it was handling was blowing it away in cleanup. + +2000-04-28 Nalin Dahyabhai <nalin@redhat.com> + + * ccdefname.c (get_from_os): Don't overflow buffer "name_buf". + * kuserok.c (krb5_kuserok): Don't overflow buffer "pbuf". + +2000-04-22 Ken Raeburn <raeburn@mit.edu> + + * localaddr.c: Include stddef.h. + (foreach_localaddr): Check each address against previously used + addresses, and skip duplicates, in case multiple interfaces have + the same address. If called functions fail, drop out of loop and + return nonzero. + (krb5_os_localaddr): Increment count of addresses to include null + pointer terminator. Delete check for zero count. + +2000-04-18 Danilo Almeida <dalmeida@mit.edu> + + * prompter.c (krb5int_set_prompt_types): Set to actual value + intead of 0. + +2000-4-13 Alexandra Ellwood <lxs@mit.edu> + + * init_os_ctx.c: Added support to store a krb5_principal in the os_context + along with the default ccache name (if known, this principal is the same + as the last time we looked at the ccache. + * ccdefname.c: Added support to store a krb5_principal in the os_context + along with the default ccache name (if known, this principal is the same + as the last time we looked at the ccache. + +2000-04-04 Ken Raeburn <raeburn@mit.edu> + + * locate_kdc.c (maybe_use_dns): Renamed from _krb5_use_dns. Now + takes an arg to indicate a key to look up in krb5.conf, falling + back to "dns_fallback", and an arg indicating the default value if + no config file entries match. + (_krb5_use_dns_realm): New routine; use "dns_lookup_realm" and + KRB5_DNS_LOOKUP_REALM setting. + (_krb5_use_dns_kdc): New routine; use "dns_lookup_kdc" and + KRB5_DNS_LOOKUP_KDC. + (krb5_locate_kdc): Call _krb5_use_dns_kdc. + * changepw.c (krb5_locate_kpasswd): Call _krb5_use_dns_kdc. + * def_realm.c (krb5_get_default_realm): Call _krb5_use_dns_realm. + * hst_realm.c (krb5_get_host_realm): Call _krb5_use_dns_realm. + +2000-03-20 Miro Jurisic <meeroh@mit.edu> + + * def_realm.c (krb5_free_default_realm): Added, use to free + result of krb5_get_default_realm + 2000-03-15 Danilo Almeida <dalmeida@mit.edu> * prompter.c: Add krb5int_set_prompt_types() and diff --git a/src/lib/krb5/os/an_to_ln.c b/src/lib/krb5/os/an_to_ln.c index 3c721fb..02e68fb 100644 --- a/src/lib/krb5/os/an_to_ln.c +++ b/src/lib/krb5/os/an_to_ln.c @@ -298,15 +298,15 @@ do_replacement(regexp, repl, doall, in, out) strncpy(op, cp, match_match.rm_so); op += match_match.rm_so; } - strcpy(op, repl); - op += strlen(repl); + strncpy(op, repl, MAX_FORMAT_BUFFER - 1 - (op - out)); + op += strlen(op); cp += match_match.rm_eo; if (!doall) - strcpy(op, cp); + strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out)); matched = 1; } else { - strcpy(op, cp); + strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out)); matched = 0; } } while (doall && matched); @@ -333,20 +333,20 @@ do_replacement(regexp, repl, doall, in, out) strncpy(op, cp, sdispl); op += sdispl; } - strcpy(op, repl); + strncpy(op, repl, MAX_FORMAT_BUFFER - 1 - (op - out)); op += strlen(repl); cp += edispl; if (!doall) - strcpy(op, cp); + strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out)); matched = 1; } else { - strcpy(op, cp); + strncpy(op, cp, MAX_FORMAT_BUFFER - 1 - (op - out)); matched = 0; } } while (doall && matched); #else /* HAVE_REGEXP_H */ - strcpy(out, in); + memcpy(out, in, MAX_FORMAT_BUFFER); #endif /* HAVE_REGCOMP */ } @@ -379,7 +379,8 @@ aname_replacer(string, contextp, result) * Prime the buffers. Copy input string to "out" to simulate it * being the result of an initial iteration. */ - strcpy(out, string); + strncpy(out, string, MAX_FORMAT_BUFFER - 1); + out[MAX_FORMAT_BUFFER - 1] = '\0'; in[0] = '\0'; kret = 0; /* @@ -421,6 +422,7 @@ aname_replacer(string, contextp, result) out = ep; /* Do the replacemenbt */ + memset(out, '\0', MAX_FORMAT_BUFFER); do_replacement(rule, repl, doglobal, in, out); free(rule); free(repl); diff --git a/src/lib/krb5/os/ccdefname.c b/src/lib/krb5/os/ccdefname.c index 53e7888..6b00e52 100644 --- a/src/lib/krb5/os/ccdefname.c +++ b/src/lib/krb5/os/ccdefname.c @@ -160,7 +160,7 @@ static krb5_error_code get_from_os(char *name_buf, int name_size) if (get_from_registry_indirect(name_buf, name_size) != 0) return 0; - strncpy(name_buf, prefix, name_size); + strncpy(name_buf, prefix, name_size - 1); name_buf[name_size - 1] = 0; size = name_size - strlen(prefix); if (size > 0) @@ -261,6 +261,13 @@ krb5_cc_set_default_name(context, name) return ENOMEM; strcpy(new_name, name_buf); + if (!os_ctx->default_ccname || (strcmp(os_ctx->default_ccname, new_name) != 0)) { + /* the ccache changed... forget the old principal */ + if (os_ctx->default_ccprincipal) + krb5_free_principal (context, os_ctx->default_ccprincipal); + os_ctx->default_ccprincipal = 0; /* we don't care until we use it */ + } + if (os_ctx->default_ccname) free(os_ctx->default_ccname); diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c index 6ed95bc..575866e 100644 --- a/src/lib/krb5/os/changepw.c +++ b/src/lib/krb5/os/changepw.c @@ -53,31 +53,24 @@ */ static krb5_error_code -krb5_locate_kpasswd(context, realm, addr_pp, naddrs, master_index, nmasters) +krb5_locate_kpasswd(context, realm, addr_pp, naddrs) krb5_context context; const krb5_data *realm; struct sockaddr **addr_pp; int *naddrs; - int *master_index; - int *nmasters; { krb5_error_code code; int i; -#ifdef KRB5_DNS_LOOKUP - struct sockaddr *admin_addr_p, *kdc_addr_p; - int nadmin_addrs, nkdc_addrs; - int j; -#endif /* KRB5_DNS_LOOKUP */ /* * We always try the local file first */ - code = krb5_locate_srv_conf(context, realm, "kpasswd_server", addr_pp, naddrs, - master_index, nmasters); + code = krb5_locate_srv_conf(context, realm, "kpasswd_server", + addr_pp, naddrs, 0); if (code) { - code = krb5_locate_srv_conf(context, realm, "admin_server", addr_pp, naddrs, - master_index, nmasters); + code = krb5_locate_srv_conf(context, realm, "admin_server", + addr_pp, naddrs, 0); if ( !code ) { /* success with admin_server but now we need to change the port */ /* number to use DEFAULT_KPASSWD_PORT. */ @@ -90,7 +83,7 @@ krb5_locate_kpasswd(context, realm, addr_pp, naddrs, master_index, nmasters) #ifdef KRB5_DNS_LOOKUP if (code) { - int use_dns = _krb5_use_dns(context); + int use_dns = _krb5_use_dns_kdc(context); if ( use_dns ) { code = krb5_locate_srv_dns(realm, "_kpasswd", "_udp", addr_pp, naddrs); @@ -108,10 +101,6 @@ krb5_locate_kpasswd(context, realm, addr_pp, naddrs, master_index, nmasters) } } } - if ( !code && master_index && nmasters ) { - *master_index = 1; - *nmasters = *naddrs; - } } } #endif /* KRB5_DNS_LOOKUP */ @@ -158,7 +147,7 @@ krb5_change_password(context, creds, newpw, result_code, if (code = krb5_locate_kpasswd(context, krb5_princ_realm(context, creds->client), - &addr_p, &naddr_p,NULL,NULL)) + &addr_p, &naddr_p)) goto cleanup; /* this is really obscure. s1 is used for all communications. it diff --git a/src/lib/krb5/os/def_realm.c b/src/lib/krb5/os/def_realm.c index 8647f89..d9bd017 100644 --- a/src/lib/krb5/os/def_realm.c +++ b/src/lib/krb5/os/def_realm.c @@ -24,7 +24,8 @@ * or implied warranty. * * - * krb5_get_default_realm() function. + * krb5_get_default_realm(), krb5_set_default_realm(), + * krb5_free_default_realm() functions. */ #include "k5-int.h" @@ -103,7 +104,7 @@ krb5_get_default_realm(context, lrealm) #ifdef KRB5_DNS_LOOKUP if (context->default_realm == 0) { - int use_dns = _krb5_use_dns(context); + int use_dns = _krb5_use_dns_realm(context); if ( use_dns ) { /* * Since this didn't appear in our config file, try looking @@ -202,3 +203,11 @@ krb5_set_default_realm(context, lrealm) return(0); } + +KRB5_DLLIMP void KRB5_CALLCONV +krb5_free_default_realm(context, lrealm) + krb5_context context; + char FAR* lrealm; +{ + free (lrealm); +}
\ No newline at end of file diff --git a/src/lib/krb5/os/hst_realm.c b/src/lib/krb5/os/hst_realm.c index 3c0005c..5a30001 100644 --- a/src/lib/krb5/os/hst_realm.c +++ b/src/lib/krb5/os/hst_realm.c @@ -117,6 +117,8 @@ krb5_try_realm_txt_rr(prefix, name, realm) */ if (name == NULL || name[0] == '\0') { + if (strlen (prefix) >= sizeof(host)-1) + return KRB5_ERR_HOST_REALM_UNKNOWN; strcpy(host,prefix); } else { if ( strlen(prefix) + strlen(name) + 3 > MAX_DNS_NAMELEN ) @@ -134,7 +136,7 @@ krb5_try_realm_txt_rr(prefix, name, realm) */ h = host + strlen (host); - if (h > host && h[-1] != '.') + if ((h > host) && (h[-1] != '.') && ((h - host + 1) < sizeof(host))) strcpy (h, "."); } size = res_search(host, C_IN, T_TXT, answer.bytes, sizeof(answer.bytes)); @@ -312,7 +314,7 @@ krb5_get_host_realm(context, host, realmsp) #ifdef KRB5_DNS_LOOKUP if (realm == (char *)NULL) { - int use_dns = _krb5_use_dns(context); + int use_dns = _krb5_use_dns_realm(context); if ( use_dns ) { /* * Since this didn't appear in our config file, try looking @@ -330,17 +332,6 @@ krb5_get_host_realm(context, host, realmsp) if (cp) cp++; } while (retval && cp && cp[0]); - if (retval) - retval = krb5_try_realm_txt_rr("_kerberos", "", &realm); - if (retval && default_realm) { - cp = default_realm; - do { - retval = krb5_try_realm_txt_rr("_kerberos", cp, &realm); - cp = strchr(cp,'.'); - if (cp) - cp++; - } while (retval && cp && cp[0]); - } } } #endif /* KRB5_DNS_LOOKUP */ diff --git a/src/lib/krb5/os/init_os_ctx.c b/src/lib/krb5/os/init_os_ctx.c index 48d8bc2..4140398 100644 --- a/src/lib/krb5/os/init_os_ctx.c +++ b/src/lib/krb5/os/init_os_ctx.c @@ -30,22 +30,7 @@ #include "k5-int.h" #ifdef macintosh -OSErr -GetMacProfileFileSpec (FSSpec* outFileSpec, StringPtr inName, UInt32 whichFolder) -{ - OSErr err; - - - - err = FindFolder (kOnSystemDisk, whichFolder, kCreateFolder, - &(outFileSpec -> vRefNum) , &(outFileSpec -> parID)); - - if (err == noErr) { - BlockMoveData (inName, &(outFileSpec -> name), strlen (inName) + 1); - } - - return err; -} +#include <PreferencesLib.h> #endif /* macintosh */ #if defined(_MSDOS) || defined(_WIN32) @@ -204,42 +189,94 @@ os_get_default_config_files(pfiles, secure) { profile_filespec_t* files; #ifdef macintosh - files = malloc(7 * sizeof(FSSpec)); - - if (files != 0) { - OSErr err = GetMacProfileFileSpec(&(files [3]), "\pKerberos Preferences", kApplicationSupportFolderType); - if (err == noErr) { - err = GetMacProfileFileSpec( &(files [4]), "\pkrb5.ini", kApplicationSupportFolderType); - } - if (err == noErr) { - err = GetMacProfileFileSpec( &(files [5]), "\pKerberos5 Configuration", kApplicationSupportFolderType); - } - - if (err == noErr) { - files[6].vRefNum = 0; - files[6].parID = 0; - files[6].name[0] = '\0'; - } else { - files[3].vRefNum = 0; - files[3].parID = 0; - files[3].name[0] = '\0'; + FSSpec* preferencesFiles = nil; + UInt32 numPreferencesFiles; + FSSpec* preferencesFilesToInit = nil; + UInt32 numPreferencesFilesToInit; + UInt32 i; + Boolean foundPreferences = false; + Boolean writtenPreferences = false; + SInt16 refNum = -1; + SInt32 length = 0; + + OSErr err = KPGetListOfPreferencesFiles ( + secure ? kpSystemPreferences : kpUserPreferences | kpSystemPreferences, + &preferencesFiles, + &numPreferencesFiles); + + if (err == noErr) { + /* After we get the list of files, check whether any of them contain any useful information */ + for (i = 0; i < numPreferencesFiles; i++) { + if (KPPreferencesFileIsReadable (&preferencesFiles [i]) == noErr) { + /* It's readable, check if it has anything in the data fork */ + err = FSpOpenDF (&preferencesFiles [i], fsRdPerm, &refNum); + if (err == noErr) { + err = GetEOF (refNum, &length); + } + + if (refNum != -1) { + FSClose (refNum); + } + + if (length != 0) { + foundPreferences = true; + break; + } + } } - err = GetMacProfileFileSpec(&(files [0]), "\pKerberos Preferences", kPreferencesFolderType); - if (err == noErr) { - err = GetMacProfileFileSpec( &(files [1]), "\pkrb5.ini", kPreferencesFolderType); - } - if (err == noErr) { - err = GetMacProfileFileSpec( &(files [2]), "\pKerberos5 Configuration", kPreferencesFolderType); + if (!foundPreferences) { + /* We found no profile data in any of those files; try to initialize one */ + /* If we are running "secure" do not try to initialize preferences */ + if (!secure) { + err = KPGetListOfPreferencesFiles (kpUserPreferences, &preferencesFilesToInit, &numPreferencesFilesToInit); + if (err == noErr) { + for (i = 0; i < numPreferencesFilesToInit; i++) { + if (KPPreferencesFileIsWritable (&preferencesFilesToInit [i]) == noErr) { + err = noErr; + /* If not readable, create it */ + if (KPPreferencesFileIsReadable (&preferencesFilesToInit [i]) != noErr) { + err = KPCreatePreferencesFile (&preferencesFilesToInit [i]); + } + /* Initialize it */ + if (err == noErr) { + err = KPInitializeWithDefaultKerberosLibraryPreferences (&preferencesFilesToInit [i]); + } + break; + } + } + } + } } + } + + if (err == noErr) { + files = malloc ((numPreferencesFiles + 1) * sizeof (FSSpec)); + if (files == NULL) + err = memFullErr; + } + + if (err == noErr) { + for (i = 0; i < numPreferencesFiles; i++) { + files [i] = preferencesFiles [i]; + } + + files [numPreferencesFiles].vRefNum = 0; + files [numPreferencesFiles].parID = 0; + files [numPreferencesFiles].name[0] = '\0'; + } + + if (preferencesFiles != nil) + KPFreeListOfPreferencesFiles (preferencesFiles); + + if (preferencesFilesToInit != nil) + KPFreeListOfPreferencesFiles (preferencesFilesToInit); - if (err != noErr) { - free (files); - return ENFILE; - } - } else { + if (err == memFullErr) return ENOMEM; - } + else if (err != noErr) + return ENFILE; + #else /* !macintosh */ #if defined(_MSDOS) || defined(_WIN32) krb5_error_code retval = 0; @@ -404,6 +441,7 @@ krb5_os_init_context(ctx) os_ctx->usec_offset = 0; os_ctx->os_flags = 0; os_ctx->default_ccname = 0; + os_ctx->default_ccprincipal = 0; krb5_cc_set_default_name(ctx, NULL); @@ -524,6 +562,11 @@ krb5_os_free_context(ctx) os_ctx->default_ccname = 0; } + if (os_ctx->default_ccprincipal) { + krb5_free_principal (ctx, os_ctx->default_ccprincipal); + os_ctx->default_ccprincipal = 0; + } + os_ctx->magic = 0; free(os_ctx); ctx->os_context = 0; diff --git a/src/lib/krb5/os/kuserok.c b/src/lib/krb5/os/kuserok.c index ef08037..6d2adb1 100644 --- a/src/lib/krb5/os/kuserok.c +++ b/src/lib/krb5/os/kuserok.c @@ -80,8 +80,9 @@ krb5_kuserok(context, principal, luser) if ((pwd = getpwnam(luser)) == NULL) { return(FALSE); } - (void) strcpy(pbuf, pwd->pw_dir); - (void) strcat(pbuf, "/.k5login"); + (void) strncpy(pbuf, pwd->pw_dir, sizeof(pbuf) - 1); + pbuf[sizeof(pbuf) - 1] = '\0'; + (void) strncat(pbuf, "/.k5login", sizeof(pbuf) - 1 - strlen(pbuf)); if (access(pbuf, F_OK)) { /* not accessible */ /* diff --git a/src/lib/krb5/os/localaddr.c b/src/lib/krb5/os/localaddr.c index 9079500..44210de 100644 --- a/src/lib/krb5/os/localaddr.c +++ b/src/lib/krb5/os/localaddr.c @@ -1,7 +1,7 @@ /* * lib/krb5/os/localaddr.c * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. + * Copyright 1990,1991,2000 by the Massachusetts Institute of Technology. * All Rights Reserved. * * Export of this software from the United States of America may @@ -39,6 +39,7 @@ #include <sys/ioctl.h> #include <sys/time.h> #include <errno.h> +#include <stddef.h> /* * The SIOCGIF* ioctls require a socket. @@ -255,13 +256,14 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) int (*betweenfn) (void *); int (*pass2fn) (void *, struct sockaddr *); { - struct ifreq *ifr, ifreq; + struct ifreq *ifr, ifreq, *ifr2; struct ifconf ifc; - int s, code, n, i; + int s, code, n, i, j; int est_if_count = 8, est_ifreq_size; char *buf = 0; size_t current_buf_size = 0; - + int fail = 0; + s = socket (USE_AF, USE_TYPE, USE_PROTO); if (s < 0) return SOCKET_ERRNO; @@ -312,26 +314,49 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) ifr = (struct ifreq *)((caddr_t) ifc.ifc_buf+i); strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof (ifreq.ifr_name)); - if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0 -#ifdef IFF_LOOPBACK - /* None of the current callers want loopback addresses. */ - || (ifreq.ifr_flags & IFF_LOOPBACK) -#endif - /* Ignore interfaces that are down. */ - || !(ifreq.ifr_flags & IFF_UP)) { + if (ioctl (s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { + skip: /* mark for next pass */ ifr->ifr_name[0] = 0; continue; } +#ifdef IFF_LOOPBACK + /* None of the current callers want loopback addresses. */ + if (ifreq.ifr_flags & IFF_LOOPBACK) + goto skip; +#endif + /* Ignore interfaces that are down. */ + if (!(ifreq.ifr_flags & IFF_UP)) + goto skip; + + /* Make sure we didn't process this address already. */ + for (j = 0; j < i; j += ifreq_size(*ifr2)) { + ifr2 = (struct ifreq *)((caddr_t) ifc.ifc_buf+j); + if (ifr2->ifr_name[0] == 0) + continue; + if (ifr2->ifr_addr.sa_family == ifr->ifr_addr.sa_family + && ifreq_size (*ifr) == ifreq_size (*ifr2) + /* Compare address info. If this isn't good enough -- + i.e., if random padding bytes turn out to differ + when the addresses are the same -- then we'll have + to do it on a per address family basis. */ + && !memcmp (&ifr2->ifr_addr.sa_data, &ifr->ifr_addr.sa_data, + (ifreq_size (*ifr) + - offsetof (struct ifreq, ifr_addr.sa_data)))) + goto skip; + } + if ((*pass1fn) (data, &ifr->ifr_addr)) { - abort (); + fail = 1; + goto punt; } } if (betweenfn && (*betweenfn)(data)) { - abort (); + fail = 1; + goto punt; } if (pass2fn) @@ -343,13 +368,15 @@ foreach_localaddr (data, pass1fn, betweenfn, pass2fn) continue; if ((*pass2fn) (data, &ifr->ifr_addr)) { - abort (); + fail = 1; + goto punt; } } + punt: closesocket(s); free (buf); - return 0; + return fail; } @@ -376,10 +403,9 @@ krb5_os_localaddr(context, addr) return r; } + data.cur_idx++; /* null termination */ if (data.mem_err) return ENOMEM; - else if (data.cur_idx == 0) - abort (); else if (data.cur_idx == data.count) *addr = data.addr_temp; else { @@ -473,6 +499,8 @@ krb5_os_localaddr (krb5_context context, krb5_address ***addr) { hostrec = local_addr_fallback_kludge(); if (!hostrec) return err; + else + err = 0; /* otherwise we will die at cleanup */ } for (count = 0; hostrec->h_addr_list[count]; count++); diff --git a/src/lib/krb5/os/locate_kdc.c b/src/lib/krb5/os/locate_kdc.c index fcdfa03..2cabf84 100644 --- a/src/lib/krb5/os/locate_kdc.c +++ b/src/lib/krb5/os/locate_kdc.c @@ -53,29 +53,57 @@ #define KPASSWD_PORTNAME "kpasswd" #endif -int -_krb5_use_dns(context) - krb5_context context; +#if KRB5_DNS_LOOKUP_KDC +#define DEFAULT_LOOKUP_KDC 1 +#else +#define DEFAULT_LOOKUP_KDC 0 +#endif +#if KRB5_DNS_LOOKUP_REALM +#define DEFAULT_LOOKUP_REALM 1 +#else +#define DEFAULT_LOOKUP_REALM 0 +#endif + +static int +maybe_use_dns (context, name, defalt) + krb5_context context; + const char *name; + int defalt; { krb5_error_code code; char * value = NULL; int use_dns = 0; code = profile_get_string(context->profile, "libdefaults", - "dns_fallback", 0, - context->profile_in_memory?"1":"0", - &value); + name, 0, 0, &value); + if (value == 0 && code == 0) + code = profile_get_string(context->profile, "libdefaults", + "dns_fallback", 0, 0, &value); if (code) - return(code); + return defalt; - if (value) { - use_dns = _krb5_conf_boolean(value); - profile_release_string(value); - } + if (value == 0) + return defalt; + use_dns = _krb5_conf_boolean(value); + profile_release_string(value); return use_dns; } +int +_krb5_use_dns_kdc(context) + krb5_context context; +{ + return maybe_use_dns (context, "dns_lookup_kdc", DEFAULT_LOOKUP_KDC); +} + +int +_krb5_use_dns_realm(context) + krb5_context context; +{ + return maybe_use_dns (context, "dns_lookup_realm", DEFAULT_LOOKUP_REALM); +} + #endif /* KRB5_DNS_LOOKUP */ /* @@ -85,14 +113,13 @@ _krb5_use_dns(context) */ krb5_error_code -krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmasters) +krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, get_masters) krb5_context context; const krb5_data *realm; const char * name; struct sockaddr **addr_pp; int *naddrs; - int *master_index; - int *nmasters; + int get_masters; { const char *realm_srv_names[4]; char **masterlist, **hostlist, *host, *port, *cp; @@ -162,10 +189,7 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste return 0; } - if (master_index) { - *master_index = 0; - *nmasters = 0; - + if (get_masters) { realm_srv_names[0] = "realms"; realm_srv_names[1] = host; realm_srv_names[2] = "admin_server"; @@ -209,8 +233,10 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste addr_p = (struct sockaddr *)malloc (sizeof (struct sockaddr) * count); if (addr_p == NULL) { - profile_free_list(hostlist); - profile_free_list(masterlist); + if (hostlist) + profile_free_list(hostlist); + if (masterlist) + profile_free_list(masterlist); return ENOMEM; } @@ -239,12 +265,12 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste if (masterlist) { for (j=0; masterlist[j]; j++) { if (strcasecmp(hostlist[i], masterlist[j]) == 0) { - *master_index = out; ismaster = 1; } } } + if ( !get_masters || ismaster ) { switch (hp->h_addrtype) { #ifdef HAVE_NETINET_IN_H @@ -263,8 +289,10 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste realloc ((char *)addr_p, sizeof(struct sockaddr) * count); if (addr_p == NULL) { - profile_free_list(hostlist); - profile_free_list(masterlist); + if (hostlist) + profile_free_list(hostlist); + if (masterlist) + profile_free_list(masterlist); return ENOMEM; } } @@ -279,12 +307,13 @@ krb5_locate_srv_conf(context, realm, name, addr_pp, naddrs, master_index, nmaste default: break; } - if (ismaster) - *nmasters = out - *master_index; + } } - profile_free_list(hostlist); - profile_free_list(masterlist); + if (hostlist) + profile_free_list(hostlist); + if (masterlist) + profile_free_list(masterlist); if (out == 0) { /* Couldn't resolve any KDC names */ free (addr_p); @@ -564,78 +593,29 @@ krb5_locate_srv_dns(realm, service, protocol, addr_pp, naddrs) */ krb5_error_code -krb5_locate_kdc(context, realm, addr_pp, naddrs, master_index, nmasters) +krb5_locate_kdc(context, realm, addr_pp, naddrs, get_masters) krb5_context context; const krb5_data *realm; struct sockaddr **addr_pp; int *naddrs; - int *master_index; - int *nmasters; + int get_masters; { krb5_error_code code; -#ifdef KRB5_DNS_LOOKUP - struct sockaddr *admin_addr_p, *kdc_addr_p; - int nadmin_addrs, nkdc_addrs; - int i,j; -#endif /* KRB5_DNS_LOOKUP */ /* * We always try the local file first */ code = krb5_locate_srv_conf(context, realm, "kdc", addr_pp, naddrs, - master_index, nmasters); + get_masters); #ifdef KRB5_DNS_LOOKUP if (code) { - int use_dns = _krb5_use_dns(context); + int use_dns = _krb5_use_dns_kdc(context); if ( use_dns ) { - code = krb5_locate_srv_dns(realm, "_kerberos", "_udp", - addr_pp, naddrs); - if ( master_index && nmasters ) { - - code = krb5_locate_srv_dns(realm, "_kerberos-adm", "_tcp", - &admin_addr_p, &nadmin_addrs); - if ( code ) { - free(*addr_pp); - *addr_pp = NULL; - *naddrs = 0; - return(code); - } - - kdc_addr_p = *addr_pp; - nkdc_addrs = *naddrs; - - *naddrs = 0; - *addr_pp = (struct sockaddr *) malloc(sizeof(*kdc_addr_p)); - if ( *addr_pp == NULL ) { - free(kdc_addr_p); - free(admin_addr_p); - return ENOMEM; - } - - for ( i=0; i<nkdc_addrs; i++ ) { - for ( j=0 ; j<nadmin_addrs; j++) { - if ( !memcmp(&kdc_addr_p[i].sa_data[2],&admin_addr_p[j].sa_data[2],4) ) { - memcpy(&(*addr_pp)[(*naddrs)],&kdc_addr_p[i], - sizeof(struct sockaddr)); - (*naddrs)++; - break; - } - } - } - - free(kdc_addr_p); - free(admin_addr_p); - - if ( *naddrs == 0 ) { - free(*addr_pp); - *addr_pp = NULL; - return KRB5_REALM_CANT_RESOLVE; - } - *master_index = 1; - *nmasters = *naddrs; - } + code = krb5_locate_srv_dns(realm, + get_masters ? "_kerberos-master" : "_kerberos", + "_udp", addr_pp, naddrs); } } #endif /* KRB5_DNS_LOOKUP */ diff --git a/src/lib/krb5/os/os-proto.h b/src/lib/krb5/os/os-proto.h index fed7a81..a6b67f1 100644 --- a/src/lib/krb5/os/os-proto.h +++ b/src/lib/krb5/os/os-proto.h @@ -36,8 +36,7 @@ krb5_error_code krb5_locate_kdc const krb5_data *, struct sockaddr **, int *, - int *, - int *)); + int)); #endif #ifdef HAVE_NETINET_IN_H diff --git a/src/lib/krb5/os/prompter.c b/src/lib/krb5/os/prompter.c index 933ff2c..985ed6e 100644 --- a/src/lib/krb5/os/prompter.c +++ b/src/lib/krb5/os/prompter.c @@ -235,7 +235,7 @@ krb5int_set_prompt_types(context, types) krb5_context context; krb5_prompt_type *types; { - context->prompt_types = 0; + context->prompt_types = types; } KRB5_DLLIMP diff --git a/src/lib/krb5/os/sendto_kdc.c b/src/lib/krb5/os/sendto_kdc.c index 01b797e..47f2408 100644 --- a/src/lib/krb5/os/sendto_kdc.c +++ b/src/lib/krb5/os/sendto_kdc.c @@ -60,16 +60,16 @@ extern int krb5_skdc_timeout_shift; extern int krb5_skdc_timeout_1; krb5_error_code -krb5_sendto_kdc (context, message, realm, reply, master) +krb5_sendto_kdc (context, message, realm, reply, use_master) krb5_context context; const krb5_data * message; const krb5_data * realm; krb5_data * reply; - int *master; + int use_master; { register int timeout, host, i; struct sockaddr *addr; - int naddr, master_index, nmasters; + int naddr; int sent, nready; krb5_error_code retval; SOCKET *socklist; @@ -81,14 +81,10 @@ krb5_sendto_kdc (context, message, realm, reply, master) * find KDC location(s) for realm */ - if (retval = krb5_locate_kdc (context, realm, &addr, &naddr, - master?&master_index:NULL, - master?&nmasters:NULL)) + if (retval = krb5_locate_kdc (context, realm, &addr, &naddr, use_master)) return retval; if (naddr == 0) - return KRB5_REALM_UNKNOWN; - if (master && (*master == 1) && (nmasters == 0)) - return KRB5_KDC_UNREACH; + return (use_master ? KRB5_KDC_UNREACH : KRB5_REALM_UNKNOWN); socklist = (SOCKET *)malloc(naddr * sizeof(SOCKET)); if (socklist == NULL) { @@ -128,12 +124,6 @@ krb5_sendto_kdc (context, message, realm, reply, master) timeout <<= krb5_skdc_timeout_shift) { sent = 0; for (host = 0; host < naddr; host++) { - /* if a master kdc is required, skip the non-master kdc's */ - - if (master && (*master == 1) && - ((host < master_index) || (host >= (master_index+nmasters)))) - continue; - /* send to the host, wait timeout seconds for a response, then move on. */ /* cache some sockets for each host */ @@ -211,12 +201,6 @@ krb5_sendto_kdc (context, message, realm, reply, master) reply->length = cc; retval = 0; - /* if the caller asked to be informed if it - got a master kdc, tell it */ - if (master) - *master = ((host >= master_index) && - (host < (master_index+nmasters))); - goto out; } else if (nready == 0) { /* timeout */ diff --git a/src/lib/krb5/os/t_std_conf.c b/src/lib/krb5/os/t_std_conf.c index 0846b1c..a95c67a 100644 --- a/src/lib/krb5/os/t_std_conf.c +++ b/src/lib/krb5/os/t_std_conf.c @@ -110,14 +110,14 @@ void test_locate_kdc(ctx, realm) struct sockaddr *addrs; struct sockaddr_in *sin; int i, naddrs; - int master_index, nmasters; + int get_masters=0; krb5_data rlm; krb5_error_code retval; rlm.data = realm; rlm.length = strlen(realm); retval = krb5_locate_kdc(ctx, &rlm, &addrs, &naddrs, - &master_index, &nmasters); + get_masters); if (retval) { com_err("krb5_get_krbhst", retval, 0); return; diff --git a/src/lib/krb5/posix/ChangeLog b/src/lib/krb5/posix/ChangeLog index e90e47b..6f9a5ef 100644 --- a/src/lib/krb5/posix/ChangeLog +++ b/src/lib/krb5/posix/ChangeLog @@ -1,3 +1,10 @@ +2000-04-28 Ken Raeburn <raeburn@mit.edu> + Nalin Dahyabhai <nalin@redhat.com> + + * syslog.c (vsyslog): Use strncpy and strncat instead of strcpy + and strcat when adding to buffer "tbuf". If calling vsprintf, + abort if it appears to have overrun the buffer. + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/lib/krb5/posix/syslog.c b/src/lib/krb5/posix/syslog.c index 31e7874..f7ddbff 100644 --- a/src/lib/krb5/posix/syslog.c +++ b/src/lib/krb5/posix/syslog.c @@ -115,7 +115,7 @@ vsyslog(pri, fmt, ap) (void)sprintf(tbuf, "<%d>%.15s ", pri, ctime(&now) + 4); for (p = tbuf; *p; ++p); if (LogTag) { - (void)strcpy(p, LogTag); + (void)strncpy(p, LogTag, sizeof(tbuf) - 1 - (p - tbuf)); for (; *p; ++p); } if (LogStat & LOG_PID) { @@ -146,6 +146,11 @@ vsyslog(pri, fmt, ap) } (void)vsprintf(p, fmt_cpy, ap); + /* Bounds checking?? If a system doesn't have syslog, we + probably can't rely on it having vsnprintf either. Try not + to let a buffer overrun be exploited. */ + if (strlen (tbuf) >= sizeof (tbuf)) + abort (); /* output the message to the local logger */ if (send(LogFile, tbuf, cnt = strlen(tbuf), 0) >= 0 || @@ -169,7 +174,8 @@ vsyslog(pri, fmt, ap) if ((fd = open(CONSOLE, O_WRONLY, 0)) < 0) return; (void)alarm((u_int)0); - (void)strcat(tbuf, "\r"); + tbuf[sizeof(tbuf) - 1] = '\0'; + (void)strncat(tbuf, "\r", sizeof(tbuf) - 1 - strlen(tbuf)); p = strchr(tbuf, '>') + 1; (void)write(fd, p, cnt + 1 - (p - tbuf)); (void)close(fd); diff --git a/src/lib/krb5/rcache/ChangeLog b/src/lib/krb5/rcache/ChangeLog index a3b8b4f..c8f5de1 100644 --- a/src/lib/krb5/rcache/ChangeLog +++ b/src/lib/krb5/rcache/ChangeLog @@ -1,3 +1,8 @@ +2000-04-28 Nalin Dahyabhai <nalin@redhat.com> + + * rc_io.c (getdir): Don't check dirlen again, the call sites + always do. Fix dirlen calculation. + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/lib/krb5/rcache/rc_io.c b/src/lib/krb5/rcache/rc_io.c index d45c7a1..b4291bc 100644 --- a/src/lib/krb5/rcache/rc_io.c +++ b/src/lib/krb5/rcache/rc_io.c @@ -57,8 +57,6 @@ static char *dir; static void getdir() { - if (!dirlen) - { if (!(dir = getenv("KRB5RCACHEDIR"))) #if defined(_MSDOS) || defined(_WIN32) if (!(dir = getenv("TEMP"))) @@ -72,8 +70,7 @@ static void getdir() dir = "/tmp"; #endif #endif - dirlen = strlen(dir) + 1; - } + dirlen = strlen(dir) + sizeof(PATH_SEPARATOR); } krb5_error_code krb5_rc_io_creat (context, d, fn) diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def index 4c5f271..5506c42 100644 --- a/src/lib/krb5_32.def +++ b/src/lib/krb5_32.def @@ -13,10 +13,6 @@ ; !CALLCONV - entrypoint that should have used KRB5_CALLCONV, but did not due ; developer error -;LIBRARY KRB5 -DESCRIPTION 'DLL for Kerberos 5' -HEAPSIZE 8192 - EXPORTS ; Kerberos 5 krb5_build_principal @@ -42,7 +38,7 @@ EXPORTS krb5_free_authenticator krb5_free_authenticator_contents krb5_free_checksum - krb5_free_config_files + krb5_free_config_files krb5_free_context krb5_free_cred krb5_free_cred_contents @@ -76,7 +72,7 @@ EXPORTS krb5_get_credentials krb5_get_credentials_renew krb5_get_credentials_validate - krb5_get_default_config_files + krb5_get_default_config_files krb5_get_default_realm krb5_get_host_realm krb5_get_realm_domain @@ -208,46 +204,49 @@ EXPORTS krb5_change_password ; - krb5_write_message - krb5_read_message - krb5_net_write - krb5_net_read - krb5_encrypt - krb5_decrypt - krb5_encrypt_size + krb5_write_message + krb5_read_message + krb5_net_write + krb5_net_read + krb5_encrypt + krb5_decrypt + krb5_encrypt_size ; ; Added for Kermit 95 - krb5_address_search ; !CALLCONV - krb5_auth_con_getrcache ; !CALLCONV - krb5_c_enctype_compare + krb5_address_search ; !CALLCONV + krb5_auth_con_getrcache ; !CALLCONV + krb5_c_enctype_compare ; krb5_kuserok ; ; Added for 1.2: krb5_decode_ticket + krb5_appdefault_string + krb5_appdefault_boolean ; ; Temporary exports (DO NOT USE) -; decode_krb5_ticket -- no longer in library des_ecb_encrypt des_new_random_key des_key_sched des_pcbc_encrypt des_quad_cksum des_string_to_key -; des_set_random_generator_seed -- no longer in library des_init_random_number_generator krb5_random_confounder - krb5_size_opaque - krb5_internalize_opaque - krb5_externalize_opaque - krb5_ser_pack_int32 - krb5_ser_unpack_int32 - krb5_ser_pack_bytes - krb5_ser_unpack_bytes - krb5_ser_auth_context_init - krb5_ser_context_init - krb5_ser_ccache_init - krb5_ser_keytab_init - krb5_ser_rcache_init + krb5_size_opaque ; gssapi + krb5_internalize_opaque ; gssapi + krb5_externalize_opaque ; gssapi + krb5_ser_pack_int32 ; gssapi + krb5_ser_unpack_int32 ; gssapi + krb5_ser_pack_bytes ; gssapi + krb5_ser_unpack_bytes ; gssapi + krb5_ser_auth_context_init ; gssapi + krb5_ser_context_init ; gssapi + krb5_ser_ccache_init ; gssapi + krb5_ser_keytab_init ; gssapi + krb5_ser_rcache_init ; gssapi decode_krb5_ap_req ; gssapi - krb5_mcc_ops + krb5_mcc_ops ; gssapi + krb5_get_tgs_ktypes ; gssapi + krb5_free_ktypes ; gssapi + krb5int_cc_default ; gssapi diff --git a/src/lib/krb5util/ChangeLog b/src/lib/krb5util/ChangeLog index ec629cb..8f671a0 100644 --- a/src/lib/krb5util/ChangeLog +++ b/src/lib/krb5util/ChangeLog @@ -1,3 +1,8 @@ +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * compat_recv.c (krb5_compat_recvauth_version): Variant of + krb5_compat_recvauth, similar to krb5_recvauth_version. + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/lib/krb5util/compat_recv.c b/src/lib/krb5util/compat_recv.c index ec6b151..ee7df24 100644 --- a/src/lib/krb5util/compat_recv.c +++ b/src/lib/krb5util/compat_recv.c @@ -193,6 +193,151 @@ krb5_compat_recvauth(context, auth_context, return retval; } +krb5_error_code +krb5_compat_recvauth_version(context, auth_context, + /* IN */ + fdp, server, flags, keytab, + v4_options, v4_service, v4_instance, v4_faddr, + v4_laddr, + v4_filename, + /* OUT */ + ticket, + auth_sys, v4_kdata, v4_schedule, + version) + krb5_context context; + krb5_auth_context *auth_context; + krb5_pointer fdp; + krb5_principal server; + krb5_int32 flags; + krb5_keytab keytab; + krb5_ticket ** ticket; + krb5_int32 *auth_sys; + + /* + * Version 4 arguments + */ + krb5_int32 v4_options; /* bit-pattern of options */ + char *v4_service; /* service expected */ + char *v4_instance; /* inst expected (may be filled in) */ + struct sockaddr_in *v4_faddr; /* foreign address */ + struct sockaddr_in *v4_laddr; /* local address */ + AUTH_DAT **v4_kdata; /* kerberos data (returned) */ + char *v4_filename; /* name of file with service keys */ + Key_schedule v4_schedule; /* key schedule (return) */ + krb5_data *version; /* application version filled in */ +{ + union verslen { + krb5_int32 len; + char vers[4]; + } vers; + char *buf; + int len, length; + krb5_int32 retval; + int fd = *( (int *) fdp); +#ifdef KRB5_KRB4_COMPAT + KTEXT v4_ticket; /* storage for client's ticket */ +#endif + + if ((retval = krb5_net_read(context, fd, vers.vers, 4)) != 4) + return((retval < 0) ? errno : ECONNABORTED); + +#ifdef KRB5_KRB4_COMPAT + if (!strncmp(vers.vers, KRB_V4_SENDAUTH_VERS, 4)) { + /* + * We must be talking to a V4 sendauth; read in the + * rest of the version string and make sure. + */ + if ((retval = krb5_net_read(context, fd, vers.vers, 4)) != 4) + return((retval < 0) ? errno : ECONNABORTED); + + if (strncmp(vers.vers, KRB_V4_SENDAUTH_VERS+4, 4)) + return KRB5_SENDAUTH_BADAUTHVERS; + + *auth_sys = KRB5_RECVAUTH_V4; + + *v4_kdata = (AUTH_DAT *) malloc( sizeof(AUTH_DAT) ); + v4_ticket = (KTEXT) malloc(sizeof(KTEXT_ST)); + + version->length = KRB_SENDAUTH_VLEN; /* no trailing \0! */ + version->data = malloc (KRB_SENDAUTH_VLEN + 1); + version->data[KRB_SENDAUTH_VLEN] = 0; + if (version->data == 0) + return errno; + retval = krb_v4_recvauth(v4_options, fd, v4_ticket, + v4_service, v4_instance, v4_faddr, + v4_laddr, *v4_kdata, v4_filename, + v4_schedule, version->data); + krb5_xfree(v4_ticket); + /* + * XXX error code translation? + */ + switch (retval) { + case RD_AP_OK: + return 0; + case RD_AP_TIME: + return KRB5KRB_AP_ERR_SKEW; + case RD_AP_EXP: + return KRB5KRB_AP_ERR_TKT_EXPIRED; + case RD_AP_NYV: + return KRB5KRB_AP_ERR_TKT_NYV; + case RD_AP_NOT_US: + return KRB5KRB_AP_ERR_NOT_US; + case RD_AP_UNDEC: + return KRB5KRB_AP_ERR_BAD_INTEGRITY; + case RD_AP_REPEAT: + return KRB5KRB_AP_ERR_REPEAT; + case RD_AP_MSG_TYPE: + return KRB5KRB_AP_ERR_MSG_TYPE; + case RD_AP_MODIFIED: + return KRB5KRB_AP_ERR_MODIFIED; + case RD_AP_ORDER: + return KRB5KRB_AP_ERR_BADORDER; + case RD_AP_BADD: + return KRB5KRB_AP_ERR_BADADDR; + default: + return KRB5_SENDAUTH_BADRESPONSE; + } + } +#endif + + /* + * Assume that we're talking to a V5 recvauth; read in the + * the version string, and make sure it matches. + */ + + len = (int) ntohl(vers.len); + + if (len < 0 || len > 255) + return KRB5_SENDAUTH_BADAUTHVERS; + + buf = malloc(len); + if (!buf) + return ENOMEM; + + length = krb5_net_read(context, fd, buf, len); + if (len != length) { + krb5_xfree(buf); + if (len < 0) + return errno; + else + return ECONNABORTED; + } + + if (strcmp(buf, KRB_V5_SENDAUTH_VERS)) { + krb5_xfree(buf); + return KRB5_SENDAUTH_BADAUTHVERS; + } + krb5_xfree(buf); + + *auth_sys = KRB5_RECVAUTH_V5; + + retval = krb5_recvauth_version(context, auth_context, fdp, server, + flags | KRB5_RECVAUTH_SKIP_VERSION, + keytab, ticket, version); + + return retval; +} + #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) diff --git a/src/lib/rpc/ChangeLog b/src/lib/rpc/ChangeLog index 8467267..926dd06 100644 --- a/src/lib/rpc/ChangeLog +++ b/src/lib/rpc/ChangeLog @@ -1,3 +1,36 @@ +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * pmap_rmt.c (GIFCONF_BUFSIZE): New macro. + (getbroadcastnets): Use it for buffer size. + (clnt_broadcast): Make buffer at least that big. + + * get_myaddress.c (get_myaddress): Increase buffer size. + +2000-05-18 Ken Raeburn <raeburn@mit.edu> + + * auth_gssapi_misc.c (auth_gssapi_display_status_1): Don't pass a + gss_buffer_desc to fprintf. + + * clnt_tcp.c (clnttcp_create): Initialize "ct". + * clnt_udp.c (clntudp_bufcreate): Initialize "cu". + + * svc_auth_gssapi.c (_svcauth_gssapi, create_client, + destroy_client, dump_db, clean_client): Use %p format for + displaying pointers. Remove unused variables. + +2000-05-17 Ken Raeburn <raeburn@mit.edu> + Nalin Dahyabhai <nalin@redhat.com> + + * clnt_perror.c (clnt_sperror): Don't overflow buffer "str" beyond + known allocation size. + * clnt_simple.c (gssrpc_callrpc): Don't overfill buffer "crp->oldhost". + +2000-05-03 Nalin Dahyabhai <nalin@redhat.com> + + * clnt_perror.c (_buf): Use bigger buffer. + (clnt_spcreateerror): Don't overflow buffer "buf" beyond known + allocation size. + 2000-02-22 Donn Cave <donn@u.washington.edu> * Makefile.in (includes): Extract basename of header file to be diff --git a/src/lib/rpc/auth_gssapi_misc.c b/src/lib/rpc/auth_gssapi_misc.c index fd9393c..e7c38a8 100644 --- a/src/lib/rpc/auth_gssapi_misc.c +++ b/src/lib/rpc/auth_gssapi_misc.c @@ -162,15 +162,17 @@ static void auth_gssapi_display_status_1(m, code, type, rec) auth_gssapi_display_status_1(m,gssstat,GSS_C_GSS_CODE,1); auth_gssapi_display_status_1(m, minor_stat, GSS_C_MECH_CODE, 1); - } else - fprintf(stderr, - "GSS-API authentication error %s: recursive failure!\n", - msg); + } else { + fputs ("GSS-API authentication error ", stderr); + fwrite (msg.value, msg.length, 1, stderr); + fputs (": recursive failure!\n", stderr); + } return; } - - fprintf(stderr, "GSS-API authentication error %s: %s\n", m, - (char *)msg.value); + + fprintf (stderr, "GSS-API authentication error %s: ", m); + fwrite (msg.value, msg.length, 1, stderr); + putc ('\n', stderr); (void) gss_release_buffer(&minor_stat, &msg); if (!msg_ctx) diff --git a/src/lib/rpc/clnt_perror.c b/src/lib/rpc/clnt_perror.c index 560cb27..06dd22e 100644 --- a/src/lib/rpc/clnt_perror.c +++ b/src/lib/rpc/clnt_perror.c @@ -57,9 +57,8 @@ static char *buf; static char * _buf() { - - if (buf == 0) - buf = (char *)malloc(256); + if (buf == NULL) + buf = (char *)malloc(BUFSIZ); return (buf); } @@ -74,17 +73,20 @@ clnt_sperror(rpch, s) struct rpc_err e; void clnt_perrno(); char *err; - char *str = _buf(); + char *bufstart = _buf(); + char *str = bufstart; char *strstart = str; if (str == 0) return (0); CLNT_GETERR(rpch, &e); - (void) sprintf(str, "%s: ", s); + strncpy (str, s, BUFSIZ - 1); + str[BUFSIZ - 1] = 0; + strncat (str, ": ", BUFSIZ - 1 - strlen (bufstart)); str += strlen(str); - - (void) strcpy(str, clnt_sperrno(e.re_status)); + strncat (str, clnt_sperrno(e.re_status), BUFSIZ - 1 - strlen (bufstart)); + str[BUFSIZ - 1] = '\0'; str += strlen(str); switch (e.re_status) { @@ -105,47 +107,64 @@ clnt_sperror(rpch, s) case RPC_CANTSEND: case RPC_CANTRECV: - (void) sprintf(str, "; errno = %s", - sys_errlist[e.re_errno]); + /* 10 for the string */ + if(str - bufstart + 10 + strlen(sys_errlist[e.re_errno]) < BUFSIZ) + (void) sprintf(str, "; errno = %s", + sys_errlist[e.re_errno]); str += strlen(str); break; case RPC_VERSMISMATCH: - (void) sprintf(str, - "; low version = %lu, high version = %lu", - e.re_vers.low, e.re_vers.high); + /* 33 for the string, 22 for the numbers */ + if(str - bufstart + 33 + 22 < BUFSIZ) + (void) sprintf(str, + "; low version = %lu, high version = %lu", + (unsigned long) e.re_vers.low, + (unsigned long) e.re_vers.high); str += strlen(str); break; case RPC_AUTHERROR: err = auth_errmsg(e.re_why); - (void) sprintf(str,"; why = "); + /* 8 for the string */ + if(str - bufstart + 8 < BUFSIZ) + (void) sprintf(str,"; why = "); str += strlen(str); if (err != NULL) { - (void) sprintf(str, "%s",err); + if(str - bufstart + strlen(err) < BUFSIZ) + (void) sprintf(str, "%s",err); } else { + /* 33 for the string, 11 for the number */ + if(str - bufstart + 33 + 11 < BUFSIZ) (void) sprintf(str, - "(unknown authentication error - %d)", - (int) e.re_why); + "(unknown authentication error - %d)", + (int) e.re_why); } str += strlen(str); break; case RPC_PROGVERSMISMATCH: - (void) sprintf(str, - "; low version = %lu, high version = %lu", - e.re_vers.low, e.re_vers.high); + /* 33 for the string, 22 for the numbers */ + if(str - bufstart + 33 + 22 < BUFSIZ) + (void) sprintf(str, + "; low version = %lu, high version = %lu", + (unsigned long) e.re_vers.low, + (unsigned long) e.re_vers.high); str += strlen(str); break; default: /* unknown */ - (void) sprintf(str, - "; s1 = %lu, s2 = %lu", - e.re_lb.s1, e.re_lb.s2); + /* 14 for the string, 22 for the numbers */ + if(str - bufstart + 14 + 22 < BUFSIZ) + (void) sprintf(str, + "; s1 = %lu, s2 = %lu", + (unsigned long) e.re_lb.s1, + (unsigned long) e.re_lb.s2); str += strlen(str); break; } - (void) sprintf(str, "\n"); + if(str - bufstart + 1 < BUFSIZ) + (void) sprintf(str, "\n"); return(strstart) ; } @@ -238,26 +257,29 @@ clnt_spcreateerror(s) if (str == 0) return(0); (void) sprintf(str, "%s: ", s); - (void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat)); + str[BUFSIZ - 1] = '\0'; + (void) strncat(str, clnt_sperrno(rpc_createerr.cf_stat), BUFSIZ - 1); switch (rpc_createerr.cf_stat) { case RPC_PMAPFAILURE: - (void) strcat(str, " - "); - (void) strcat(str, - clnt_sperrno(rpc_createerr.cf_error.re_status)); + (void) strncat(str, " - ", BUFSIZ - 1 - strlen(str)); + (void) strncat(str, + clnt_sperrno(rpc_createerr.cf_error.re_status), + BUFSIZ - 1 - strlen(str)); break; case RPC_SYSTEMERROR: - (void) strcat(str, " - "); + (void) strncat(str, " - ", BUFSIZ - 1 - strlen(str)); if (rpc_createerr.cf_error.re_errno > 0 && rpc_createerr.cf_error.re_errno < sys_nerr) - (void) strcat(str, - sys_errlist[rpc_createerr.cf_error.re_errno]); + (void) strncat(str, + sys_errlist[rpc_createerr.cf_error.re_errno], + BUFSIZ - 1 - strlen(str)); else (void) sprintf(&str[strlen(str)], "Error %d", rpc_createerr.cf_error.re_errno); break; } - (void) strcat(str, "\n"); + (void) strncat(str, "\n", BUFSIZ - 1 - strlen(str)); return (str); } diff --git a/src/lib/rpc/clnt_simple.c b/src/lib/rpc/clnt_simple.c index b3d2eb3..2f203d7 100644 --- a/src/lib/rpc/clnt_simple.c +++ b/src/lib/rpc/clnt_simple.c @@ -70,6 +70,8 @@ gssrpc_callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) } if (crp->oldhost == NULL) { crp->oldhost = mem_alloc(256); + if (crp->oldhost == 0) + return 0; crp->oldhost[0] = 0; crp->socket = RPC_ANYSOCK; } @@ -98,7 +100,8 @@ gssrpc_callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) crp->valid = 1; crp->oldprognum = prognum; crp->oldversnum = versnum; - (void) strcpy(crp->oldhost, host); + (void) strncpy(crp->oldhost, host, 255); + crp->oldhost[255] = '\0'; } tottimeout.tv_sec = 25; tottimeout.tv_usec = 0; diff --git a/src/lib/rpc/clnt_tcp.c b/src/lib/rpc/clnt_tcp.c index 4e10a48..f87da78 100644 --- a/src/lib/rpc/clnt_tcp.c +++ b/src/lib/rpc/clnt_tcp.c @@ -116,7 +116,7 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) unsigned int recvsz; { CLIENT *h; - register struct ct_data *ct; + register struct ct_data *ct = 0; struct timeval now; struct rpc_msg call_msg; diff --git a/src/lib/rpc/clnt_udp.c b/src/lib/rpc/clnt_udp.c index 6046942..df3945a 100644 --- a/src/lib/rpc/clnt_udp.c +++ b/src/lib/rpc/clnt_udp.c @@ -117,7 +117,7 @@ clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) unsigned int recvsz; { CLIENT *cl; - register struct cu_data *cu; + register struct cu_data *cu = 0; struct timeval now; struct rpc_msg call_msg; diff --git a/src/lib/rpc/get_myaddress.c b/src/lib/rpc/get_myaddress.c index 4c9bf29..13bafa0 100644 --- a/src/lib/rpc/get_myaddress.c +++ b/src/lib/rpc/get_myaddress.c @@ -81,7 +81,7 @@ get_myaddress(addr) struct sockaddr_in *addr; { int s; - char buf[BUFSIZ]; + char buf[256 * sizeof (struct ifconf)]; struct ifconf ifc; struct ifreq ifreq, *ifr; int len; diff --git a/src/lib/rpc/pmap_rmt.c b/src/lib/rpc/pmap_rmt.c index 7cafe6e..dc9735d 100644 --- a/src/lib/rpc/pmap_rmt.c +++ b/src/lib/rpc/pmap_rmt.c @@ -165,6 +165,8 @@ xdr_rmtcallres(xdrs, crp) * routines which only support udp/ip . */ +#define GIFCONF_BUFSIZE (256 * sizeof (struct ifconf)) + static int getbroadcastnets(addrs, sock, buf) struct in_addr *addrs; @@ -176,8 +178,9 @@ getbroadcastnets(addrs, sock, buf) struct sockaddr_in *sin; int n, i; - ifc.ifc_len = UDPMSGSIZE; + ifc.ifc_len = GIFCONF_BUFSIZE; ifc.ifc_buf = buf; + memset (buf, 0, GIFCONF_BUFSIZE); if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { perror("broadcast: ioctl (get interface configuration)"); return (0); @@ -255,7 +258,11 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) struct rmtcallres r; struct rpc_msg msg; struct timeval t; - char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE]; + char outbuf[MAX_BROADCAST_SIZE]; +#ifndef MAX +#define MAX(A,B) ((A)<(B)?(B):(A)) +#endif + char inbuf[MAX (UDPMSGSIZE, GIFCONF_BUFSIZE)]; /* * initialization: create a socket, a broadcast address, and diff --git a/src/lib/rpc/svc_auth_gssapi.c b/src/lib/rpc/svc_auth_gssapi.c index 827596a..34ee0ef 100644 --- a/src/lib/rpc/svc_auth_gssapi.c +++ b/src/lib/rpc/svc_auth_gssapi.c @@ -134,7 +134,6 @@ enum auth_stat _svcauth_gssapi(rqst, msg, no_dispatch) svc_auth_gssapi_data *client_data; int ret_flags, ret, i; rpc_u_int32 seq_num; - int flag; PRINTF(("svcauth_gssapi: starting\n")); @@ -307,8 +306,6 @@ enum auth_stat _svcauth_gssapi(rqst, msg, no_dispatch) #endif if (call_arg.version >= 3) { - int len; - memset(&bindings, 0, sizeof(bindings)); bindings.application_data.length = 0; bindings.initiator_addrtype = GSS_C_AF_INET; @@ -657,7 +654,6 @@ static svc_auth_gssapi_data *create_client() client_list *c; svc_auth_gssapi_data *client_data; static int client_key = 1; - int ret; PRINTF(("svcauth_gssapi: empty creds, creating\n")); @@ -665,7 +661,7 @@ static svc_auth_gssapi_data *create_client() if (client_data == NULL) return NULL; memset((char *) client_data, 0, sizeof(*client_data)); - L_PRINTF(2, ("create_client: new client_data = %#x\n", client_data)); + L_PRINTF(2, ("create_client: new client_data = %p\n", client_data)); /* set up client data structure */ client_data->established = 0; @@ -783,10 +779,9 @@ static void destroy_client(client_data) OM_uint32 gssstat, minor_stat; gss_buffer_desc out_buf; client_list *c, *c2; - int ret; PRINTF(("destroy_client: destroying client_data\n")); - L_PRINTF(2, ("destroy_client: client_data = %#x\n", client_data)); + L_PRINTF(2, ("destroy_client: client_data = %p\n", client_data)); #ifdef DEBUG_GSSAPI if (svc_debug_gssapi >= 3) @@ -852,7 +847,7 @@ static void dump_db(msg) c = clients; while (c) { client_data = c->client; - L_PRINTF(3, ("\tclient_data = %#x, exp = %d\n", + L_PRINTF(3, ("\tclient_data = %p, exp = %d\n", client_data, client_data->expiration)); c = c->next; } @@ -871,7 +866,7 @@ static void clean_client() while (c) { client_data = c->client; - L_PRINTF(2, ("clean_client: client_data = %#x\n", + L_PRINTF(2, ("clean_client: client_data = %p\n", client_data)); if (client_data->expiration < time(0)) { @@ -884,7 +879,6 @@ static void clean_client() } } -done: PRINTF(("clean_client: done\n")); } diff --git a/src/lib/rpc/unit-test/ChangeLog b/src/lib/rpc/unit-test/ChangeLog index 1c3d401..7835f0b 100644 --- a/src/lib/rpc/unit-test/ChangeLog +++ b/src/lib/rpc/unit-test/ChangeLog @@ -1,3 +1,9 @@ +2000-06-08 Tom Yu <tlyu@mit.edu> + + * lib/helpers.exp (kinit): Move "expect eof" into the commands + that send the prompt. Don't "expect eof" outside of the main + expect, as the main expect may have already read eof. + 2000-02-15 Tom Yu <tlyu@mit.edu> * server.c: Add code to set a signal handler for SIGHUP and a few diff --git a/src/lib/win_glue.c b/src/lib/win_glue.c index ab3e1a1..6dc9e10 100644 --- a/src/lib/win_glue.c +++ b/src/lib/win_glue.c @@ -90,8 +90,13 @@ extern void krb5_stdcc_shutdown(); * arbitrary third party applications. If there is an error, or we * decide that we should not version check the calling application * then VSflag will be FALSE when the function returns. + * + * The buffers passed into this function must be at least + * APPVERINFO_SIZE bytes long. */ - + +#define APPVERINFO_SIZE 256 + void GetCallingAppVerInfo( char *AppTitle, char *AppVer, char *AppIni, BOOL *VSflag) { @@ -187,11 +192,15 @@ void GetCallingAppVerInfo( char *AppTitle, char *AppVer, char *AppIni, * We don't have a way to determine that INI file of the * application at the moment so let's just use krb5.ini */ - strcpy( locAppIni, KERBEROS_INI ); + strncpy( locAppIni, KERBEROS_INI, sizeof(locAppIni) - 1 ); + locAppIni[ sizeof(locAppIni) - 1 ] = '\0'; - strcpy( AppTitle, locAppTitle); - strcpy( AppVer, locAppVer); - strcpy( AppIni, locAppIni); + strncpy( AppTitle, locAppTitle, APPVERINFO_SIZE); + AppTitle[APPVERINFO_SIZE - 1] = '\0'; + strncpy( AppVer, locAppVer, APPVERINFO_SIZE); + AppVer[APPVERINFO_SIZE - 1] = '\0'; + strncpy( AppIni, locAppIni, APPVERINFO_SIZE); + AppIni[APPVERINFO_SIZE - 1] = '\0'; /* * We also need to determine if we want to suppress version @@ -271,9 +280,10 @@ static krb5_error_code do_timebomb() if (first_time) { sprintf(buf, "Your version of %s has expired.\n", TIMEBOMB_PRODUCT); - strcat(buf, "Please upgrade it."); + buf[sizeof(buf) - 1] = '\0'; + strncat(buf, "Please upgrade it.", sizeof(buf) - 1 - strlen(buf)); #ifdef TIMEBOMB_INFO - strcat(buf, TIMEBOMB_INFO); + strncat(buf, TIMEBOMB_INFO, sizeof(buf) - 1 - strlen(buf)); #endif MessageBox(NULL, buf, "", MB_OK); first_time = 0; @@ -285,9 +295,9 @@ static krb5_error_code do_timebomb() if (first_time) { sprintf(buf, "Your version of %s will expire in %ld days.\n", TIMEBOMB_PRODUCT, timeleft); - strcat(buf, "Please upgrade it soon."); + strncat(buf, "Please upgrade it soon.", sizeof(buf) - 1 - strlen(buf)); #ifdef TIMEBOMB_INFO - strcat(buf, TIMEBOMB_INFO); + strncat(buf, TIMEBOMB_INFO, sizeof(buf) - 1 - strlen(buf)); #endif MessageBox(NULL, buf, "", MB_OK); first_time = 0; @@ -323,9 +333,9 @@ krb5_error_code krb5_vercheck() if (CallVersionServer(APP_TITLE, APP_VER, APP_INI, NULL)) return VERSERV_ERROR; #else - char AppTitle[256]; - char AppVer[256]; - char AppIni[256]; + char AppTitle[APPVERINFO_SIZE]; + char AppVer[APPVERINFO_SIZE]; + char AppIni[APPVERINFO_SIZE]; BOOL VSflag=TRUE; GetCallingAppVerInfo( AppTitle, AppVer, AppIni, &VSflag); diff --git a/src/mac/K5Library.exp b/src/mac/K5Library.exp index cf710dc..a27d776 100644 --- a/src/mac/K5Library.exp +++ b/src/mac/K5Library.exp @@ -33,6 +33,7 @@ krb5_free_creds krb5_free_data krb5_free_data_contents + krb5_free_default_realm krb5_free_enc_kdc_rep_part krb5_free_enc_tkt_part krb5_free_error @@ -41,6 +42,7 @@ krb5_free_kdc_req krb5_free_keyblock krb5_free_keyblock_contents + krb5_free_ktypes krb5_free_last_req krb5_free_pa_data krb5_free_principal @@ -77,7 +79,11 @@ krb5_get_init_creds_password krb5_get_init_creds_keytab krb5_get_init_creds_opt_init + krb5_get_validated_creds + krb5_get_renewed_creds krb5_get_notification_message + krb5_get_tgs_ktypes + krb5_get_time_offsets krb5_init_context krb5_mk_error krb5_mk_priv @@ -88,6 +94,7 @@ krb5_os_localaddr krb5_parse_name krb5_principal_compare + krb5_get_prompt_types krb5_rd_cred krb5_rd_error krb5_rd_priv @@ -121,16 +128,6 @@ krb5_finish_random_key krb5_random_key # - krb5_c_decrypt - krb5_c_encrypt - krb5_c_encrypt_length - krb5_c_checksum_length - krb5_c_block_size - krb5_c_make_checksum - krb5_c_verify_checksum - krb5_c_random_make_octets - krb5_c_keyed_checksum_types -# krb5_425_conv_principal krb5_524_conv_principal # @@ -193,31 +190,32 @@ # krb5_cc_set_default_name # - krb5_rc_default - krb5_rc_register_type - krb5_rc_resolve_type - krb5_rc_resolve_full - krb5_rc_get_type - krb5_rc_default_type - krb5_rc_default_name - krb5_auth_to_rep -# krb5_get_profile +# +# Added for 1.2: + krb5_decode_ticket #Temporary exports (DO NOT USE) - decode_krb5_ticket # remove in next version - krb5_random_confounder - krb5_size_opaque - krb5_internalize_opaque - krb5_externalize_opaque - krb5_ser_pack_int32 - krb5_ser_unpack_int32 - krb5_ser_pack_bytes - krb5_ser_unpack_bytes - krb5_ser_auth_context_init - krb5_ser_context_init - krb5_ser_ccache_init - krb5_ser_keytab_init - krb5_ser_rcache_init - decode_krb5_ap_req # remove in next version - krb5_mcc_ops + krb5_size_opaque # GSSAPI + krb5_internalize_opaque # GSSAPI + krb5_externalize_opaque # GSSAPI + krb5_ser_pack_int32 # GSSAPI + krb5_ser_unpack_int32 # GSSAPI + krb5_ser_pack_bytes # GSSAPI + krb5_ser_unpack_bytes # GSSAPI + krb5_ser_auth_context_init # GSSAPI + krb5_ser_context_init # GSSAPI + krb5_ser_ccache_init # GSSAPI + krb5_ser_keytab_init # GSSAPI + krb5_ser_rcache_init # GSSAPI + decode_krb5_ap_req # GSSAPI + krb5_mcc_ops # GSSAPI + krb5_c_keyed_checksum_types # GSSAPI + krb5_c_random_make_octets # GSSAPI + krb5_c_encrypt # GSSAPI + krb5_c_make_checksum # GSSAPI + krb5_c_decrypt # GSSAPI + krb5_c_verify_checksum # GSSAPI + krb5_c_block_size # GSSAPI + krb5_c_checksum_length # GSSAPI + krb5_c_encrypt_length # GSSAPI
\ No newline at end of file diff --git a/src/mac/Kerberos5Lib.exp b/src/mac/Kerberos5Lib.exp new file mode 100644 index 0000000..a98f2d1 --- /dev/null +++ b/src/mac/Kerberos5Lib.exp @@ -0,0 +1,191 @@ +#---------------------------------------------------- +# Kerberos5Lib.exp +# +# Public Kerberos v5 API +#---------------------------------------------------- + +# Kerberos 5 + krb5_build_principal + krb5_build_principal_ext + krb5_copy_addr + krb5_copy_addresses + krb5_copy_authdata + krb5_copy_authenticator + krb5_copy_checksum + krb5_copy_creds + krb5_copy_data + krb5_copy_keyblock + krb5_copy_keyblock_contents + krb5_copy_principal + krb5_copy_ticket + krb5_decrypt_tkt_part + krb5_free_address + krb5_free_addresses + krb5_free_ap_rep + krb5_free_ap_rep_enc_part + krb5_free_ap_req + krb5_free_authdata + krb5_free_authenticator + krb5_free_authenticator_contents + krb5_free_checksum + krb5_free_context + krb5_free_cred + krb5_free_cred_contents + krb5_free_cred_enc_part + krb5_free_creds + krb5_free_data + krb5_free_data_contents + krb5_free_default_realm + krb5_free_enc_kdc_rep_part + krb5_free_enc_tkt_part + krb5_free_error + krb5_free_host_realm + krb5_free_kdc_rep + krb5_free_kdc_req + krb5_free_keyblock + krb5_free_keyblock_contents + krb5_free_last_req + krb5_free_pa_data + krb5_free_principal + krb5_free_priv + krb5_free_priv_enc_part + krb5_free_pwd_data + krb5_free_pwd_sequences + krb5_free_safe + krb5_free_tgt_creds + krb5_free_ticket + krb5_free_tickets + krb5_free_tkt_authent + krb5_free_checksum_contents + krb5_free_cksumtypes + krb5_fwd_tgt_creds + krb5_get_credentials + krb5_get_credentials_renew + krb5_get_credentials_validate + krb5_get_default_realm + krb5_get_host_realm + krb5_get_in_tkt + krb5_get_in_tkt_with_keytab + krb5_get_in_tkt_with_password + krb5_get_in_tkt_with_skey + krb5_get_init_creds_opt_init + krb5_get_init_creds_opt_set_tkt_life + krb5_get_init_creds_opt_set_renew_life + krb5_get_init_creds_opt_set_forwardable + krb5_get_init_creds_opt_set_proxiable + krb5_get_init_creds_opt_set_etype_list + krb5_get_init_creds_opt_set_address_list + krb5_get_init_creds_opt_set_preauth_list + krb5_get_init_creds_opt_set_salt + krb5_get_init_creds_password + krb5_get_init_creds_keytab + krb5_get_init_creds_opt_init + krb5_get_validated_creds + krb5_get_renewed_creds + krb5_get_notification_message + krb5_get_time_offsets + krb5_init_context + krb5_mk_error + krb5_mk_priv + krb5_mk_rep + krb5_mk_req + krb5_mk_req_extended + krb5_mk_safe + krb5_os_localaddr + krb5_parse_name + krb5_principal_compare + krb5_get_prompt_types + krb5_rd_cred + krb5_rd_error + krb5_rd_priv + krb5_rd_rep + krb5_rd_req + krb5_rd_safe + krb5_read_password + krb5_recvauth + krb5_sendauth + krb5_sname_to_principal + krb5_timeofday + krb5_unparse_name + krb5_unparse_name_ext + krb5_free_unparsed_name + krb5_us_timeofday + krb5_get_server_rcache +# + krb5_use_enctype + krb5_checksum_size + krb5_encrypt_size + krb5_calculate_checksum + krb5_verify_checksum + krb5_eblock_enctype +# + krb5_decrypt + krb5_encrypt + krb5_string_to_key + krb5_process_key + krb5_finish_key + krb5_init_random_key + krb5_finish_random_key + krb5_random_key +# + krb5_425_conv_principal + krb5_524_conv_principal +# + krb5_cksumtype_to_string + krb5_deltat_to_string + krb5_enctype_to_string + krb5_salttype_to_string + krb5_string_to_cksumtype + krb5_string_to_deltat + krb5_string_to_enctype + krb5_string_to_salttype + krb5_string_to_timestamp + krb5_timestamp_to_sfstring + krb5_timestamp_to_string +# + krb5_auth_con_init + krb5_auth_con_free + krb5_auth_con_setflags + krb5_auth_con_getflags + krb5_auth_con_setaddrs + krb5_auth_con_getaddrs + krb5_auth_con_setports + krb5_auth_con_setuseruserkey + krb5_auth_con_getkey + krb5_auth_con_getlocalsubkey + krb5_auth_con_set_req_cksumtype + krb5_auth_con_set_safe_cksumtype +# krb5_auth_con_getcksumtype Why is this missing from sources? + krb5_auth_con_getlocalseqnumber + krb5_auth_con_getremoteseqnumber + krb5_auth_con_initivector + krb5_auth_con_getivector + krb5_auth_con_setivector + krb5_auth_con_setrcache + krb5_auth_con_getrcache + krb5_auth_con_getremotesubkey + krb5_auth_con_getauthenticator + krb5_auth_con_genaddrs +# + krb5_cc_default + krb5_cc_default_name + krb5_cc_register + krb5_cc_resolve +# + krb5_kt_default + krb5_kt_register + krb5_kt_resolve + krb5_kt_add_entry + krb5_kt_free_entry + krb5_kt_read_service_key + krb5_kt_remove_entry + +# + krb5_change_password +# + krb5_cc_set_default_name +# + krb5_get_profile +# +# Added for 1.2: + krb5_decode_ticket diff --git a/src/mac/Makefile b/src/mac/Makefile index 95cc9ba..a942317 100644 --- a/src/mac/Makefile +++ b/src/mac/Makefile @@ -42,37 +42,44 @@ unset-echo Ä ############################################################################################################## gss-library-output-folder = {root-folder}:GSSLib:Binaries: +privatekrb5-library-output-folder = {root-folder}:Kerberos5Lib:Binaries: krb5-library-output-folder = {root-folder}:Kerberos5Lib:Binaries: profile-library-output-folder = {root-folder}:KerberosProfileLib:Binaries: comerr-library-output-folder = {root-folder}:ComErrLib:Binaries: gss-library-name = GSSLib +privatekrb5-library-name = PrivateKrb5Lib krb5-library-name = Kerberos5Lib profile-library-name = KrbProfileLib comerr-library-name = ComErrLib gss-library-export = {root-folder}mac:GSSLibrary.exp -krb5-library-export = {root-folder}mac:K5Library.exp +privatekrb5-library-export = {root-folder}mac:PrivateKerberos5Lib.exp +krb5-library-export = {root-folder}mac:Kerberos5Lib.exp profile-library-export = {root-folder}util:profile:profile.exp comerr-library-export = {root-folder}util:et:et.exp gss-library-fragment-name = "GSSLibrary" +privatekrb5-library-fragment-name = "MIT Kerberos¥PrivateKerberos5Lib" krb5-library-fragment-name = "MIT Kerberos¥Kerberos5Lib" profile-library-fragment-name = "MIT Kerberos¥KerberosProfileLib" comerr-library-fragment-name = "MIT Kerberos¥ComErrLib" gss-library-main = ¶"¶" +privatekrb5-library-main = ¶"¶" krb5-library-main = ¶"¶" profile-library-main = ¶"¶" comerr-library-main = ¶"¶" gss-library-init = __initializeGSS -krb5-library-init = __initializeK5 +privatekrb5-library-init = __initializeK5 +krb5-library-init = ¶"¶" profile-library-init = InitializeProfileLib comerr-library-init = __initialize gss-library-term = __terminateGSS -krb5-library-term = __terminateK5 +privatekrb5-library-term = __terminateK5 +krb5-library-term = ¶"¶" profile-library-term = TerminateProfileLib comerr-library-term = __terminate @@ -80,9 +87,13 @@ gss-library-current-version = 1 gss-library-definition-version = 0 gss-library-implementation-version = 1 -krb5-library-current-version = 2 -krb5-library-definition-version = 2 -krb5-library-implementation-version = 2 +privatekrb5-library-current-version = 5 +privatekrb5-library-definition-version = 5 +privatekrb5-library-implementation-version = 5 + +krb5-library-current-version = 5 +krb5-library-definition-version = 5 +krb5-library-implementation-version = 5 profile-library-current-version = 0 profile-library-definition-version = 0 @@ -393,39 +404,57 @@ standard-libraries-ppc-final = ¶ ccachelib-ppc-debug = {mitkerberoslib-root-folder}CCacheLib:Binaries:CCacheLib.PPC.debug ccachelib-ppc-final = {mitkerberoslib-root-folder}CCacheLib:Binaries:CCacheLib.PPC +loginlib-ppc-debug = {mitkerberoslib-root-folder}LoginLib:Binaries:KrbLoginLib.stub.PPC.debug +loginlib-ppc-final = {mitkerberoslib-root-folder}LoginLib:Binaries:KrbLoginLib.stub.PPC + +preferenceslib-ppc-debug = {mitkerberoslib-root-folder}PreferencesLib:Binaries:PreferencesLib.PPC.debug +preferenceslib-ppc-final = {mitkerberoslib-root-folder}PreferencesLib:Binaries:PreferencesLib.PPC + socketslib-ppc-debug = {mitsupportlib-root-folder}SocketsLib:Binaries:SocketsLib.PPC.debug socketslib-ppc-final = {mitsupportlib-root-folder}SocketsLib:Binaries:SocketsLib.PPC errorlib-ppc-debug = {mitsupportlib-root-folder}ErrorLib:Binaries:ErrorLib.PPC.debug errorlib-ppc-final = {mitsupportlib-root-folder}ErrorLib:Binaries:ErrorLib.PPC +utilitieslib-ppc-debug = {mitsupportlib-root-folder}UtilitiesLib:Binaries:UtilitiesLib.PPC.debug +utilitieslib-ppc-final = {mitsupportlib-root-folder}UtilitiesLib:Binaries:UtilitiesLib.PPC + object-suffix-ppc-debug = .ppcd.o object-suffix-ppc-final = .ppcf.o object-suffix-ppc-data = .ppc.o gss-library-libraries-ppc-debug = ¶ {standard-libraries-ppc-debug} ¶ - {krb5-library-output-folder}{krb5-library-name}{library-platform-ppc}{library-kind-debug} ¶ + {privatekrb5-library-output-folder}{privatekrb5-library-name}{library-platform-ppc}{library-kind-debug} ¶ {profile-library-output-folder}{profile-library-name}{library-platform-ppc}{library-kind-debug} ¶ {comerr-library-output-folder}{comerr-library-name}{library-platform-ppc}{library-kind-debug} gss-library-libraries-ppc-final = ¶ {standard-libraries-ppc-final} ¶ - {krb5-library-output-folder}{krb5-library-name}{library-platform-ppc}{library-kind-final} ¶ + {privatekrb5-library-output-folder}{privatekrb5-library-name}{library-platform-ppc}{library-kind-final} ¶ {profile-library-output-folder}{profile-library-name}{library-platform-ppc}{library-kind-final} ¶ {comerr-library-output-folder}{comerr-library-name}{library-platform-ppc}{library-kind-final} krb5-library-libraries-ppc-debug = ¶ + {privatekrb5-library-output-folder}{privatekrb5-library-name}{library-platform-ppc}{library-kind-debug} +krb5-library-libraries-ppc-final = ¶ + {privatekrb5-library-output-folder}{privatekrb5-library-name}{library-platform-ppc}{library-kind-final} + +privatekrb5-library-libraries-ppc-debug = ¶ {standard-libraries-ppc-debug} ¶ {ccachelib-ppc-debug} ¶ + {preferenceslib-ppc-debug} ¶ + {loginlib-ppc-debug} ¶ {socketslib-ppc-debug} ¶ {errorlib-ppc-debug} ¶ {profile-library-output-folder}{profile-library-name}{library-platform-ppc}{library-kind-debug} ¶ {comerr-library-output-folder}{comerr-library-name}{library-platform-ppc}{library-kind-debug} ¶ ¶"{PPCLibraries}PPCMath64Lib.o¶" ¶ ¶"{SharedLibraries}DriverServicesLib¶" -krb5-library-libraries-ppc-final = ¶ +privatekrb5-library-libraries-ppc-final = ¶ {standard-libraries-ppc-final} ¶ {ccachelib-ppc-final} ¶ + {preferenceslib-ppc-final} ¶ + {loginlib-ppc-final} ¶ {socketslib-ppc-final} ¶ {errorlib-ppc-final} ¶ {profile-library-output-folder}{profile-library-name}{library-platform-ppc}{library-kind-final} ¶ @@ -435,9 +464,11 @@ krb5-library-libraries-ppc-final = ¶ profile-library-libraries-ppc-debug = ¶ {standard-libraries-ppc-debug} ¶ + {utilitieslib-ppc-debug} ¶ {comerr-library-output-folder}{comerr-library-name}{library-platform-ppc}{library-kind-debug} profile-library-libraries-ppc-final = ¶ {standard-libraries-ppc-final} ¶ + {utilitieslib-ppc-final} ¶ {comerr-library-output-folder}{comerr-library-name}{library-platform-ppc}{library-kind-final} comerr-library-libraries-ppc-debug = ¶ @@ -464,8 +495,16 @@ krb5-library-common-linker-options = ¶ -dv {krb5-library-definition-version} ¶ -uv {krb5-library-implementation-version} -krb5-library-linker-options-ppc-debug = {common-linker-options-debug} {krb5-library-common-linker-options} -weaklib "DriverServicesLib" -krb5-library-linker-options-ppc-final = {common-linker-options-final} {krb5-library-common-linker-options} -weaklib "DriverServicesLib" +krb5-library-linker-options-ppc-debug = {common-linker-options-debug} {krb5-library-common-linker-options} +krb5-library-linker-options-ppc-final = {common-linker-options-final} {krb5-library-common-linker-options} + +privatekrb5-library-common-linker-options = ¶ + -cv {privatekrb5-library-current-version} ¶ + -dv {privatekrb5-library-definition-version} ¶ + -uv {privatekrb5-library-implementation-version} + +privatekrb5-library-linker-options-ppc-debug = {common-linker-options-debug} {privatekrb5-library-common-linker-options} -weaklib "DriverServicesLib" +privatekrb5-library-linker-options-ppc-final = {common-linker-options-final} {privatekrb5-library-common-linker-options} -weaklib "DriverServicesLib" profile-library-common-linker-options = ¶ -cv {profile-library-current-version} ¶ @@ -488,9 +527,9 @@ gss-library-objects-ppc-debug = `catenate {gss-objects-ppc-debug-list} | StreamE gss-library-objects-ppc-final = `catenate {gss-objects-ppc-final-list} | StreamEdit -d -set prefix="{root-folder}" -e "/¥:(Å)¨2/ Print prefix¨2"` ¶ {root-folder}mac:GSS.CFM{object-suffix-ppc-final} -krb5-library-objects-ppc-debug = `catenate {krb5-objects-ppc-debug-list} | StreamEdit -d -set prefix="{root-folder}" -e "/¥:(Å)¨2/ Print prefix¨2"` ¶ +privatekrb5-library-objects-ppc-debug = `catenate {krb5-objects-ppc-debug-list} | StreamEdit -d -set prefix="{root-folder}" -e "/¥:(Å)¨2/ Print prefix¨2"` ¶ {root-folder}mac:K5.CFM{object-suffix-ppc-debug} -krb5-library-objects-ppc-final = `catenate {krb5-objects-ppc-final-list} | StreamEdit -d -set prefix="{root-folder}" -e "/¥:(Å)¨2/ Print prefix¨2"` ¶ +privatekrb5-library-objects-ppc-final = `catenate {krb5-objects-ppc-final-list} | StreamEdit -d -set prefix="{root-folder}" -e "/¥:(Å)¨2/ Print prefix¨2"` ¶ {root-folder}mac:K5.CFM{object-suffix-ppc-final} profile-library-objects-ppc-debug = `catenate {profile-objects-ppc-debug-list} | StreamEdit -d -set prefix="{root-folder}" -e "/¥:(Å)¨2/ Print prefix¨2"` ¶ @@ -523,6 +562,8 @@ mitsupportlib-include-paths = ¶ include-paths = `catenate {include-folders-list} | StreamEdit -d -set prefix="{root-folder}mac:" -e "/-i (Å)¨1/ Print '-i 'prefix¨1"` ¶ -i {mitkerberoslib-root-folder}CCacheLib:Headers: ¶ + -i {mitkerberoslib-root-folder}LoginLib:Headers: ¶ + -i {mitkerberoslib-root-folder}PreferencesLib:Headers: ¶ {mitsupportlib-include-paths} compiler-options-ppc-debug = {include-paths} {common-compiler-options} {ppc-compiler-options} ¶ @@ -562,6 +603,13 @@ make-options-common = ¶ -d krb5-library-main="{krb5-library-main}" ¶ -d krb5-library-init="{krb5-library-init}" ¶ -d krb5-library-term="{krb5-library-term}" ¶ + -d privatekrb5-library-output-folder="{privatekrb5-library-output-folder}" ¶ + -d privatekrb5-library-name="{privatekrb5-library-name}" ¶ + -d privatekrb5-library-export="{privatekrb5-library-export}" ¶ + -d privatekrb5-library-fragment-name={privatekrb5-library-fragment-name} ¶ + -d privatekrb5-library-main="{privatekrb5-library-main}" ¶ + -d privatekrb5-library-init="{privatekrb5-library-init}" ¶ + -d privatekrb5-library-term="{privatekrb5-library-term}" ¶ -d profile-library-output-folder="{profile-library-output-folder}" ¶ -d profile-library-name="{profile-library-name}" ¶ -d profile-library-export="{profile-library-export}" ¶ @@ -587,6 +635,9 @@ make-options-ppc-debug = ¶ -d krb5-library-libraries="{krb5-library-libraries-ppc-debug}" ¶ -d krb5-library-objects="{krb5-library-objects-ppc-debug}" ¶ -d krb5-library-linker-options="{krb5-library-linker-options-ppc-debug}" ¶ + -d privatekrb5-library-libraries="{privatekrb5-library-libraries-ppc-debug}" ¶ + -d privatekrb5-library-objects="{privatekrb5-library-objects-ppc-debug}" ¶ + -d privatekrb5-library-linker-options="{privatekrb5-library-linker-options-ppc-debug}" ¶ -d profile-library-libraries="{profile-library-libraries-ppc-debug}" ¶ -d profile-library-objects="{profile-library-objects-ppc-debug}" ¶ -d profile-library-linker-options="{profile-library-linker-options-ppc-debug}" ¶ @@ -609,6 +660,9 @@ make-options-ppc-final = ¶ -d krb5-library-libraries="{krb5-library-libraries-ppc-final}" ¶ -d krb5-library-objects="{krb5-library-objects-ppc-final}" ¶ -d krb5-library-linker-options="{krb5-library-linker-options-ppc-final}" ¶ + -d privatekrb5-library-libraries="{privatekrb5-library-libraries-ppc-final}" ¶ + -d privatekrb5-library-objects="{privatekrb5-library-objects-ppc-final}" ¶ + -d privatekrb5-library-linker-options="{privatekrb5-library-linker-options-ppc-final}" ¶ -d profile-library-libraries="{profile-library-libraries-ppc-final}" ¶ -d profile-library-objects="{profile-library-objects-ppc-final}" ¶ -d profile-library-linker-options="{profile-library-linker-options-ppc-final}" ¶ @@ -622,17 +676,23 @@ make-options-ppc-final = ¶ -d precompiled-headers="{precompiled-headers-ppc}" make-output = "{TempFolder}GSS/Kerberos Makefile script" -submakefile-target = gss-library +submakefile-gss-target = gss-library +submakefile-krb5-target = krb5-library ppc-debug Ä glue headers documentation {makefile-name} {gss-objects-ppc-debug-list} {krb5-objects-ppc-debug-list} ¶ {profile-objects-ppc-debug-list} {comerr-objects-ppc-debug-list} {include-folders-list} - Make {make-options-common} {make-options-ppc-debug} {submakefile-target} > {make-output} + Make {make-options-common} {make-options-ppc-debug} {submakefile-gss-target} > {make-output} + {make-output} + Make {make-options-common} {make-options-ppc-debug} {submakefile-krb5-target} > {make-output} {make-output} ppc-final Ä glue headers documentation {makefile-name} {gss-objects-ppc-final-list} {krb5-objects-ppc-final-list} ¶ {profile-objects-ppc-final-list} {comerr-objects-ppc-final-list} {include-folders-list} - Make {make-options-common} {make-options-ppc-final} {submakefile-target} > {make-output} + Make {make-options-common} {make-options-ppc-final} {submakefile-gss-target} > {make-output} {make-output} + Make {make-options-common} {make-options-ppc-final} {submakefile-krb5-target} > {make-output} + {make-output} + ############################################################################################################## ### Variable targets -- these depend on which target we select in the above make invocations @@ -660,6 +720,17 @@ ppc-final Ä glue headers documentation {makefile-name} {gss-objects-ppc-final-l ### krb5-library-init -- name of Krb5 library initialization routine ### krb5-library-term -- name of Krb5 library termination routine ### krb5-library-linker-options -- all other Krb5 library linker options +### For PrivateKrb5 library +### privatekrb5-library-output-folder -- destination of PrivateKrb5 library output +### privatekrb5-library-name -- name of the PrivateKrb5 library +### privatekrb5-library-export -- name of PrivateKrb5 library export file +### privatekrb5-library-libraries -- list of libraries PrivateKrb5 library links against +### privatekrb5-library-objects -- list of object files PrivateKrb5 library links +### privatekrb5-library-fragment-name -- name of PrivateKrb5 library fragment +### privatekrb5-library-main -- name of PrivateKrb5 library main entry point +### privatekrb5-library-init -- name of PrivateKrb5 library initialization routine +### privatekrb5-library-term -- name of PrivateKrb5 library termination routine +### privatekrb5-library-linker-options -- all other PrivateKrb5 library linker options ### For profile library ### profile-library-output-folder -- destination of profile library output ### profile-library-name -- name of the profile library @@ -703,6 +774,9 @@ gss-library-linker-options = krb5-library-libraries = krb5-library-objects = krb5-library-linker-options = +privatekrb5-library-libraries = +privatekrb5-library-objects = +privatekrb5-library-linker-options = precompiled-headers = object-suffix = .ignore.me object-suffix-data = .ignore.me.too @@ -746,6 +820,23 @@ krb5-library-build-command = ¶ {krb5-library-linker-options} ¶ {krb5-library-objects} {krb5-library-libraries} +privatekrb5-library-output-files = ¶ + {privatekrb5-library-output-folder}{privatekrb5-library-name}{library-platform}{library-kind} +privatekrb5-library-dependencies = ¶ + {autogenerated-files} {privatekrb5-library-export} {privatekrb5-library-libraries} {privatekrb5-library-objects} +privatekrb5-library-build-command = ¶ + {library-linker} ¶ + -name "{privatekrb5-library-fragment-name}{library-kind}" ¶ + -main {privatekrb5-library-main} ¶ + -init {privatekrb5-library-init} ¶ + -term {privatekrb5-library-term} ¶ + -@export {privatekrb5-library-export} ¶ + -@export {krb5-library-export} ¶ + -map {privatekrb5-library-output-folder}{privatekrb5-library-name}{library-platform}{library-kind}.MAP ¶ + -o {privatekrb5-library-output-folder}{privatekrb5-library-name}{library-platform}{library-kind} ¶ + {privatekrb5-library-linker-options} ¶ + {privatekrb5-library-objects} {privatekrb5-library-libraries} + profile-library-output-files = ¶ {profile-library-output-folder}{profile-library-name}{library-platform}{library-kind} profile-library-dependencies = ¶ @@ -782,6 +873,7 @@ comerr-library-build-command = ¶ gss-library Ä {gss-library-output-files} krb5-library Ä {krb5-library-output-files} +privatekrb5-library Ä {privatekrb5-library-output-files} profile-library Ä {profile-library-output-files} comerr-library Ä {comerr-library-output-files} @@ -793,6 +885,10 @@ comerr-library Ä {comerr-library-output-files} {create-folder} {krb5-library-output-folder} {krb5-library-build-command} +{privatekrb5-library-output-files} ÄÄ {privatekrb5-library-dependencies} {makefile-name} + {create-folder} {privatekrb5-library-output-folder} + {privatekrb5-library-build-command} + {profile-library-output-files} ÄÄ {profile-library-dependencies} {makefile-name} {create-folder} {profile-library-output-folder} {profile-library-build-command} diff --git a/src/mac/PrivateKerberos5Lib.exp b/src/mac/PrivateKerberos5Lib.exp new file mode 100644 index 0000000..3a8588a --- /dev/null +++ b/src/mac/PrivateKerberos5Lib.exp @@ -0,0 +1,33 @@ +#---------------------------------------------------- +# PrivateKerberos5Lib.exp +# +# Exports from Kerberos v5 library which are not +# a part of the public API, but are needed by some +# critical clients. Each call is annotated by the +# offending client. +#---------------------------------------------------- + + krb5_size_opaque # GSSAPI + krb5_internalize_opaque # GSSAPI + krb5_externalize_opaque # GSSAPI + krb5_ser_pack_int32 # GSSAPI + krb5_ser_unpack_int32 # GSSAPI + krb5_ser_pack_bytes # GSSAPI + krb5_ser_unpack_bytes # GSSAPI + krb5_ser_auth_context_init # GSSAPI + krb5_ser_context_init # GSSAPI + krb5_ser_ccache_init # GSSAPI + krb5_ser_keytab_init # GSSAPI + krb5_ser_rcache_init # GSSAPI + decode_krb5_ap_req # GSSAPI + krb5_mcc_ops # GSSAPI + krb5_c_keyed_checksum_types # GSSAPI + krb5_c_random_make_octets # GSSAPI + krb5_c_encrypt # GSSAPI + krb5_c_make_checksum # GSSAPI + krb5_c_decrypt # GSSAPI + krb5_c_verify_checksum # GSSAPI + krb5_c_block_size # GSSAPI + krb5_c_checksum_length # GSSAPI + krb5_c_encrypt_length # GSSAPI + krb5int_cc_default # GSSAPI
\ No newline at end of file diff --git a/src/mac/Release notes b/src/mac/Release notes index d087037..dfa58a3 100644 --- a/src/mac/Release notes +++ b/src/mac/Release notes @@ -153,4 +153,39 @@ Changes in 1.1a3: 3.0d3 from tag Mac_GSSKerberos5_3_0d3 no changes on the Mac side - fixed crash in get_init_creds when no network
\ No newline at end of file + fixed crash in get_init_creds when no network + +3.0d4 + from tag Mac_GSSKerberos5_3_0d4 + no changes on the Mac side + +3.0d5 + from tag Mac_GSSKerberos5_3_0d5 + no changes on the Mac side + +3.0d6 + from tag Mac_GSSKerberos5_3_0d6 + login lib support + fixed to ccache v5 creds copying code + +3.0d7 + from tag Mac_GSSKerberos5_3_0d7 + support for login library in expired passwords + +3.0d8 + from tag Mac_GSSKerberos5_3_0d8 + now following the krb5-1-2 branch (except in util/profile) + +3.0a1 + from tag Mac_GSSKerberos5_3_0a1 + fixed krb5_cc_default + workaround for hostname resolution problems + +3.0a2 + from tag Mac_GSSKerberos5_3_0a2 + no changes on the Mac side + +3.0b1 + from tag Mac_GSSKerberos5_3_0b1 + Kerberos5Lib now uses PreferencesLib + fixed get_credentials [BZ 323]
\ No newline at end of file diff --git a/src/slave/ChangeLog b/src/slave/ChangeLog index e80bb38..3a72951 100644 --- a/src/slave/ChangeLog +++ b/src/slave/ChangeLog @@ -1,3 +1,9 @@ +2000-05-08 Nalin Dahyabhai <nalin@redhat.com> + + * kprop.c (open_connection): New argument indicates output buffer + size. Don't overrun it. + (get_tickets): Pass size of Errmsg. + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/slave/kprop.c b/src/slave/kprop.c index 5b6b596..fa32f11 100644 --- a/src/slave/kprop.c +++ b/src/slave/kprop.c @@ -72,7 +72,7 @@ void get_tickets static void usage PROTOTYPE((void)); krb5_error_code open_connection - PROTOTYPE((char *, int *, char *)); + PROTOTYPE((char *, int *, char *, int)); void kerberos_authenticate PROTOTYPE((krb5_context, krb5_auth_context *, int, krb5_principal, krb5_creds **)); @@ -116,7 +116,7 @@ main(argc, argv) get_tickets(context); database_fd = open_database(context, file, &database_size); - if (retval = open_connection(slave_host, &fd, Errmsg)) { + if (retval = open_connection(slave_host, &fd, Errmsg, sizeof(Errmsg))) { com_err(progname, retval, "%s while opening connection to %s", Errmsg, slave_host); exit(1); @@ -307,10 +307,11 @@ void get_tickets(context) } krb5_error_code -open_connection(host, fd, Errmsg) +open_connection(host, fd, Errmsg, ErrmsgSz) char *host; int *fd; char *Errmsg; + int ErrmsgSz; { int s; krb5_error_code retval; @@ -331,8 +332,9 @@ open_connection(host, fd, Errmsg) if(!port) { sp = getservbyname(KPROP_SERVICE, "tcp"); if (sp == 0) { - (void) strcpy(Errmsg, KPROP_SERVICE); - (void) strcat(Errmsg, "/tcp: unknown service"); + (void) strncpy(Errmsg, KPROP_SERVICE, ErrmsgSz - 1); + Errmsg[ErrmsgSz - 1] = '\0'; + (void) strncat(Errmsg, "/tcp: unknown service", ErrmsgSz - 1 - strlen(Errmsg)); *fd = -1; return(0); } @@ -481,7 +483,8 @@ open_database(context, data_fn, size) com_err(progname, ENOMEM, "while trying to malloc data_ok_fn"); exit(1); } - strcat(strcpy(data_ok_fn, data_fn), ok); + strcpy(data_ok_fn, data_fn); + strcat(data_ok_fn, ok); if (stat(data_ok_fn, &stbuf_ok)) { com_err(progname, errno, "while trying to stat %s", data_ok_fn); diff --git a/src/tests/create/ChangeLog b/src/tests/create/ChangeLog index 5573352..bc57b0c 100644 --- a/src/tests/create/ChangeLog +++ b/src/tests/create/ChangeLog @@ -1,3 +1,13 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * kdb5_mkdums.c (main): Make sure buffer 'principal' is terminated. + +2000-05-08 Ken Raeburn <raeburn@mit.edu> + Nalin Dahyabhai <nalin@redhat.com> + + * kdb5_mkdums.c (main): Make sure buffer "tmp" is + null-terminated. Don't overflow buffer "tmp" or "tmp2". + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/tests/create/kdb5_mkdums.c b/src/tests/create/kdb5_mkdums.c index 3cacc19..aa1854c 100644 --- a/src/tests/create/kdb5_mkdums.c +++ b/src/tests/create/kdb5_mkdums.c @@ -130,7 +130,8 @@ char *argv[]; mkey_password = optarg; break; case 'p': /* prefix name to create */ - strcpy(principal_string, optarg); + strncpy(principal_string, optarg, sizeof(principal_string) - 1); + principal_string[sizeof(principal_string) - 1] = '\0'; suffix = principal_string + strlen(principal_string); break; case 'n': /* how many to create */ @@ -195,13 +196,14 @@ char *argv[]; again given a prefix and count to test the db lib and kdb */ (void) sprintf(suffix, "%d", n); (void) sprintf(tmp, "%s-DEPTH-1", principal_string); + tmp[sizeof(tmp) - 1] = '\0'; str_newprinc = tmp; add_princ(test_context, str_newprinc); for (i = 2; i <= depth; i++) { - tmp2[0] = '\0'; (void) sprintf(tmp2, "/%s-DEPTH-%d", principal_string, i); - strcat(tmp, tmp2); + tmp2[sizeof(tmp2) - 1] = '\0'; + strncat(tmp, tmp2, sizeof(tmp) - 1 - strlen(tmp)); str_newprinc = tmp; add_princ(test_context, str_newprinc); } diff --git a/src/tests/dejagnu/config/ChangeLog b/src/tests/dejagnu/config/ChangeLog index 54d0e4b..f3767a9 100644 --- a/src/tests/dejagnu/config/ChangeLog +++ b/src/tests/dejagnu/config/ChangeLog @@ -1,3 +1,8 @@ +2000-05-31 Ken Raeburn <raeburn@mit.edu> + + * default.exp (setup_kerberos_files): Include des3 in supported + enctypes. + 2000-02-07 Tom Yu <tlyu@mit.edu> * default.exp: Remove default_tgs_enctypes for now as it was diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/dejagnu/config/default.exp index 44ffab7..e399354 100644 --- a/src/tests/dejagnu/config/default.exp +++ b/src/tests/dejagnu/config/default.exp @@ -352,8 +352,7 @@ proc setup_kerberos_files { } { puts $conffile " max_renewable_life = 3:00:00" puts $conffile " master_key_type = des-cbc-md5" puts $conffile " master_key_name = master/key" -# des3-cbc-sha1:normal - puts $conffile " supported_enctypes = des-cbc-crc:normal des-cbc-md5:normal des-cbc-crc:v4 des-cbc-md5:norealm" + puts $conffile " supported_enctypes = des3-cbc-sha1:normal des-cbc-crc:normal des-cbc-md5:normal des-cbc-crc:v4 des-cbc-md5:norealm" puts $conffile " kdc_supported_enctypes = des3-cbc-sha1:normal des-cbc-crc:normal des-cbc-md5:normal des-cbc-crc:v4 des-cbc-md5:norealm" puts $conffile " kdc_ports = 3088" puts $conffile " default_principal_expiration = 2037.12.31.23.59.59" diff --git a/src/tests/hammer/ChangeLog b/src/tests/hammer/ChangeLog index 1504de4..fcdd391 100644 --- a/src/tests/hammer/ChangeLog +++ b/src/tests/hammer/ChangeLog @@ -1,3 +1,12 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * kdc5_hammer.c (main): Make sure buffer 'prefix' is null-terminated. + +2000-05-08 Ken Raeburn <raeburn@mit.edu> + Nalin Dahyabhai <nalin@redhat.com> + + * kdc5_hammer.c (main): Don't overflow buffers "ctmp" or "stmp". + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/tests/hammer/kdc5_hammer.c b/src/tests/hammer/kdc5_hammer.c index 780f92d..6429a38 100644 --- a/src/tests/hammer/kdc5_hammer.c +++ b/src/tests/hammer/kdc5_hammer.c @@ -169,7 +169,8 @@ main(argc, argv) depth = atoi(optarg); /* how deep to go */ break; case 'p': /* prefix name to check */ - strcpy(prefix, optarg); + strncpy(prefix, optarg, sizeof(prefix) - 1); + prefix[sizeof(prefix) - 1] = '\0'; break; case 'n': /* how many to check */ num_to_check = atoi(optarg); @@ -240,10 +241,11 @@ main(argc, argv) again given a prefix and count to test the db lib and kdb */ ctmp[0] = '\0'; for (i = 1; i <= depth; i++) { - ctmp2[0] = '\0'; (void) sprintf(ctmp2, "%s%s%d-DEPTH-%d", (i != 1) ? "/" : "", prefix, n, i); - strcat(ctmp, ctmp2); + ctmp2[sizeof(ctmp2) - 1] = '\0'; + strncat(ctmp, ctmp2, sizeof(ctmp) - 1 - strlen(ctmp)); + ctmp[sizeof(ctmp) - 1] = '\0'; sprintf(client, "%s@%s", ctmp, cur_realm); if (get_tgt (test_context, client, &client_princ, ccache)) { @@ -255,10 +257,11 @@ main(argc, argv) stmp[0] = '\0'; for (j = 1; j <= depth; j++) { - stmp2[0] = '\0'; (void) sprintf(stmp2, "%s%s%d-DEPTH-%d", (j != 1) ? "/" : "", prefix, n, j); - strcat(stmp, stmp2); + stmp2[sizeof (stmp2) - 1] = '\0'; + strncat(stmp, stmp2, sizeof(stmp) - 1 - strlen(stmp)); + stmp[sizeof(stmp) - 1] = '\0'; sprintf(server, "%s@%s", stmp, cur_realm); if (verify_cs_pair(test_context, client, client_princ, stmp, cur_realm, n, i, j, ccache)) diff --git a/src/tests/verify/ChangeLog b/src/tests/verify/ChangeLog index 7d0a88f..f73710b 100644 --- a/src/tests/verify/ChangeLog +++ b/src/tests/verify/ChangeLog @@ -1,3 +1,12 @@ +2000-05-11 Nalin Dahyabhai <nalin@redhat.com> + + * kdb5_verify.c (main): Make sure buffer "principal_string" is + properly terminated. + +2000-05-08 Nalin Dahyabhai <nalin@redhat.com> + + * kdb5_verify.c (main): Don't overflow buffer "tmp". + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/tests/verify/kdb5_verify.c b/src/tests/verify/kdb5_verify.c index bfb0661..e4277b1 100644 --- a/src/tests/verify/kdb5_verify.c +++ b/src/tests/verify/kdb5_verify.c @@ -131,7 +131,8 @@ char *argv[]; mkey_password = optarg; break; case 'p': /* prefix name to check */ - strcpy(principal_string, optarg); + strncpy(principal_string, optarg, sizeof(principal_string) - 1); + principal_string[sizeof(principal_string) - 1] = '\0'; suffix = principal_string + strlen(principal_string); break; case 'n': /* how many to check */ @@ -199,9 +200,9 @@ char *argv[]; if (check_princ(context, str_princ)) errors++; for (i = 2; i <= depth; i++) { - tmp2[0] = '\0'; (void) sprintf(tmp2, "/%s-DEPTH-%d", principal_string, i); - strcat(tmp, tmp2); + tmp2[sizeof(tmp2) - 1] = '\0'; + strncat(tmp, tmp2, sizeof(tmp) - 1 - strlen(tmp)); str_princ = tmp; if (check_princ(context, str_princ)) errors++; } diff --git a/src/util/db2/ChangeLog b/src/util/db2/ChangeLog index 7972728..9ce240a 100644 --- a/src/util/db2/ChangeLog +++ b/src/util/db2/ChangeLog @@ -1,3 +1,7 @@ +2000-05-01 Nalin Dahyabhai <nalin@redhat.com> + + * hash/dbm.c (kdb2_dbm_open): Don't overflow buffer "path". + 1999-08-15 Tom Yu <tlyu@mit.edu> * README.NOT.SLEEPYCAT.DB: New file; pointer to README to diff --git a/src/util/db2/hash/dbm.c b/src/util/db2/hash/dbm.c index 50921de..aa96766 100644 --- a/src/util/db2/hash/dbm.c +++ b/src/util/db2/hash/dbm.c @@ -168,8 +168,9 @@ kdb2_dbm_open(file, flags, mode) info.cachesize = 0; info.hash = NULL; info.lorder = 0; - (void)strcpy(path, file); - (void)strcat(path, DBM_SUFFIX); + (void)strncpy(path, file, sizeof(path) - 1); + path[sizeof(path) - 1] = '\0'; + (void)strncat(path, DBM_SUFFIX, sizeof(path) - 1 - strlen(path)); return ((DBM *)__hash_open(path, flags, mode, &info, 0)); } diff --git a/src/util/et/ChangeLog b/src/util/et/ChangeLog index 345416e..96a7c75 100644 --- a/src/util/et/ChangeLog +++ b/src/util/et/ChangeLog @@ -1,3 +1,13 @@ +2000-05-07 Miro Jurisic <meeroh@mit.edu> + + * com_err.c (default_com_err_proc): use strncpy + where strncpy was meant (typo in Nalin's patch) + +2000-05-01 Nalin Dahyabhai <nalin@redhat.com> + + * com_err.c (default_com_err_proc) [_MSDOS || _WIN32 || + macintosh]: Don't overflow buffer "errbuf". + 2000-02-23 Ken Raeburn <raeburn@mit.edu> * Makefile.in (com_err.o): Depends on com_err.c. diff --git a/src/util/et/com_err.c b/src/util/et/com_err.c index 31da130..7bb0810 100644 --- a/src/util/et/com_err.c +++ b/src/util/et/com_err.c @@ -50,15 +50,18 @@ static void default_com_err_proc(whoami, code, fmt, ap) char errbuf[1024] = ""; if (whoami) { - strcat (errbuf, whoami); - strcat (errbuf, ": "); + errbuf[sizeof(errbuf) - 1] = '\0'; + strncat (errbuf, whoami, sizeof(errbuf) - 1 - strlen(errbuf)); + strncat (errbuf, ": ", sizeof(errbuf) - 1 - strlen(errbuf)); } if (code) { - strcat (errbuf, error_message(code)); - strcat (errbuf, " "); + errbuf[sizeof(errbuf) - 1] = '\0'; + strncat (errbuf, error_message(code), sizeof(errbuf) - 1 - strlen(errbuf)); + strncat (errbuf, " ", sizeof(errbuf) - 1 - strlen(errbuf)); } if (fmt) vsprintf (errbuf + strlen (errbuf), fmt, ap); + errbuf[sizeof(errbuf) - 1] = '\0'; #ifdef macintosh MacMessageBox(errbuf); diff --git a/src/util/pty/ChangeLog b/src/util/pty/ChangeLog index ff815b7..1986967 100644 --- a/src/util/pty/ChangeLog +++ b/src/util/pty/ChangeLog @@ -1,3 +1,8 @@ +2000-03-24 Ken Raeburn <raeburn@mit.edu> + + * configure.in: Check for alpha*-dec-osf* instead of + alpha-dec-osf*. + 1999-10-26 Tom Yu <tlyu@mit.edu> * Makefile.in: Clean up usage of CFLAGS, CPPFLAGS, DEFS, DEFINES, diff --git a/src/util/pty/configure.in b/src/util/pty/configure.in index 398b182..58ceb83 100644 --- a/src/util/pty/configure.in +++ b/src/util/pty/configure.in @@ -30,7 +30,7 @@ ac_cv_func_setsid=no # setsid doesn't do the right thing under Ultrix even thoug # Moreover, strops.h trashes sys/ioctl.h krb5_cv_has_streams=no ;; -alpha-dec-osf*) +alpha*-dec-osf*) AC_CHECK_LIB(security,main, AC_DEFINE(HAVE_SETLUID) LOGINLIBS="$LOGINLIBS -lsecurity" diff --git a/src/util/ss/ChangeLog b/src/util/ss/ChangeLog index 8cac4b7..72063d7 100644 --- a/src/util/ss/ChangeLog +++ b/src/util/ss/ChangeLog @@ -1,3 +1,11 @@ +2000-05-01 Nalin Dahyabhai <nalin@redhat.com> + + * help.c (ss_help): Don't overflow buffers "buffer" or "buf". + * list_rqs.c (ss_list_requests): Don't overflow buffer "buffer". + * mk_cmds.c (main): Don't overflow buffer "c_file". + * utils.c (generate_rqte): Update lengths of constant strings in + computing buffer size. + 2000-02-01 Ken Raeburn <raeburn@mit.edu> * listen.c (ss_listen): Local var END should be volatile. diff --git a/src/util/ss/help.c b/src/util/ss/help.c index e09b777..3c9cbec 100644 --- a/src/util/ss/help.c +++ b/src/util/ss/help.c @@ -53,16 +53,18 @@ void ss_help (argc, argv, sci_idx, info_ptr) return; } for (idx = 0; info->info_dirs[idx] != (char *)NULL; idx++) { - (void) strcpy(buffer, info->info_dirs[idx]); - (void) strcat(buffer, "/"); - (void) strcat(buffer, argv[1]); - (void) strcat(buffer, ".info"); + (void) strncpy(buffer, info->info_dirs[idx], sizeof(buffer) - 1); + buffer[sizeof(buffer) - 1] = '\0'; + (void) strncat(buffer, "/", sizeof(buffer) - 1 - strlen(buffer)); + (void) strncat(buffer, argv[1], sizeof(buffer) - 1 - strlen(buffer)); + (void) strncat(buffer, ".info", sizeof(buffer) - 1 - strlen(buffer)); if ((fd = open(&buffer[0], O_RDONLY)) >= 0) goto got_it; } if ((fd = open(&buffer[0], O_RDONLY)) < 0) { char buf[MAXPATHLEN]; - strcpy(buf, "No info found for "); - strcat(buf, argv[1]); + strncpy(buf, "No info found for ", sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + strncat(buf, argv[1], sizeof(buf) - 1 - strlen(buf)); ss_perror(sci_idx, 0, buf); return; } diff --git a/src/util/ss/list_rqs.c b/src/util/ss/list_rqs.c index cf2c931..045a0c8 100644 --- a/src/util/ss/list_rqs.c +++ b/src/util/ss/list_rqs.c @@ -87,23 +87,24 @@ ss_list_requests(argc, argv, sci_idx, info_ptr) buffer[0] = '\0'; if (entry->flags & SS_OPT_DONT_LIST) continue; + buffer[sizeof(buffer) - 1] = '\0'; for (name = entry->command_names; *name; name++) { register int len = strlen(*name); - strncat(buffer, *name, len); + strncat(buffer, *name, sizeof(buffer) - 1 - strlen(buffer)); spacing += len + 2; if (name[1]) { - strcat(buffer, ", "); + strncat(buffer, ", ", sizeof(buffer) - 1 - strlen(buffer)); } } if (spacing > 23) { - strcat(buffer, NL); + strncat(buffer, NL, sizeof(buffer) - 1 - strlen(buffer)); fputs(buffer, output); spacing = 0; buffer[0] = '\0'; } - strncat(buffer, twentyfive_spaces, 25-spacing); - strcat(buffer, entry->info_string); - strcat(buffer, NL); + strncat(buffer, twentyfive_spaces, sizeof(buffer) - 1 - (25-spacing)); + strncpy(buffer + 25, entry->info_string, sizeof(buffer) - 1 - 25); + strncat(buffer, NL, sizeof(buffer) - 1 - strlen(buffer)); fputs(buffer, output); } } diff --git a/src/util/ss/mk_cmds.c b/src/util/ss/mk_cmds.c index 0bcd770..bba5edd 100644 --- a/src/util/ss/mk_cmds.c +++ b/src/util/ss/mk_cmds.c @@ -62,8 +62,9 @@ int main(argc, argv) p = strrchr(path, '.'); *p = '\0'; q = rindex(path, '/'); - strcpy(c_file, (q) ? q + 1 : path); - strcat(c_file, ".c"); + strncpy(c_file, (q) ? q + 1 : path, sizeof(c_file) - 1); + c_file[sizeof(c_file) - 1] = '\0'; + strncat(c_file, ".c", sizeof(c_file) - 1 - strlen(c_file)); *p = '.'; output_file = fopen(c_file, "w+"); diff --git a/src/util/ss/utils.c b/src/util/ss/utils.c index 9698e70..c578001 100644 --- a/src/util/ss/utils.c +++ b/src/util/ss/utils.c @@ -61,13 +61,12 @@ char * generate_rqte(func_name, info_string, cmds, options) var_name = generate_cmds_string(cmds); generate_function_definition(func_name); size = 6; /* " { " */ - size += strlen(var_name)+7; /* "quux, " */ - size += strlen(func_name)+7; /* "foo, " */ - size += strlen(info_string)+9; /* "\"Info!\", " */ + size += strlen(var_name)+8; /* "quux, " */ + size += strlen(func_name)+8; /* "foo, " */ + size += strlen(info_string)+8; /* "\"Info!\", " */ sprintf(numbuf, "%d", options); - size += strlen(numbuf); - size += 4; /* " }," + NL */ - string = malloc(size * sizeof(char *)); + size += strlen(numbuf)+5; /* " }," + NL + NUL */ + string = malloc(size); strcpy(string, " { "); strcat(string, var_name); strcat(string, ",\n "); diff --git a/src/wconfig.c b/src/wconfig.c index 0671a1e..fdbc0d9 100644 --- a/src/wconfig.c +++ b/src/wconfig.c @@ -76,6 +76,13 @@ int main(int argc, char *argv[]) ignore_len = strlen(ignore_str); argc--; argv++; while (*argv && *argv[0] == '-') { + wflags[sizeof(wflags) - 1] = '\0'; + if (strlen (wflags) + 1 + strlen (*argv) > sizeof (wflags) - 1) { + fprintf (stderr, + "wconfig: argument list too long (internal limit %d)", + sizeof (wflags)); + exit (1); + } if (wflags[0]) strcat(wflags, " "); strcat(wflags, *argv); diff --git a/src/windows/ChangeLog b/src/windows/ChangeLog index ce20631..23bc3ec 100644 --- a/src/windows/ChangeLog +++ b/src/windows/ChangeLog @@ -1,3 +1,7 @@ +2000-04-25 Danilo Almeida <dalmeida@mit.edu> + + * version.rc: Bump version to 1.2 beta. + 2000-02-06 Danilo Almeida <dalmeida@mit.edu> * README: Add documentation about debug vs. release builds. diff --git a/src/windows/cns/ChangeLog b/src/windows/cns/ChangeLog index f99c56a..b420e42 100644 --- a/src/windows/cns/ChangeLog +++ b/src/windows/cns/ChangeLog @@ -1,3 +1,12 @@ +2000-05-08 Ken Raeburn <raeburn@mit.edu> + Nalin Dahyabhai <nalin@redhat.com> + + * cns.c (kwin_push_login): Don't overflow buffer "fullname". + (kwin_command): Don't overflow buffer "copyright". + * cns_reg.c (cns_load_registry): Don't overflow buffer + "cns_res.def_confname". + * tktlist.c (ticket_init_list): Don't overflow buffer "buf". + 1999-12-03 Danilo Almeida <dalmeida@mit.edu> * Makefile.in: Windows fix for updated win-pre.in. diff --git a/src/windows/cns/cns.c b/src/windows/cns/cns.c index 7af81fc..512f2f5 100644 --- a/src/windows/cns/cns.c +++ b/src/windows/cns/cns.c @@ -384,12 +384,13 @@ kwin_push_login(HWND hwnd, char *name, char *instance, char *realm) char menuitem[MAX_K_NAME_SZ + 3]; BOOL rc; - strcpy(fullname, "&x "); - strcat(fullname, name); - strcat(fullname, "."); - strcat(fullname, instance); - strcat(fullname, "@"); - strcat(fullname, realm); + fullname[sizeof(fullname) - 1] = '\0'; + strncpy(fullname, "&x ", sizeof(fullname) - 1); + strncat(fullname, name, sizeof(fullname) - 1 - strlen(fullname)); + strncat(fullname, ".", sizeof(fullname) - 1 - strlen(fullname)); + strncat(fullname, instance, sizeof(fullname) - 1 - strlen(fullname)); + strncat(fullname, "@", sizeof(fullname) - 1 - strlen(fullname)); + strncat(fullname, realm, sizeof(fullname) - 1 - strlen(fullname)); hmenu = GetMenu(hwnd); assert(hmenu != NULL); @@ -1339,14 +1340,16 @@ kwin_command(HWND hwnd, int cid, HWND hwndCtl, UINT codeNotify) strcpy(copyright, " Kerberos V5 for Windows "); #endif #ifdef _WIN32 - strcat(copyright, "32-bit\n"); + strncat(copyright, "32-bit\n", sizeof(copyright) - 1 - strlen(copyright)); #else - strcat(copyright, "16-bit\n"); + strncat(copyright, "16-bit\n", sizeof(copyright) - 1 - strlen(copyright)); #endif - strcat(copyright, "\n Version 1.12\n\n"); + strncat(copyright, "\n Version 1.12\n\n", + sizeof(copyright) - 1 - strlen(copyright)); #ifdef ORGANIZATION - strcat(copyright, " For information, contact:\n"); - strcat(copyright, ORGANIZATION); + strncat(copyright, " For information, contact:\n", + sizeof(copyright) - 1 - strlen(copyright)); + strncat(copyright, ORGANIZATION, sizeof(copyright) - 1 - strlen(copyright)); #endif MessageBox(hwnd, copyright, KWIN_DIALOG_NAME, MB_OK); @@ -1469,8 +1472,9 @@ kwin_paint(HWND hwnd) sprintf(buf, "%s - %ld hr", KWIN_DIALOG_NAME, dt); } + buf[sizeof(buf) - 1] = '\0'; if (dt > 1) - strcat(buf, "s"); + strncat(buf, "s", sizeof(buf) - 1 - strlen(buf)); } DrawIcon(hdc, r.left, r.top, hicon); diff --git a/src/windows/cns/cns_reg.c b/src/windows/cns/cns_reg.c index 400d72d..160eb15 100644 --- a/src/windows/cns/cns_reg.c +++ b/src/windows/cns/cns_reg.c @@ -74,8 +74,12 @@ cns_load_registry(void) if (key != INVALID_HANDLE_VALUE) { if (registry_string_get(key, KERBNET_HOME, &ts) == 0) { cns_res.conf_override = 0; - strcpy(cns_res.def_confname, ts); - strcat(cns_res.def_confname, "\\etc\\krb5.conf"); + cns_res.def_confname[sizeof(cns_res.def_confname) - 1]; + strncpy(cns_res.def_confname, ts, + sizeof(cns_res.def_confname) - 1); + strncat(cns_res.def_confname, "\\etc\\krb5.conf", + sizeof(cns_res.def_confname) - 1 - + strlen(cns_res.def_confname)); free(ts); } diff --git a/src/windows/cns/tktlist.c b/src/windows/cns/tktlist.c index 62b6eb8..5e15201 100644 --- a/src/windows/cns/tktlist.c +++ b/src/windows/cns/tktlist.c @@ -122,11 +122,12 @@ ticket_init_list (HWND hwnd) krb_get_nth_cred(service, instance, realm, i); krb_get_cred(service, instance, realm, &c); strcpy(buf, " "); - strcat(buf, short_date(c.issue_date - kwin_get_epoch())); + strncat(buf, short_date(c.issue_date - kwin_get_epoch()), + sizeof(buf) - 1 - strlen(buf)); expiration = c.issue_date - kwin_get_epoch() + (long) c.lifetime * 5L * 60L; - strcat (buf, " "); - strcat(buf, short_date(expiration)); - strcat (buf, " "); + strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); + strncat(buf, short_date(expiration), sizeof(buf) - 1 - strlen(buf)); + strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); l = strlen(buf); sprintf(&buf[l], "%s%s%s%s%s (%d)", c.service, (c.instance[0] ? "." : ""), c.instance, @@ -172,10 +173,12 @@ ticket_init_list (HWND hwnd) ncred++; strcpy (buf, " "); - strcat (buf, short_date (c.times.starttime - kwin_get_epoch())); - strcat (buf, " "); - strcat (buf, short_date (c.times.endtime - kwin_get_epoch())); - strcat (buf, " "); + strncat(buf, short_date (c.times.starttime - kwin_get_epoch()), + sizeof(buf) - 1 - strlen(buf)); + strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); + strncat(buf, short_date (c.times.endtime - kwin_get_epoch()), + sizeof(buf) - 1 - strlen(buf)); + strncat(buf, " ", sizeof(buf) - 1 - strlen(buf)); /* Add ticket service name and realm */ code = krb5_unparse_name (k5_context, c.server, &sname); @@ -183,9 +186,9 @@ ticket_init_list (HWND hwnd) com_err (NULL, code, "while unparsing server name"); break; } - strcat (buf, sname); + strncat (buf, sname, sizeof(buf) - 1 - strlen(buf)); - strcat (buf, flags_string (&c)); /* Add flag info */ + strncat (buf, flags_string (&c), sizeof(buf) - 1 - strlen(buf)); /* Add flag info */ l = strlen(buf); lpinfo = (LPTICKETINFO) malloc(sizeof(TICKETINFO) + l + 1); diff --git a/src/windows/lib/ChangeLog b/src/windows/lib/ChangeLog index 25f20f4..160a899 100644 --- a/src/windows/lib/ChangeLog +++ b/src/windows/lib/ChangeLog @@ -1,3 +1,7 @@ +2000-05-18 Danilo Almeida <dalmeida@mit.edu> + + * cacheapi.h: Update to v2. + 1999-12-03 Danilo Almeida <dalmeida@mit.edu> * Makefile.in: Fix of build flags with updated win-pre.in. diff --git a/src/windows/lib/cacheapi.h b/src/windows/lib/cacheapi.h index d23b8d4..7661599 100644 --- a/src/windows/lib/cacheapi.h +++ b/src/windows/lib/cacheapi.h @@ -49,74 +49,64 @@ ** */ -#include <krb5.h> - #ifndef Krb_CCacheAPI_h_ #define Krb_CCacheAPI_h_ #include <windows.h> -#define CC_API_VER_1 1 +//typedef int cc_int32; +#define cc_int32 long +#define cc_uint32 unsigned long -#define CCACHE_API __declspec(dllexport) cc_int32 -//#define CCACHE_API __declspec( dllexport ) cc_int32 __stdcall +typedef cc_int32 cc_time_t; -/* -** Decisions I haven't nailed down yet -*/ -// determines if cred_type precedes ptrs to creds in cred_union -//#define CRED_TYPE_IN_UNION -// -// JENNYEXT - modifications Jenny made to cacheapi for MIT code -// not blessed, but reproduced temporarily -#ifndef JENNYEXT -#define JENNYEXT -#endif +#define CC_API_VER_1 1 +#define CC_API_VER_2 2 + +//enum { +// CC_API_VER_1 = 1, +// CC_API_VER_2 = 2 +//}; + +#define CCACHE_API __declspec(dllexport) cc_int32 /* ** The Official Error Codes */ -#define CC_NOERROR 0 -#define CC_BADNAME 1 -#define CC_NOTFOUND 2 -#define CC_END 3 -#define CC_IO 4 -#define CC_WRITE 5 -#define CC_NOMEM 6 -#define CC_FORMAT 7 -#define CC_LOCKED 8 -#define CC_BAD_API_VERSION 9 -#define CC_NO_EXIST 10 -#define CC_NOT_SUPP 11 -#define CC_BAD_PARM 12 -#define CC_ERR_CACHE_ATTACH 13 -#define CC_ERR_CACHE_RELEASE 14 -#define CC_ERR_CACHE_FULL 15 -#define CC_ERR_CRED_VERSION 16 +#define CC_NOERROR 0 +#define CC_BADNAME 1 +#define CC_NOTFOUND 2 +#define CC_END 3 +#define CC_IO 4 +#define CC_WRITE 5 +#define CC_NOMEM 6 +#define CC_FORMAT 7 +#define CC_LOCKED 8 +#define CC_BAD_API_VERSION 9 +#define CC_NO_EXIST 10 +#define CC_NOT_SUPP 11 +#define CC_BAD_PARM 12 +#define CC_ERR_CACHE_ATTACH 13 +#define CC_ERR_CACHE_RELEASE 14 +#define CC_ERR_CACHE_FULL 15 +#define CC_ERR_CRED_VERSION 16 /* ** types, structs, & constants */ -typedef int cc_int32; -typedef cc_int32 cc_time_t; - // Flag bits promised by Ted "RSN" #define CC_FLAGS_RESERVED 0xFFFFFFFF -typedef cc_int32 cc_nc_flags; // set via constants above +typedef cc_uint32 cc_nc_flags; // set via constants above -typedef struct opaque_ccache_pointer_type* ccache_p; typedef struct opaque_dll_control_block_type* apiCB; +typedef struct opaque_ccache_pointer_type* ccache_p; typedef struct opaque_credential_iterator_type* ccache_cit; -enum { KRB5_CLIENT_SZ = 256}; -enum { KRB5_SERVER_SZ = 256}; -enum { KRB5_DATA_SZ = 1024}; -enum { KRB5_DATA_CNT = 20}; - +#if 0 enum _cc_data_type { - type_ticket = 0, // 0 for ticket, second_ticket + type_ticket = 0, /* 0 for ticket, second_ticket */ /* Ted's draft spec says these are to be "as defined in the Kerberos V5 protocol" all I can find are typdefs, @@ -125,22 +115,17 @@ enum _cc_data_type { type_address, /* = <"as defined in the Kerberos V5 protocol"> */ type_authdata, /* = <"as defined in the Kerberos V5 protocol"> */ type_encryption, /* = <"as defined in the Kerberos V5 protocol"> */ - cc_data_type_max }; // for validation + cc_data_type_max /* for validation */ +}; +#endif typedef struct _cc_data { - cc_int32 type; // should be one of _cc_data_type - cc_int32 length; - unsigned char* data; // the proverbial bag-o-bits + cc_uint32 type; // should be one of _cc_data_type + cc_uint32 length; + unsigned char* data; // the proverbial bag-o-bits } cc_data; -typedef struct _cc_data1 -{ - cc_int32 type; // should be one of _cc_data_type - cc_int32 length; - unsigned char data[KRB5_DATA_SZ]; // the proverbial bag-o-bits -} cc_data1; - // V5 Credentials typedef struct _cc_creds { char* client; @@ -150,75 +135,53 @@ typedef struct _cc_creds { cc_time_t starttime; cc_time_t endtime; cc_time_t renew_till; - cc_int32 is_skey; - cc_int32 ticket_flags; + cc_uint32 is_skey; + cc_uint32 ticket_flags; cc_data FAR ** addresses; cc_data ticket; cc_data second_ticket; cc_data FAR ** authdata; } cc_creds; -typedef struct _cc_cache_creds { - char client[KRB5_CLIENT_SZ]; - char server[KRB5_SERVER_SZ]; - cc_data1 keyblock; - cc_time_t authtime; - cc_time_t starttime; - cc_time_t endtime; - cc_time_t renew_till; - cc_int32 is_skey; - cc_int32 ticket_flags; - cc_data1 addresses[KRB5_DATA_CNT]; - cc_data1 ticket; - cc_data1 second_ticket; - cc_data1 authdata[KRB5_DATA_CNT]; -} cc_cache_creds; - // begin V4 stuff - -enum { KRB_PRINCIPAL_SZ = 40 }; -enum { KRB_SERVICE_SZ = 40}; -enum { KRB_INSTANCE_SZ = 40}; -enum { KRB_REALM_SZ = 40}; -#ifndef ADDR_SZ -enum { ADDR_SZ = 16}; -#endif - // use an enumerated type so all callers infer the same meaning // these values are what krbv4win uses internally. -enum StringToKey_Type { STK_AFS = 0, STK_DES = 1 }; +#define STK_AFS 0 +#define STK_DES 1 // K4 uses a MAX_KTXT_LEN of 1250 to hold a ticket // K95 uses 256 // To be safe I'll use the larger number, but a factor of 5!!! -enum { MAX_V4_CRED_LEN = 1250 }; +#define MAX_V4_CRED_LEN 1250 // V4 Credentials + +enum { + KRB_NAME_SZ = 40, + KRB_INSTANCE_SZ = 40, + KRB_REALM_SZ = 40 +}; + typedef struct cc_V4credential { - unsigned char kversion; - char principal[KRB_PRINCIPAL_SZ]; - char principal_instance[KRB_INSTANCE_SZ]; - char service[KRB_SERVICE_SZ]; - char service_instance[KRB_INSTANCE_SZ]; - char realm[KRB_REALM_SZ]; - unsigned char session_key[8]; - cc_int32 kvno; // k95 used BYTE skvno - enum StringToKey_Type - str_to_key; // k4 infers dynamically, k95 stores - long issue_date; // k95 called this issue_time - cc_int32 lifetime; // k95 used LONG expiration_time - char address[ADDR_SZ]; // IP Address of local host - cc_int32 ticket_sz; // k95 used BYTE, k4 ktext uses int to hold up to 1250 - unsigned char ticket[MAX_V4_CRED_LEN]; - unsigned long oops; // zero to catch runaways + unsigned char kversion; + char principal[KRB_NAME_SZ + 1]; + char principal_instance[KRB_INSTANCE_SZ + 1]; + char service[KRB_NAME_SZ + 1]; + char service_instance[KRB_INSTANCE_SZ + 1]; + char realm[KRB_REALM_SZ + 1]; + unsigned char session_key[8]; + cc_int32 kvno; // k95 used BYTE skvno + cc_int32 str_to_key; // k4 infers dynamically, k95 stores + long issue_date; // k95 called this issue_time + cc_int32 lifetime; // k95 used LONG expiration_time + cc_uint32 address; // IP Address of local host + cc_int32 ticket_sz; // k95 used BYTE, k4 ktext uses int to hold up to 1250 + unsigned char ticket[MAX_V4_CRED_LEN]; + unsigned long oops; // zero to catch runaways } V4Cred_type; -#ifdef JENNYEXT -typedef struct cc_V4credential CCV4CREDENTIALS; // JENNYEXT -#endif - -enum cc_cred_vers { +enum { CC_CRED_VUNKNOWN = 0, // For validation CC_CRED_V4 = 1, CC_CRED_V5 = 2, @@ -226,17 +189,21 @@ enum cc_cred_vers { }; typedef union cred_ptr_union_type { - V4Cred_type* pV4Cred; - cc_creds* pV5Cred; + V4Cred_type* pV4Cred; + cc_creds* pV5Cred; } cred_ptr_union; typedef struct cred_union_type { -//#ifdef CRED_TYPE_IN_UNION - enum cc_cred_vers cred_type; -//#endif - cred_ptr_union cred; + cc_int32 cred_type; + cred_ptr_union cred; } cred_union; +typedef struct _infoNC { + char* name; + char* principal; + cc_int32 vers; +} infoNC; + /* ** The official (externally visible) API @@ -251,113 +218,147 @@ extern "C" /* this entire list of functions */ ** Main cache routines : initialize, shutdown, get_cache_names, & get_change_time */ CCACHE_API -cc_initialize(apiCB** cc_ctx, // < DLL's primary control structure. - // returned here, passed everywhere else - const cc_int32 api_version,// > ver supported by caller (use CC_API_VER_1) - cc_int32* api_supported, // < if ~NULL, max ver supported by DLL - const char** vendor); // < if ~NULL, vendor name in read only C string +cc_initialize( + apiCB** cc_ctx, // < DLL's primary control structure. + // returned here, passed everywhere else + cc_int32 api_version, // > ver supported by caller (use CC_API_VER_1) + cc_int32* api_supported, // < if ~NULL, max ver supported by DLL + const char** vendor // < if ~NULL, vendor name in read only C string + ); CCACHE_API -cc_shutdown(apiCB** cc_ctx); // <> DLL's primary control structure. NULL after call. +cc_shutdown( + apiCB** cc_ctx // <> DLL's primary control structure. NULL after call. + ); CCACHE_API -cc_get_change_time(apiCB* cc_ctx, // > DLL's primary control structure - cc_time_t* time); // < time of last change to main cache +cc_get_change_time( + apiCB* cc_ctx, // > DLL's primary control structure + cc_time_t* time // < time of last change to main cache + ); /* ** Named Cache (NC) routines -** create, open, close, destroy, get_principal, get_cred_version, & lock_request +** create, open, close, destroy, get_principal, get_cred_version, & +** lock_request ** -** Multiple NCs are allowed within the main cache. Each has a Name and kerberos -** version # (V4 or V5). Caller gets "ccache_ptr"s for NCs. +** Multiple NCs are allowed within the main cache. Each has a Name +** and kerberos version # (V4 or V5). Caller gets "ccache_ptr"s for +** NCs. */ CCACHE_API -cc_create(apiCB* cc_ctx, // > DLL's primary control structure - const char* name, // > name of cache to be [destroyed if exists, then] created - const char* principal, // > name of principal associated with NC - const enum cc_cred_vers vers, // > ticket version (CC_CRED_V4 or CC_CRED_V5) - const cc_int32 cc_flags, // > options - ccache_p** ccache_ptr); // < NC control structure +cc_create( + apiCB* cc_ctx, // > DLL's primary control structure + const char* name, // > name of cache to be [destroyed if exists, then] created + const char* principal, + cc_int32 vers, // > ticket version (CC_CRED_V4 or CC_CRED_V5) + cc_uint32 cc_flags, // > options + ccache_p** ccache_ptr // < NC control structure + ); CCACHE_API -cc_open(apiCB* cc_ctx, // > DLL's primary control structure - const char* name, // > name of pre-created cache - const enum cc_cred_vers vers, // > ticket version (CC_CRED_V4 or CC_CRED_V5) - const cc_int32 cc_flags, // > options - ccache_p** ccache_ptr); // < NC control structure +cc_open( + apiCB* cc_ctx, // > DLL's primary control structure + const char* name, // > name of pre-created cache + cc_int32 vers, // > ticket version (CC_CRED_V4 or CC_CRED_V5) + cc_uint32 cc_flags, // > options + ccache_p** ccache_ptr // < NC control structure + ); CCACHE_API -cc_close(apiCB* cc_ctx, // > DLL's primary control structure - ccache_p** ccache_ptr); // <> NC control structure. NULL after call. +cc_close( + apiCB* cc_ctx, // > DLL's primary control structure + ccache_p** ccache_ptr // <> NC control structure. NULL after call. + ); CCACHE_API -cc_destroy(apiCB* cc_ctx, // > DLL's primary control structure - ccache_p** ccache_ptr); // <> NC control structure. NULL after call. - +cc_destroy( + apiCB* cc_ctx, // > DLL's primary control structure + ccache_p** ccache_ptr // <> NC control structure. NULL after call. + ); /* ** Ways to get information about the NCs */ CCACHE_API -cc_seq_fetch_NCs(apiCB* cc_ctx, // > DLL's primary control structure - ccache_p** ccache_ptr, // < NC control structure (free via cc_close()) - ccache_cit** itNCs); // <> iterator used by DLL, - // set to NULL before first call - // returned NULL at CC_END +cc_seq_fetch_NCs_begin( + apiCB* cc_ctx, + ccache_cit** itNCs + ); -typedef struct _infoNC { - char* name; - enum cc_cred_vers vers; -} infoNC; +CCACHE_API +cc_seq_fetch_NCs_end( + apiCB* cc_ctx, + ccache_cit** itNCs + ); + +CCACHE_API +cc_seq_fetch_NCs_next( + apiCB* cc_ctx, + ccache_p** ccache_ptr, + ccache_cit* itNCs + ); CCACHE_API -cc_get_NC_info(apiCB* cc_ctx, // > DLL's primary control structure - struct _infoNC*** ppNCi); // < (NULL before call) null terminated, - // list of a structs (free via cc_free_infoNC()) +cc_seq_fetch_NCs( + apiCB* cc_ctx, // > DLL's primary control structure + ccache_p** ccache_ptr, // < NC control structure (free via cc_close()) + ccache_cit** itNCs // <> iterator used by DLL, + // set to NULL before first call + // returned NULL at CC_END + ); CCACHE_API -cc_free_NC_info(apiCB* cc_ctx, - struct _infoNC*** ppNCi); // < free list of structs returned by cc_get_cache_names() - // set to NULL on return +cc_get_NC_info( + apiCB* cc_ctx, // > DLL's primary control structure + struct _infoNC*** ppNCi // < (NULL before call) null terminated, + // list of a structs (free via cc_free_infoNC()) + ); + +CCACHE_API +cc_free_NC_info( + apiCB* cc_ctx, + struct _infoNC*** ppNCi // < free list of structs returned by + // cc_get_cache_names(). set to NULL on return + ); /* ** Functions that provide distinguishing characteristics of NCs. */ CCACHE_API -cc_get_name(apiCB* cc_ctx, // > DLL's primary control structure - const ccache_p* ccache_ptr, // > NC control structure - char** name); // < name of NC associated with ccache_ptr (free via cc_free_name()) +cc_get_name( + apiCB* cc_ctx, // > DLL's primary control structure + const ccache_p* ccache_ptr, // > NC control structure + char** name // < name of NC associated with ccache_ptr + // (free via cc_free_name()) + ); CCACHE_API -cc_set_principal(apiCB* cc_ctx, // > DLL's primary control structure - const ccache_p* ccache_pointer,// < name of principal associated with NC - const enum cc_cred_vers vers, // Free via cc_free_principal() - const char* principal); +cc_set_principal( + apiCB* cc_ctx, // > DLL's primary control structure + const ccache_p* ccache_pointer, // > NC control structure + const cc_int32 vers, + const char* principal // > name of principal associated with NC + // Free via cc_free_principal() + ); CCACHE_API -cc_get_principal(apiCB* cc_ctx, // > DLL's primary control structure - ccache_p* ccache_pointer, // < name of principal associated with NC - char** principal); // Free via cc_free_principal() +cc_get_principal( + apiCB* cc_ctx, // > DLL's primary control structure + const ccache_p* ccache_pointer, // > NC control structure + char** principal // < name of principal associated with NC + // Free via cc_free_principal() + ); -#ifdef JENNYEXT - -CCACHE_API -cc_set_instance(apiCB* cc_ctx, // > DLL's primary control structure - const char* instance); // < name of principal_instance associated with NC - // Free via cc_free_instance() CCACHE_API -cc_get_instance(apiCB* cc_ctx, // > DLL's primary control structure - char** instance); // < name of principal_instance associated with NC - // Free via cc_free_instance() -#endif /* JENNYEXT */ - -CCACHE_API -cc_get_cred_version(apiCB* cc_ctx, // > DLL's primary control structure - const ccache_p* ccache_ptr,// > NC control structure - enum cc_cred_vers* vers);// < ticket version associated with NC +cc_get_cred_version( + apiCB* cc_ctx, // > DLL's primary control structure + const ccache_p* ccache_ptr, // > NC control structure + cc_int32* vers // < ticket version associated with NC + ); #define CC_LOCK_UNLOCK 1 #define CC_LOCK_READER 2 @@ -365,9 +366,12 @@ cc_get_cred_version(apiCB* cc_ctx, // > DLL's primary control structure #define CC_LOCK_NOBLOCK 16 CCACHE_API -cc_lock_request(apiCB* cc_ctx, // > DLL's primary control structure - const ccache_p* ccache_ptr,// > NC control structure - const cc_int32 lock_type);// > one (or combination) of above defined lock types +cc_lock_request( + apiCB* cc_ctx, // > DLL's primary control structure + const ccache_p* ccache_ptr, // > NC control structure + const cc_int32 lock_type // > one (or combination) of above defined + // lock types + ); /* @@ -375,23 +379,49 @@ cc_lock_request(apiCB* cc_ctx, // > DLL's primary control structure ** store, remove_cred, seq_fetch_creds */ CCACHE_API -cc_store(apiCB* cc_ctx, // > DLL's primary control structure - const ccache_p* ccache_ptr, // > NC control structure - const cred_union creds); // > credentials to be copied into NC +cc_store( + apiCB* cc_ctx, // > DLL's primary control structure + ccache_p* ccache_ptr, // > NC control structure + const cred_union creds // > credentials to be copied into NC + ); CCACHE_API -cc_remove_cred(apiCB* cc_ctx, // > DLL's primary control structure - const ccache_p* ccache_ptr, // > NC control structure - const cred_union cred); // > credentials to remove from NC +cc_remove_cred( + apiCB* cc_ctx, // > DLL's primary control structure + ccache_p* ccache_ptr, // > NC control structure + const cred_union cred // > credentials to remove from NC + ); CCACHE_API -cc_seq_fetch_creds(apiCB* cc_ctx, // > DLL's primary control structure - const ccache_p* ccache_ptr, // > NC control structure - cred_union** creds, // < filled in by DLL, free via cc_free_creds() - ccache_cit** itCreds); // <> iterator used by DLL, set to NULL before first call - // Also NULL for final call if loop ends before CC_END +cc_seq_fetch_creds( + apiCB* cc_ctx, // > DLL's primary control structure + const ccache_p* ccache_ptr, // > NC control structure + cred_union** creds, // < filled in by DLL, free via cc_free_creds() + ccache_cit** itCreds // <> iterator used by DLL, set to NULL + // before first call -- Also NULL for final + // call if loop ends before CC_END + ); + +CCACHE_API +cc_seq_fetch_creds_begin( + apiCB* cc_ctx, + const ccache_p* ccache_ptr, + ccache_cit** itCreds + ); + +CCACHE_API +cc_seq_fetch_creds_end( + apiCB* cc_ctx, + ccache_cit** itCreds + ); + +CCACHE_API +cc_seq_fetch_creds_next( + apiCB* cc_ctx, + cred_union** cred, + ccache_cit* itCreds + ); - /* ** methods of liberation, ** or freeing space via the free that goes with the malloc used to get it @@ -401,37 +431,28 @@ cc_seq_fetch_creds(apiCB* cc_ctx, // > DLL's primary control structure ** freeing a NULL pointer is not treated as an error */ CCACHE_API -cc_free_principal(apiCB* cc_ctx, // > DLL's primary control structure - char** principal); // <> ptr to principal to be freed, returned as NULL - // (from cc_get_principal()) - -#ifdef JENNYEXT - -CCACHE_API -cc_free_instance(apiCB* cc_ctx, // > DLL's primary control structure - char** instance); // <> ptr to instance to be freed, returned as NULL - // (from cc_get_instance()) - -#endif +cc_free_principal( + apiCB* cc_ctx, // > DLL's primary control structure + char** principal // <> ptr to principal to be freed, returned as NULL + // (from cc_get_principal()) + ); CCACHE_API -cc_free_name(apiCB* cc_ctx, // > DLL's primary control structure - char** name); // <> ptr to name to be freed, returned as NULL - // (from cc_get_name()) +cc_free_name( + apiCB* cc_ctx, // > DLL's primary control structure + char** name // <> ptr to name to be freed, returned as NULL + // (from cc_get_name()) + ); CCACHE_API -cc_free_name_list(apiCB* cc_ctx, // > DLL's primary control structure - char*** name_list); // <> ptr to null terminated list of names to be freed - // (from cc_get_cache_names()), returned as NULL - -CCACHE_API -cc_free_creds(apiCB* cc_ctx, // > DLL's primary control structure - cred_union** pCred); // <> cred (from cc_seq_fetch_creds()) to be freed - // Returned as NULL. +cc_free_creds( + apiCB* cc_ctx, // > DLL's primary control structure + cred_union** pCred // <> cred (from cc_seq_fetch_creds()) to be freed + // Returned as NULL. + ); #ifdef __cplusplus } /* end extern "C" */ #endif /* __cplusplus */ #endif /* Krb_CCacheAPI_h_ */ - diff --git a/src/windows/version.rc b/src/windows/version.rc index 67660fc..ba5e1a1 100644 --- a/src/windows/version.rc +++ b/src/windows/version.rc @@ -5,6 +5,16 @@ * BEGIN COMMON VERSION INFO for GSS and Kerberos version resources */ +#define PRE_RELEASE + +#ifdef PRE_RELEASE +#define BETA_STR " beta" +#define BETA_FLAG VS_FF_PRERELEASE +#else +#define BETA_STR "" +#define BETA_FLAG 0 +#endif + #if !defined(_WIN32) #define Targ_OS VOS__WINDOWS16 #else @@ -13,10 +23,10 @@ /* we're going to stamp all the DLLs with the same version number */ -#define K5_PRODUCT_VERSION_STRING "1.1.1\0" -#define K5_PRODUCT_VERSION 1, 1, 1, 0 +#define K5_PRODUCT_VERSION_STRING "1.2" BETA_STR "\0" +#define K5_PRODUCT_VERSION 1, 2, 0, 0 -#define K5_COPYRIGHT "Copyright (C) 1997-1999 by the Massachusetts Institute of Technology\0" +#define K5_COPYRIGHT "Copyright (C) 1997-2000 by the Massachusetts Institute of Technology\0" #define K5_COMPANY_NAME "Massachusetts Institute of Technology.\0" /* @@ -134,7 +144,7 @@ VS_VERSION_INFO VERSIONINFO FILEVERSION K5_PRODUCT_VERSION PRODUCTVERSION K5_PRODUCT_VERSION FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -FILEFLAGS (VS_FF_DEBUG | VS_FF_PRIVATEBUILD) +FILEFLAGS (VS_FF_DEBUG | VS_FF_PRIVATEBUILD | BETA_FLAG) FILEOS Targ_OS FILETYPE K5_FILETYPE BEGIN diff --git a/src/windows/wintel/ChangeLog b/src/windows/wintel/ChangeLog index a9d6900..f8526d9 100644 --- a/src/windows/wintel/ChangeLog +++ b/src/windows/wintel/ChangeLog @@ -1,3 +1,9 @@ +2000-05-08 Nalin Dahyabhai <nalin@redhat.com> + + * auth.c (auth_abort): Don't overflow buffer "strTmp". + (k4_auth_send): Don't overflow buffer "dbgbuf". + * encrypt.c (printsub): Don't overflow buffer "p". + 1999-12-03 Danilo Almeida <dalmeida@mit.edu> * Makefile.in: Windows fix for updated win-pre.in. diff --git a/src/windows/wintel/auth.c b/src/windows/wintel/auth.c index 5e9d1d2..28f515b 100644 --- a/src/windows/wintel/auth.c +++ b/src/windows/wintel/auth.c @@ -151,10 +151,11 @@ auth_abort(kstream ks, char *errmsg, long r) TelnetSend(ks, (LPSTR)buf, 8, 0); if (errmsg != NULL) { - strcpy(strTmp, errmsg); + strTmp[sizeof(strTmp) - 1] = '\0'; + strncpy(strTmp, errmsg, sizeof(strTmp) - 1); if (r != KSUCCESS) { - strcat(strTmp, "\n"); + strncat(strTmp, "\n", sizeof(strTmp) - 1 - strlen(strTmp)); #ifdef KRB4 lstrcat(strTmp, krb_get_err_text((int)r)); #endif @@ -423,8 +424,8 @@ k4_auth_send(kstream ks) if (!realm) { strcpy(buf, "Can't find realm for host \""); - strcat(buf, szHostName); - strcat(buf, "\""); + strncat(buf, szHostName, sizeof(buf) - 1 - strlen(buf)); + strncat(buf, "\"", sizeof(buf) - 1 - strlen(buf)); auth_abort(ks, buf, 0); return KFAILURE; } @@ -436,14 +437,14 @@ k4_auth_send(kstream ks) if (r) { strcpy(buf, "Can't get \""); - strcat(buf, KRB_SERVICE_NAME); + strncat(buf, KRB_SERVICE_NAME, sizeof(buf) - 1 - strlen(buf)); if (instance[0] != 0) { - strcat(buf, "."); + strncat(buf, ".", sizeof(buf) - 1 - strlen(buf)); lstrcat(buf, instance); } - strcat(buf, "@"); + strncat(buf, "@", sizeof(buf) - 1 - strlen(buf)); lstrcat(buf, realm); - strcat(buf, "\" ticket"); + strncat(buf, "\" ticket", sizeof(buf) - 1 - strlen(buf)); auth_abort(ks, buf, r); return r; diff --git a/src/windows/wintel/encrypt.c b/src/windows/wintel/encrypt.c index f1a1301..bbb5496 100644 --- a/src/windows/wintel/encrypt.c +++ b/src/windows/wintel/encrypt.c @@ -230,10 +230,11 @@ printsub(char c, unsigned char *s, size_t len) *p++ = c; - for (i = 0 ; i < len ; i++) + for (i = 0 ; (i < len) && (p - dbgbuf + 3 < sizeof(dbgbuf)) ; i++) p += sprintf(p, "%02x ", s[i]); + dbgbuf[sizeof(dbgbuf) - 1] = '\0'; - strcat(p, "\n"); + strncat(p, "\n", sizeof(dbgbuf) - 1 - (p - dbgbuf)); OutputDebugString(dbgbuf); |