[12284] | 1 | /* |
---|
[20266] | 2 | * $Id: klist.c,v 1.4 2004-03-11 20:37:56 rbasch Exp $ |
---|
[12284] | 3 | * |
---|
| 4 | * Copyright 1990, 1991 by the Massachusetts Institute of Technology. |
---|
| 5 | * |
---|
| 6 | * For copying and distribution information, please see the file |
---|
| 7 | * <mit-copyright.h>. |
---|
| 8 | * |
---|
| 9 | */ |
---|
| 10 | |
---|
| 11 | #if (!defined(lint)) && (!defined(SABER)) |
---|
| 12 | static char *rcsid = |
---|
[20266] | 13 | "$Id: klist.c,v 1.4 2004-03-11 20:37:56 rbasch Exp $"; |
---|
[12284] | 14 | #endif |
---|
| 15 | |
---|
| 16 | #include "mit-copyright.h" |
---|
| 17 | #include <stdio.h> |
---|
[20266] | 18 | #include <stdlib.h> |
---|
[12284] | 19 | #include <errno.h> |
---|
| 20 | #include <string.h> |
---|
| 21 | #include <sys/types.h> |
---|
| 22 | #include <sys/file.h> |
---|
| 23 | #include <sys/stat.h> |
---|
| 24 | #include <krb.h> |
---|
| 25 | #include <Jets/Jets.h> |
---|
| 26 | #include <Jets/Button.h> |
---|
| 27 | #include <Jets/warn.h> |
---|
| 28 | |
---|
| 29 | |
---|
| 30 | #ifndef TICKET_GRANTING_TICKET |
---|
| 31 | #define TICKET_GRANTING_TICKET "krbtgt" |
---|
| 32 | #endif |
---|
| 33 | |
---|
| 34 | #define WARN1_TIME 15 |
---|
| 35 | #define WARN2_TIME 5 |
---|
| 36 | |
---|
| 37 | extern Jet root; |
---|
| 38 | |
---|
| 39 | static Warning *old_warn = NULL; |
---|
| 40 | static int ok(); |
---|
| 41 | |
---|
| 42 | void checkTkts(info, id) |
---|
| 43 | int info, id; |
---|
| 44 | { |
---|
| 45 | char pname[ANAME_SZ]; |
---|
| 46 | char pinst[INST_SZ]; |
---|
| 47 | char prealm[REALM_SZ]; |
---|
| 48 | int k_errno; |
---|
| 49 | CREDENTIALS c; |
---|
| 50 | char *file; |
---|
| 51 | int ret = 0; |
---|
| 52 | static int old_ret = 0; |
---|
| 53 | static time_t mod_time = 0; |
---|
| 54 | static long exp_time; |
---|
| 55 | struct stat statbuf; |
---|
| 56 | int diff; |
---|
| 57 | unsigned int timeout = 5*60*1000; /* 5 minutes... */ |
---|
| 58 | char line1[100]; |
---|
| 59 | char *line2 = "Type `renew' to re-authenticate."; |
---|
| 60 | |
---|
| 61 | line1[0] = '\0'; |
---|
| 62 | |
---|
| 63 | if ((file = getenv("KRBTKFILE")) == NULL) |
---|
| 64 | file = TKT_FILE; |
---|
| 65 | |
---|
| 66 | |
---|
| 67 | if (stat(file, &statbuf)) |
---|
| 68 | { |
---|
| 69 | sprintf(line1, "%s: `%s'", strerror(errno), file); |
---|
| 70 | |
---|
| 71 | ret = 1; |
---|
| 72 | goto done; |
---|
| 73 | } |
---|
| 74 | |
---|
| 75 | if (statbuf.st_mtime != mod_time) |
---|
| 76 | mod_time = statbuf.st_mtime; |
---|
| 77 | else if (exp_time - time(0) > 15 * 60) |
---|
| 78 | { |
---|
| 79 | ret = 0; |
---|
| 80 | goto done; |
---|
| 81 | } |
---|
| 82 | |
---|
| 83 | /* |
---|
| 84 | * Since krb_get_tf_realm will return a ticket_file error, |
---|
| 85 | * we will call tf_init and tf_close first to filter out |
---|
| 86 | * things like no ticket file. Otherwise, the error that |
---|
| 87 | * the user would see would be |
---|
| 88 | * klist: can't find realm of ticket file: No ticket file (tf_util) |
---|
| 89 | * instead of |
---|
| 90 | * klist: No ticket file (tf_util) |
---|
| 91 | */ |
---|
| 92 | |
---|
| 93 | /* Open ticket file */ |
---|
| 94 | if (k_errno = tf_init(file, R_TKT_FIL)) |
---|
| 95 | { |
---|
| 96 | sprintf(line1, "%s", krb_err_txt[k_errno]); |
---|
| 97 | ret = 1; |
---|
| 98 | goto done; |
---|
| 99 | } |
---|
| 100 | /* Close ticket file */ |
---|
| 101 | (void) tf_close(); |
---|
| 102 | |
---|
| 103 | /* |
---|
| 104 | * We must find the realm of the ticket file here before calling |
---|
| 105 | * tf_init because since the realm of the ticket file is not |
---|
| 106 | * really stored in the principal section of the file, the |
---|
| 107 | * routine we use must itself call tf_init and tf_close. |
---|
| 108 | */ |
---|
| 109 | if ((k_errno = krb_get_tf_realm(file, prealm)) != KSUCCESS) |
---|
| 110 | { |
---|
| 111 | sprintf(line1, "can't find realm of ticket file: %s", |
---|
| 112 | krb_err_txt[k_errno]); |
---|
| 113 | ret = 1; |
---|
| 114 | goto done; |
---|
| 115 | } |
---|
| 116 | |
---|
| 117 | /* Open ticket file, get principal name and instance */ |
---|
| 118 | if ((k_errno = tf_init(file, R_TKT_FIL)) || |
---|
| 119 | (k_errno = tf_get_pname(pname)) || |
---|
| 120 | (k_errno = tf_get_pinst(pinst))) |
---|
| 121 | { |
---|
| 122 | sprintf(line1, "%s", krb_err_txt[k_errno]); |
---|
| 123 | ret = 1; |
---|
| 124 | goto done; |
---|
| 125 | } |
---|
| 126 | |
---|
| 127 | /* |
---|
| 128 | * You may think that this is the obvious place to get the |
---|
| 129 | * realm of the ticket file, but it can't be done here as the |
---|
| 130 | * routine to do this must open the ticket file. This is why |
---|
| 131 | * it was done before tf_init. |
---|
| 132 | */ |
---|
| 133 | |
---|
| 134 | while ((k_errno = tf_get_cred(&c)) == KSUCCESS) |
---|
| 135 | { |
---|
| 136 | if (!strcmp(c.service, TICKET_GRANTING_TICKET) && |
---|
| 137 | !strcmp(c.instance, prealm)) |
---|
| 138 | { |
---|
| 139 | exp_time = c.issue_date + ((unsigned char) c.lifetime) * 5 * 60; |
---|
| 140 | diff = exp_time - time(0); |
---|
| 141 | |
---|
| 142 | if (diff < 0) |
---|
| 143 | { |
---|
| 144 | strcpy(line1, "Your authentication has expired."); |
---|
| 145 | ret = 3; /* has expired */ |
---|
| 146 | goto done; |
---|
| 147 | } |
---|
| 148 | |
---|
| 149 | if (diff < WARN1_TIME * 60) /* inside of 15 minutes? */ |
---|
| 150 | { |
---|
| 151 | char *expire_str = |
---|
| 152 | "Your authentication will expire in less than %d minutes."; |
---|
| 153 | timeout = 60*1000; /* set timeout to 1 minute... */ |
---|
| 154 | |
---|
| 155 | if (diff < WARN2_TIME * 60) /* inside of 5 minutes? */ |
---|
| 156 | { |
---|
| 157 | sprintf(line1, expire_str, WARN2_TIME); |
---|
| 158 | ret = 2; |
---|
| 159 | goto done; |
---|
| 160 | } |
---|
| 161 | sprintf(line1, expire_str, WARN1_TIME); |
---|
| 162 | ret = 1; |
---|
| 163 | goto done; |
---|
| 164 | } |
---|
| 165 | |
---|
| 166 | ret = 0; /* tgt hasn't expired */ |
---|
| 167 | goto done; |
---|
| 168 | } |
---|
| 169 | continue; /* not a tgt */ |
---|
| 170 | } |
---|
| 171 | |
---|
| 172 | strcpy(line1, "You have no authentication."); |
---|
| 173 | ret = 1; /* no tgt found */ |
---|
| 174 | |
---|
| 175 | |
---|
| 176 | |
---|
| 177 | done: |
---|
| 178 | if (ret && (old_ret != ret)) |
---|
| 179 | { |
---|
| 180 | Warning *w; |
---|
| 181 | |
---|
| 182 | /* Destroy last warning if user hasn't clicked it away already */ |
---|
| 183 | if (old_warn != NULL) |
---|
| 184 | XjCallCallbacks((caddr_t) old_warn, |
---|
| 185 | old_warn->button->button.activateProc, NULL); |
---|
| 186 | |
---|
| 187 | w = (Warning *)XjMalloc((unsigned) sizeof(Warning)); |
---|
| 188 | |
---|
| 189 | w->me.next = NULL; |
---|
[12537] | 190 | w->me.argType = argPtr; |
---|
| 191 | w->me.passPtr = w; |
---|
[12284] | 192 | w->me.proc = ok; |
---|
| 193 | |
---|
| 194 | w->l1 = XjNewString(line1); |
---|
| 195 | w->l2 = XjNewString(line2); |
---|
| 196 | |
---|
| 197 | old_warn = XjUserWarning(root, w, True, line1, line2); |
---|
| 198 | } |
---|
| 199 | old_ret = ret; |
---|
| 200 | (void) tf_close(); |
---|
| 201 | XjAddWakeup(checkTkts, NULL, timeout); |
---|
| 202 | /* return ret; */ |
---|
| 203 | } |
---|
| 204 | |
---|
| 205 | static int ok(who, w, data) |
---|
| 206 | Jet who; |
---|
| 207 | Warning *w; |
---|
| 208 | caddr_t data; |
---|
| 209 | { |
---|
| 210 | Display *dpy; |
---|
| 211 | |
---|
| 212 | dpy = w->top->core.display; /* save off the display before */ |
---|
| 213 | /* destroying the Jet */ |
---|
| 214 | XjDestroyJet(w->top); |
---|
| 215 | XFlush(dpy); |
---|
| 216 | |
---|
| 217 | XjFree(w->l1); |
---|
| 218 | XjFree(w->l2); |
---|
| 219 | XjFree((char *) w); |
---|
| 220 | old_warn = NULL; |
---|
| 221 | return 0; |
---|
| 222 | } |
---|