Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:mreggie
screen
krb5.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File krb5.diff of Package screen
diff -urN ./config.h.in ./config.h.in --- ./config.h.in 2012-06-11 17:54:33.000000000 +0200 +++ ./config.h.in 2013-04-19 11:49:16.000000000 +0200 @@ -283,6 +283,12 @@ * (You may also need to add -lpam to LIBS in the Makefile.) */ #undef USE_PAM + +/* + * Define USE_KRB5 if your system uses Kerberos tickets and you want + * screen to use a private ticket cache and automatically renew it. + */ +#undef USE_KRB5 /* * Define CHECK_SCREEN_W if you want screen to set TERM to screen-w diff -urN ./configure.in ./configure.in --- ./configure.in 2014-04-26 12:58:35.000000000 +0200 +++ ./configure.in 2014-08-29 16:42:09.000000000 +0200 @@ -1287,6 +1287,18 @@ if test "$enable_rxvt_osc" = "yes"; then AC_DEFINE(RXVT_OSC) fi +AC_ARG_ENABLE(krb5, [ --enable-krb5 enable Kerberos 5 support]) +if test "$enable_krb5" = "yes"; then + AC_MSG_CHECKING(for Kerberos support) + oldlibs="$LIBS" + LIBS="$LIBS -lkrb5" + AC_TRY_LINK([#include <krb5.h>], [ + krb5_context context; + krb5_init_context(&context); + krb5_free_context(context) + ], AC_MSG_RESULT(yes);AC_DEFINE(USE_KRB5, 1, [Enable Kerberos 5 support]), + AC_MSG_RESULT(no);LIBS="$oldlibs") +fi dnl dnl **** the end **** diff -urN ./kerberos.c ./kerberos.c --- ./kerberos.c 1970-01-01 01:00:00.000000000 +0100 +++ ./kerberos.c 2013-04-19 11:49:16.000000000 +0200 @@ -0,0 +1,207 @@ +/* Copyright (c) 2005 + * Fredrik Tolf (fredrik@dolda2000.com) + * Copyright (c) 2013 + * Robbert Eggermont (R.Eggermont@tudelft.nl) + * + * 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 (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + */ + +#include "config.h" +#ifdef USE_KRB5 + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <krb5.h> + +#include "screen.h" +#include "extern.h" + +#define KRB5_OK 0 +#define SAFETY_MARGIN 5 +#define MIN_TIMEOUT (60 * 60) + +static int krb_enabled = 0; +static struct event krb_ev; +static char krb5ccname[40]; +static void krb_renew(struct event *, char *); + +void +krb_error(krb5_context const context, krb5_error_code const error_code, char const *const custom_msg) +{ + char const *const error_msg = krb5_get_error_message(context, error_code); + Msg(0, "%s: %s", custom_msg, error_msg); + krb5_free_error_message(context, error_msg); + return; +} + +void +krb_init() +{ + krb5_error_code retval = 0; + krb5_context context; + krb5_ccache origcache = NULL; + krb5_ccache ccache = NULL; + krb5_principal principal = NULL; + krb5_creds creds; + char *const ccname = krb5ccname + 5; /* Filename without leading "FILE:" */ + int krb5cc = -1; + time_t timeout = MIN_TIMEOUT; /* Retry timeout in case of an error */ + + /* Create Kerberos context */ + retval = krb5_init_context(&context); + if (retval == KRB5_OK) { + /* Create our own unique credentials cache */ + snprintf(krb5ccname, sizeof(krb5ccname), "FILE:/tmp/krb5cc_%u_XXXXXX", (unsigned int) getuid()); + krb5cc = mkstemp(ccname); /* krb5_cc_new_unique is unusable: /tmp/tktXXXXXX */ + if (krb5cc != -1) { + close(krb5cc); + + /* + * We have Kerberos and our own credentials cache. From this point on, + * failures don't have to be permanent (the credentials cache can be + * manipulated from the outside), so we enable the Kerberos renewal. + */ + krb_enabled = 1; + + /* Copy Kerberos credentials from the original ticket cache */ + retval = krb5_cc_default(context, &origcache); + if (retval == KRB5_OK) { + retval = krb5_cc_get_principal(context, origcache, &principal); + if (retval == KRB5_OK) { + retval = krb5_get_renewed_creds(context, &creds, principal, origcache, NULL); + if (retval == KRB5_OK) { + retval = krb5_cc_resolve(context, krb5ccname, &ccache); + if (retval == KRB5_OK) { + retval = krb5_cc_initialize(context, ccache, principal); + if (retval == KRB5_OK) { + retval = krb5_cc_store_cred(context, ccache, &creds); + if (retval == KRB5_OK) { + Msg(0, "Renewed Kerberos credentials successfully."); + timeout = (time_t)creds.times.endtime - time(NULL) - 2 * MIN_TIMEOUT - SAFETY_MARGIN; /* Set timeout to 2 MIN_TIMEOUT intervals (plus a small SAFETY_MARGIN) before the credentials expire, so in case the next renewal fails we can do 2 retries before the credentials really expire. */ + if (timeout < MIN_TIMEOUT) timeout = MIN_TIMEOUT; /* Credentials (almost) expired; no point to retry so fast. */ + } else { /* krb5_cc_store_cred */ + krb_error(context, retval, "Could not store new credentials"); + krb5_cc_destroy(context, ccache); /* Cache file in unknown state */ + } + } else krb_error(context, retval, "Could not initialize new credentials cache"); /* krb5_cc_initialize */ + krb5_cc_close(context, ccache); /* Clean up krb5_cc_resolve */ + } else krb_error(context, retval, "Could not resolve new credentials cache"); /* krb5_cc_resolve */ + krb5_free_cred_contents(context, &creds); /* Clean up krb5_get_renewed_credentials */ + } else krb_error(context, retval, "Could not renew credentials"); /* krb5_get_renewed_credentials */ + krb5_free_principal(context, principal); /* Clean up krb5_cc_get_principal */ + } else krb_error(context, retval, "Could not get Kerberos principal from credentials cache"); /* krb5_cc_get_principal */ + krb5_cc_close(context, origcache); /* Clean up krb5_cc_default */ + } else krb_error(context, retval, "Could not get Kerberos credentials cache"); /* krb5_cc_default */ + + /* Pass the Kerberos credentials cache name to the child processess */ + xsetenv("KRB5CCNAME", krb5ccname); + MakeNewEnv(); + + /* Start Kerberos ticket renewal timer */ + memset(&krb_ev, 0, sizeof(krb_ev)); + krb_ev.type = EV_TIMEOUT; + krb_ev.handler = krb_renew; + SetTimeout(&krb_ev, timeout * 1000); /* Milliseconds */ + evenq(&krb_ev); + + } else Msg(errno, "Could not create Kerberos credentials cache file %s.", ccname); /* mkstemp */ + krb5_free_context(context); /* Clean up krb5_init_context */ + } else krb_error(context, retval, "Could not initialize Kerberos library"); /* krb5_init_context */ + + return; +} + +static void +krb_renew(ev, data) +struct event *ev; +char *data; +{ + krb5_error_code retval = 0; + krb5_context context; + krb5_ccache ccache; + krb5_principal principal; + krb5_creds creds; + time_t timeout = MIN_TIMEOUT; /* Retry timeout in case of an error */ + + /* Renew credentials */ + retval = krb5_init_context(&context); + if (retval == KRB5_OK) { + retval = krb5_cc_resolve(context, krb5ccname, &ccache); + if (retval == KRB5_OK) { + retval = krb5_cc_get_principal(context, ccache, &principal); + if (retval == KRB5_OK) { + retval = krb5_get_renewed_creds(context, &creds, principal, ccache, NULL); + if (retval == KRB5_OK) { + retval = krb5_cc_initialize(context, ccache, principal); + if (retval == KRB5_OK) { + retval = krb5_cc_store_cred(context, ccache, &creds); + if (retval == KRB5_OK) { + Msg(0, "Renewed Kerberos credentials successfully."); + timeout = (time_t)creds.times.endtime - time(NULL) - 2 * MIN_TIMEOUT - SAFETY_MARGIN; /* Set timeout to 2 MIN_TIMEOUT intervals (plus a small SAFETY_MARGIN) before the credentials expire, so in case the next renewal fails we can do 2 retries before the credentials really expire. */ + if (timeout < MIN_TIMEOUT) timeout = MIN_TIMEOUT; /* Credentials (almost) expired; no point to retry so fast. */ + } else { /* krb5_cc_store_cred */ + krb_error(context, retval, "Could not store new credentials"); + krb5_cc_destroy(context, ccache); /* Cache file in unknown state */ + } + } else krb_error(context, retval, "Could not initialize new credentials cache"); /* krb5_cc_initialize */ + krb5_free_cred_contents(context, &creds); /* Clean up krb5_get_renewed_credentials */ + } else krb_error(context, retval, "Could not renew credentials"); /* krb5_get_renewed_credentials */ + krb5_free_principal(context, principal); /* Clean up krb5_cc_get_principal */ + } else krb_error(context, retval, "Could not get Kerberos principal from credentials cache"); /* krb5_cc_get_principal */ + krb5_cc_close(context, ccache); /* Clean up krb5_cc_default */ + } else krb_error(context, retval, "Could not get Kerberos credentials cache"); /* krb5_cc_default */ + krb5_free_context(context); /* Clean up krb5_init_context */ + } else krb_error(context, retval, "Could not initialize Kerberos library"); /* krb5_init_context */ + + /* Re-enqueue */ + SetTimeout(ev, timeout * 1000); /* Milliseconds */ + evenq(ev); + + return; +} + +void +krb_cleanup() +{ + krb5_error_code retval = 0; + krb5_context context; + krb5_ccache ccache; + + if (krb_enabled) { + retval = krb5_init_context(&context); + if (retval == KRB5_OK) { + retval = krb5_cc_resolve(context, krb5ccname, &ccache); + if (retval == KRB5_OK) { + retval = krb5_cc_destroy(context, ccache); + if (retval == KRB5_OK) { + Msg(0, "Kerberos credentials cache destroyed."); + } else krb_error(context, retval, "Could not destroy Kerberos credentials cache"); /* krb5_cc_destroy */ + } else krb_error(context, retval, "Could not get Kerberos credentials cache"); /* krb5_cc_default */ + krb5_free_context(context); /* Clean up krb5_init_context */ + } else krb_error(context, retval, "Could not initialize Kerberos library"); /* krb5_init_context */ + } + + return; +} + +#endif diff -urN ./Makefile.in ./Makefile.in --- ./Makefile.in 2012-06-11 17:54:33.000000000 +0200 +++ ./Makefile.in 2013-04-19 12:08:24.000000000 +0200 @@ -65,13 +65,13 @@ termcap.c input.c attacher.c pty.c process.c display.c comm.c \ kmapdef.c acls.c braille.c braille_tsi.c logfile.c layer.c \ sched.c teln.c nethack.c encoding.c canvas.c layout.c viewport.c \ - list_display.c list_generic.c list_window.c + list_display.c list_generic.c list_window.c kerberos.c OFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \ search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \ termcap.o input.o attacher.o pty.o process.o display.o comm.o \ kmapdef.o acls.o braille.o braille_tsi.o logfile.o layer.o \ list_generic.o list_display.o list_window.o \ - sched.o teln.o nethack.o encoding.o canvas.o layout.o viewport.o + sched.o teln.o nethack.o encoding.o canvas.o layout.o viewport.o kerberos.o all: screen @@ -353,4 +353,6 @@ list_generic.o: list_generic.h list_generic.c layer.h screen.h osdef.h list_display.o: list_generic.h list_display.c layer.h screen.h osdef.h list_window.o: list_generic.h list_window.c window.h layer.h screen.h osdef.h +kerberos.o: layout.h viewport.h canvas.h kerberos.c config.h screen.h os.h osdef.h ansi.h sched.h acls.h \ + comm.h layer.h term.h image.h display.h window.h extern.h diff -urN ./screen.c ./screen.c --- ./screen.c 2012-06-08 17:20:18.000000000 +0200 +++ ./screen.c 2013-04-19 11:49:16.000000000 +0200 @@ -1424,6 +1424,10 @@ #endif FinishRc(RcFileName); +#ifdef USE_KRB5 + krb_init(); +#endif + debug2("UID %d EUID %d\n", (int)getuid(), (int)geteuid()); if (windows == NULL) { @@ -1833,6 +1837,9 @@ xsetegid(eff_gid); #endif } +#ifdef USE_KRB5 + krb_cleanup(); +#endif for (display = displays; display; display = display->d_next) { if (D_status)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor