Subject: security/3826: login for krb5-1.0
To: None <gnats-bugs@gnats.netbsd.org>
From: Chris Jones <cjones@rupert.oscs.montana.edu>
List: netbsd-bugs
Date: 07/02/1997 14:10:23
>Number: 3826
>Category: security
>Synopsis: update to k5login.c and friends for krb5-1.0
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: gnats-admin (GNATS administrator)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Jul 4 03:50:05 1997
>Last-Modified:
>Originator: Chris Jones
>Organization:
-------------------------------------------------------------------------------
Chris Jones cjones@rupert.honors.montana.edu
Mad scientist in training...
"Is this going to be a stand-up programming session, sir, or another bug hunt?"
>Release: 1997/7/1
>Environment:
System: NetBSD clydesdale.math.montana.edu 1.2G NetBSD 1.2G (CLYDESDALE) #2: Fri Jun 20 12:18:19 MDT 1997 cjones@clydesdale.math.montana.edu:/usr/src/sys/arch/i386/compile/CLYDESDALE i386
>Description:
A real Kerberos guru would know more about this than I, but here's my
take on the Kerberos 5 situation:
The API for krb5 changed between one of the betas and the current, 1.0
release. Consequently, things that compiled under the beta no longer
work. Here's a patch to make /usr/bin/login work with the new API
instead of the old one.
One issue here is the addition of -L/usr/local/lib and
-I/usr/local/include to the Makefile. That's where krb5 installs to
by default, so I need these in order to compile here. But they
weren't there before, so maybe there's a good reason for them to not
be there.
>How-To-Repeat:
>Fix:
diff -c -r /foo/src/usr.bin/login/Makefile /usr/src/usr.bin/login/Makefile
*** /foo/src/usr.bin/login/Makefile Tue Jun 24 05:25:30 1997
--- /usr/src/usr.bin/login/Makefile Wed Jul 2 13:51:27 1997
***************
*** 11,18 ****
.if defined(KERBEROS5)
SRCS+= k5login.c
DPADD+= ${LIBKRB5} ${LIBCRYPTO}
! LDADD+= -lkrb5 -lcrypto
! CFLAGS+= -DKERBEROS5
.elif defined(KERBEROS)
SRCS+= klogin.c
DPADD+= ${LIBKRB} ${LIBDES}
--- 11,18 ----
.if defined(KERBEROS5)
SRCS+= k5login.c
DPADD+= ${LIBKRB5} ${LIBCRYPTO}
! LDADD+= -L/usr/local/lib -lkrb5 -lcrypto -lcom_err
! CFLAGS+= -I/usr/local/include -DKERBEROS5
.elif defined(KERBEROS)
SRCS+= klogin.c
DPADD+= ${LIBKRB} ${LIBDES}
diff -c -r /foo/src/usr.bin/login/k5login.c /usr/src/usr.bin/login/k5login.c
*** /foo/src/usr.bin/login/k5login.c Tue Feb 11 05:22:49 1997
--- /usr/src/usr.bin/login/k5login.c Wed Jul 2 13:50:51 1997
***************
*** 43,52 ****
#ifdef KERBEROS5
#include <sys/param.h>
#include <sys/syslog.h>
! #include <com_err.h>
! #include <krb5/krb5.h>
! #include <krb5/ext-proto.h>
! #include <krb5/los-proto.h>
#include <pwd.h>
#include <netdb.h>
#include <stdio.h>
--- 43,49 ----
#ifdef KERBEROS5
#include <sys/param.h>
#include <sys/syslog.h>
! #include <krb5.h>
#include <pwd.h>
#include <netdb.h>
#include <stdio.h>
***************
*** 57,74 ****
#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
krb5_data tgtname = {
KRB5_TGS_NAME_SIZE,
KRB5_TGS_NAME
};
! /*
! * Try no preauthentication first; then try the encrypted timestamp
! */
! int preauth_search_list[] = {
! 0,
! KRB5_PADATA_ENC_TIMESTAMP,
! -1
! };
extern int notickets;
extern char *krbtkfile_env;
--- 54,65 ----
#define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */
krb5_data tgtname = {
+ 0,
KRB5_TGS_NAME_SIZE,
KRB5_TGS_NAME
};
! krb5_context kcontext;
extern int notickets;
extern char *krbtkfile_env;
***************
*** 109,115 ****
}
#endif
! krb5_init_ets();
/*
* Root logins don't use Kerberos.
--- 100,106 ----
}
#endif
! krb5_init_ets(kcontext);
/*
* Root logins don't use Kerberos.
***************
*** 120,126 ****
* without issuing any tickets.
*/
if (strcmp(pw->pw_name, "root") == 0 ||
! krb5_get_default_realm(&realm))
return (1);
/*
--- 111,117 ----
* without issuing any tickets.
*/
if (strcmp(pw->pw_name, "root") == 0 ||
! krb5_get_default_realm(kcontext, &realm))
return (1);
/*
***************
*** 137,168 ****
"FILE:/tmp/krb5cc_root_%d.%s", pw->pw_uid, tty);
krbtkfile_env = tkt_location;
! principal = malloc(strlen(pw->pw_name)+strlen(instance)+2);
strcpy(principal, pw->pw_name); /* XXX strcpy is safe */
if (strlen(instance)) {
strcat(principal, "/"); /* XXX strcat is safe */
strcat(principal, instance); /* XXX strcat is safe */
}
! if (kerror = krb5_cc_resolve(tkt_location, &ccache)) {
syslog(LOG_NOTICE, "warning: %s while getting default ccache",
error_message(kerror));
return(1);
}
! if (kerror = krb5_parse_name(principal, &me)) {
syslog(LOG_NOTICE, "warning: %s when parsing name %s",
error_message(kerror), principal);
return(1);
}
! if (kerror = krb5_unparse_name(me, &client_name)) {
syslog(LOG_NOTICE, "warning: %s when unparsing name %s",
error_message(kerror), principal);
return(1);
}
! kerror = krb5_cc_initialize (ccache, me);
if (kerror != 0) {
syslog(LOG_NOTICE, "%s when initializing cache %s",
error_message(kerror), tkt_location);
--- 128,159 ----
"FILE:/tmp/krb5cc_root_%d.%s", pw->pw_uid, tty);
krbtkfile_env = tkt_location;
! principal = (char *)malloc(strlen(pw->pw_name)+strlen(instance)+2);
strcpy(principal, pw->pw_name); /* XXX strcpy is safe */
if (strlen(instance)) {
strcat(principal, "/"); /* XXX strcat is safe */
strcat(principal, instance); /* XXX strcat is safe */
}
! if (kerror = krb5_cc_resolve(kcontext, tkt_location, &ccache)) {
syslog(LOG_NOTICE, "warning: %s while getting default ccache",
error_message(kerror));
return(1);
}
! if (kerror = krb5_parse_name(kcontext, principal, &me)) {
syslog(LOG_NOTICE, "warning: %s when parsing name %s",
error_message(kerror), principal);
return(1);
}
! if (kerror = krb5_unparse_name(kcontext, me, &client_name)) {
syslog(LOG_NOTICE, "warning: %s when unparsing name %s",
error_message(kerror), principal);
return(1);
}
! kerror = krb5_cc_initialize (kcontext, ccache, me);
if (kerror != 0) {
syslog(LOG_NOTICE, "%s when initializing cache %s",
error_message(kerror), tkt_location);
***************
*** 173,184 ****
my_creds.client = me;
! if (kerror = krb5_build_principal_ext(&server,
! krb5_princ_realm(me)->length,
! krb5_princ_realm(me)->data,
tgtname.length, tgtname.data,
! krb5_princ_realm(me)->length,
! krb5_princ_realm(me)->data,
0)) {
syslog(LOG_NOTICE, "%s while building server name",
error_message(kerror));
--- 164,176 ----
my_creds.client = me;
! if (kerror = krb5_build_principal_ext(kcontext,
! &server,
! krb5_princ_realm(kcontext, me)->length,
! krb5_princ_realm(kcontext, me)->data,
tgtname.length, tgtname.data,
! krb5_princ_realm(kcontext, me)->length,
! krb5_princ_realm(kcontext, me)->data,
0)) {
syslog(LOG_NOTICE, "%s while building server name",
error_message(kerror));
***************
*** 187,200 ****
my_creds.server = server;
! kerror = krb5_os_localaddr(&my_addresses);
if (kerror != 0) {
syslog(LOG_NOTICE, "%s when getting my address",
error_message(kerror));
return(1);
}
! if (kerror = krb5_timeofday(&now)) {
syslog(LOG_NOTICE, "%s while getting time of day",
error_message(kerror));
return(1);
--- 179,192 ----
my_creds.server = server;
! kerror = krb5_os_localaddr(kcontext, &my_addresses);
if (kerror != 0) {
syslog(LOG_NOTICE, "%s when getting my address",
error_message(kerror));
return(1);
}
! if (kerror = krb5_timeofday(kcontext, &now)) {
syslog(LOG_NOTICE, "%s while getting time of day",
error_message(kerror));
return(1);
***************
*** 204,224 ****
my_creds.times.endtime = now + lifetime;
my_creds.times.renew_till = 0;
! for (i=0; preauth_search_list[i] >= 0; i++) {
! kerror = krb5_get_in_tkt_with_password(options, my_addresses,
! preauth_search_list[i],
! ETYPE_DES_CBC_CRC,
! KEYTYPE_DES,
! password,
! ccache,
! &my_creds, 0);
! if (kerror != KRB5KDC_PREAUTH_FAILED &&
! kerror != KRB5KRB_ERR_GENERIC)
! break;
! }
! krb5_free_principal(server);
! krb5_free_addresses(my_addresses);
if (chown(&tkt_location[5], pw->pw_uid, pw->pw_gid) < 0)
syslog(LOG_ERR, "chown tkfile (%s): %m", &tkt_location[5]);
--- 196,211 ----
my_creds.times.endtime = now + lifetime;
my_creds.times.renew_till = 0;
! kerror = krb5_get_in_tkt_with_password(kcontext, options,
! my_addresses,
! NULL,
! NULL,
! password,
! ccache,
! &my_creds, 0);
! krb5_free_principal(kcontext, server);
! krb5_free_addresses(kcontext, my_addresses);
if (chown(&tkt_location[5], pw->pw_uid, pw->pw_gid) < 0)
syslog(LOG_ERR, "chown tkfile (%s): %m", &tkt_location[5]);
***************
*** 249,259 ****
if (krbtkfile_env == NULL)
return;
! code = krb5_cc_resolve(krbtkfile_env, &ccache);
if (!code) {
! code = krb5_cc_destroy(ccache);
if (!code) {
! krb5_cc_close(ccache);
}
}
}
--- 236,246 ----
if (krbtkfile_env == NULL)
return;
! code = krb5_cc_resolve(kcontext, krbtkfile_env, &ccache);
if (!code) {
! code = krb5_cc_destroy(kcontext, ccache);
if (!code) {
! krb5_cc_close(kcontext, ccache);
}
}
}
Only in /usr/src/usr.bin/login: k5login.o
Only in /usr/src/usr.bin/login: login
diff -c -r /foo/src/usr.bin/login/login.c /usr/src/usr.bin/login/login.c
*** /foo/src/usr.bin/login/login.c Sun Jun 29 05:25:38 1997
--- /usr/src/usr.bin/login/login.c Wed Jul 2 13:12:27 1997
***************
*** 75,80 ****
--- 75,84 ----
#include <utmp.h>
#include <util.h>
+ #ifdef KERBEROS5
+ #include <krb5.h> /* Solely for definition of kcontext */
+ #endif
+
#include "pathnames.h"
void badlogin __P((char *));
***************
*** 110,115 ****
--- 114,122 ----
char *krbtkfile_env;
int authok;
#endif
+ #ifdef KERBEROS5
+ extern krb5_context kcontext;
+ #endif
struct passwd *pwd;
int failures;
***************
*** 135,140 ****
--- 142,150 ----
char *domain, *p, *salt, *ttyn, *pwprompt;
char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
char localhost[MAXHOSTNAMELEN];
+ #ifdef KERBEROS5
+ krb5_error_code kerror;
+ #endif
tbuf[0] = '\0';
rval = 0;
***************
*** 218,223 ****
--- 228,242 ----
++tty;
else
tty = ttyn;
+
+ #ifdef KERBEROS5
+ kerror = krb5_init_context(&kcontext);
+ if(kerror) {
+ syslog(LOG_NOTICE, "%s when initializing Kerberos context",
+ error_message(kerror));
+ exit(1);
+ }
+ #endif KERBEROS5
for (cnt = 0;; ask = 1) {
#ifdef SKEY
Only in /usr/src/usr.bin/login: login.cat1
Only in /usr/src/usr.bin/login: login.o
>Audit-Trail:
>Unformatted: