summaryrefslogtreecommitdiffstats
path: root/src/windows/leashdll
diff options
context:
space:
mode:
authorKevin Wasserman <kevin.wasserman@painless-security.com>2012-07-23 04:30:27 -0400
committerBen Kaduk <kaduk@mit.edu>2012-08-24 12:22:58 -0400
commit9bc411e72fce5bed3ed00ae5b09f8c239309bae0 (patch)
tree0b457e8c5e0d1201f2bc4a58e2540ca3eba44ca4 /src/windows/leashdll
parentdbfd93ea15b12472e4612af928f8baabb2cda611 (diff)
downloadkrb5-9bc411e72fce5bed3ed00ae5b09f8c239309bae0.tar.gz
krb5-9bc411e72fce5bed3ed00ae5b09f8c239309bae0.tar.xz
krb5-9bc411e72fce5bed3ed00ae5b09f8c239309bae0.zip
kfw support for multiple identities
We need a sense of what the default identity is, then, with a way to set it and list it. The memory management model changes some, as well. Use a bold font to indicate the current default identity in the GUI; while here use an italic font for expired credentials. In the process, rip out some krb4 remenants, and remove ancient code conditional on the lack of KRB5_TC_NOTICKET. Define USE_MESSAGE_BOX when building leash and use MessageBox(). [kaduk@mit.edu: adjust for style, flesh out commit message.] ticket: 7253 (new) queue: kfw target_version: 1.10.4 tags: pullup
Diffstat (limited to 'src/windows/leashdll')
-rw-r--r--src/windows/leashdll/AFSroutines.c3
-rw-r--r--src/windows/leashdll/krb5routines.c790
-rw-r--r--src/windows/leashdll/leash-int.h4
-rw-r--r--src/windows/leashdll/leashdll.h15
-rw-r--r--src/windows/leashdll/leashw32.def1
-rw-r--r--src/windows/leashdll/lshfunc.c45
6 files changed, 389 insertions, 469 deletions
diff --git a/src/windows/leashdll/AFSroutines.c b/src/windows/leashdll/AFSroutines.c
index 3c1dbc02d3..f04ab29792 100644
--- a/src/windows/leashdll/AFSroutines.c
+++ b/src/windows/leashdll/AFSroutines.c
@@ -207,8 +207,7 @@ not_an_API_LeashAFSGetToken(
list->name = strdup(aclient.name);
list->inst = aclient.instance[0] ? strdup(aclient.instance) : NULL;
list->realm = strdup(aclient.cell);
- list->tktEncType = NULL;
- list->keyEncType = NULL;
+ list->encTypes = NULL;
list->addrCount = 0;
list->addrList = NULL;
diff --git a/src/windows/leashdll/krb5routines.c b/src/windows/leashdll/krb5routines.c
index 48240bfc97..8de3179004 100644
--- a/src/windows/leashdll/krb5routines.c
+++ b/src/windows/leashdll/krb5routines.c
@@ -315,412 +315,326 @@ one_addr(krb5_address *a)
return(retstr);
}
-/*
- * LeashKRB5GetTickets() treats krbv5Context as an in/out variable.
- * If the caller does not provide a krb5_context, one will be allocated.
- * It is up to the caller to ensure that the context is eventually freed.
- * A context can be returned even if the function returns an error.
- */
+static void
+CredToTicketInfo(krb5_creds KRBv5Credentials, TICKETINFO *ticketinfo)
+{
+ ticketinfo->issued = KRBv5Credentials.times.starttime;
+ ticketinfo->valid_until = KRBv5Credentials.times.endtime;
+ ticketinfo->renew_until =
+ KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE ?
+ KRBv5Credentials.times.renew_till : 0;
+ _tzset();
+ if (ticketinfo->valid_until - time(0) <= 0L)
+ ticketinfo->btickets = EXPD_TICKETS;
+ else
+ ticketinfo->btickets = GOOD_TICKETS;
+}
-long
-not_an_API_LeashKRB5GetTickets(
- TICKETINFO * ticketinfo,
- TicketList** ticketList,
- krb5_context *krbv5Context
- )
+static int
+CredToTicketList(krb5_context ctx, krb5_creds KRBv5Credentials,
+ char *PrincipalName, TicketList ***ticketListTail)
{
-#ifdef NO_KRB5
- return(0);
-#else
- krb5_context ctx = 0;
- krb5_ccache cache = 0;
- krb5_error_code code;
- krb5_principal KRBv5Principal;
- krb5_flags flags = 0;
- krb5_cc_cursor KRBv5Cursor;
- krb5_creds KRBv5Credentials;
- krb5_ticket *tkt=NULL;
- int StartMonth;
- int EndMonth;
- int RenewMonth;
- int StartDay;
- int EndDay;
- int RenewDay;
- char StartTimeString[256];
- char EndTimeString[256];
- char RenewTimeString[256];
- char fill;
- char *ClientName;
- char *PrincipalName;
- char *sServerName;
- char Buffer[256];
- char Months[12][4] = {"Jan\0", "Feb\0", "Mar\0", "Apr\0", "May\0", "Jun\0", "Jul\0", "Aug\0", "Sep\0", "Oct\0", "Nov\0", "Dec\0"};
- char StartTime[16];
- char EndTime[16];
- char RenewTime[16];
- char temp[128];
- char *sPtr;
- char *ticketFlag;
- LPCSTR functionName;
- TicketList *list = NULL;
-
- if ( ticketinfo ) {
- ticketinfo->btickets = NO_TICKETS;
- ticketinfo->principal[0] = '\0';
- }
+ krb5_error_code code = 0;
+ krb5_ticket *tkt=NULL;
+ char *sServerName = NULL;
+ char Buffer[256];
+ char *ticketFlag;
+ char *functionName = NULL;
+ TicketList *list = NULL;
+
+ functionName = "krb5_unparse_name()";
+ code = (*pkrb5_unparse_name)(ctx, KRBv5Credentials.server, &sServerName);
+ if (code)
+ goto cleanup;
- if ((code = Leash_krb5_initialize(&(*krbv5Context), &cache)))
- return(code);
+ if (!KRBv5Credentials.times.starttime)
+ KRBv5Credentials.times.starttime = KRBv5Credentials.times.authtime;
- ctx = (*krbv5Context);
+ memset(Buffer, '\0', sizeof(Buffer));
-#ifdef KRB5_TC_NOTICKET
- flags = KRB5_TC_NOTICKET;
-#endif
- if ((code = pkrb5_cc_set_flags(ctx, cache, flags)))
- {
- if (code != KRB5_FCC_NOFILE && code != KRB5_CC_NOTFOUND)
- Leash_krb5_error(code, "krb5_cc_set_flags()", 0, &ctx,
- &cache);
- else if ((code == KRB5_FCC_NOFILE || code == KRB5_CC_NOTFOUND))
- {
- if (cache != NULL)
- pkrb5_cc_close(ctx, cache);
- }
- return code;
- }
+ ticketFlag = GetTicketFlag(&KRBv5Credentials);
- if ((code = pkrb5_cc_get_principal(ctx, cache, &KRBv5Principal)))
- {
- if (code != KRB5_FCC_NOFILE && code != KRB5_CC_NOTFOUND)
- Leash_krb5_error(code, "krb5_cc_get_principal()", 0, &ctx, &cache);
- else if ((code == KRB5_FCC_NOFILE || code == KRB5_CC_NOTFOUND))
- {
- if (cache != NULL)
- pkrb5_cc_close(ctx, cache);
- }
- return code;
+ // @fixme: calloc for ptr init
+ list = calloc(1, sizeof(TicketList));
+ if (list == NULL) {
+ code = ENOMEM;
+ functionName = "calloc()";
+ goto cleanup;
}
-
- PrincipalName = NULL;
- ClientName = NULL;
- sServerName = NULL;
- if ((code = (*pkrb5_unparse_name)(ctx, KRBv5Principal,
- (char **)&PrincipalName)))
- {
- if (PrincipalName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
-
- (*pkrb5_free_principal)(ctx, KRBv5Principal);
- if (ctx != NULL)
- {
- if (cache != NULL)
- pkrb5_cc_close(ctx, cache);
- }
-
- return(code);
+ list->service = strdup(sServerName);
+ if (!list->service) {
+ code = ENOMEM;
+ functionName = "calloc()";
+ goto cleanup;
}
-
- if (!strcspn(PrincipalName, "@" ))
- {
- if (PrincipalName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
-
- (*pkrb5_free_principal)(ctx, KRBv5Principal);
- if (ctx != NULL)
- {
- if (cache != NULL)
- pkrb5_cc_close(ctx, cache);
- }
-
- return(code);
+ list->issued = KRBv5Credentials.times.starttime;
+ list->valid_until = KRBv5Credentials.times.endtime;
+ if (KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE)
+ list->renew_until = KRBv5Credentials.times.renew_till;
+ else
+ list->renew_until = 0;
+
+ if (!pkrb5_decode_ticket(&KRBv5Credentials.ticket, &tkt)) {
+ wsprintf(Buffer, "Session Key: %s Ticket: %s",
+ etype_string(KRBv5Credentials.keyblock.enctype),
+ etype_string(tkt->enc_part.enctype));
+ pkrb5_free_ticket(ctx, tkt);
+ tkt = NULL;
+ } else {
+ wsprintf(Buffer, "Session Key: %s",
+ etype_string(KRBv5Credentials.keyblock.enctype));
}
- if ( strcmp(ticketinfo->principal, PrincipalName) )
- wsprintf(ticketinfo->principal, "%s", PrincipalName);
-
- (*pkrb5_free_principal)(ctx, KRBv5Principal);
- if ((code = pkrb5_cc_start_seq_get(ctx, cache, &KRBv5Cursor)))
- {
- functionName = "krb5_cc_start_seq_get()";
- goto on_error;
+ list->encTypes = calloc(1, strlen(Buffer)+1);
+ if (list->encTypes == NULL) {
+ functionName = "calloc()";
+ code = ENOMEM;
+ goto cleanup;
}
+ strcpy(list->encTypes, Buffer);
- memset(&KRBv5Credentials, '\0', sizeof(KRBv5Credentials));
-
- while (!(code = pkrb5_cc_next_cred(ctx, cache, &KRBv5Cursor, &KRBv5Credentials)))
- {
- if ((*pkrb5_is_config_principal)(ctx, KRBv5Credentials.server))
- { /* skip configuration credentials */
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- continue;
- }
- if (!list)
- {
- list = (TicketList*) calloc(1, sizeof(TicketList));
- (*ticketList) = list;
- }
- else
- {
- list->next = (struct TicketList*) calloc(1, sizeof(TicketList));
- list = (TicketList*) list->next;
+cleanup:
+ if (code) {
+ Leash_krb5_error(code, functionName, 0, &ctx, NULL);
+ if (list != NULL) {
+ not_an_API_LeashFreeTicketList(&list);
}
+ } else {
+ **ticketListTail = list;
+ *ticketListTail = &list->next;
+ }
- if ((*pkrb5_unparse_name)(ctx, KRBv5Credentials.client, &ClientName))
- {
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- Leash_krb5_error(code, "krb5_free_cred_contents()", 0, &ctx, &cache);
-
- if (ClientName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, ClientName);
+ if (sServerName != NULL)
+ (*pkrb5_free_unparsed_name)(ctx, sServerName);
- ClientName = NULL;
- sServerName = NULL;
- continue;
- }
+ return code;
+}
- if ((*pkrb5_unparse_name)(ctx, KRBv5Credentials.server, &sServerName))
- {
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- Leash_krb5_error(code, "krb5_free_cred_contents()", 0, &ctx, &cache);
+int
+do_ccache(krb5_context ctx,
+ krb5_ccache cache,
+ TICKETINFO ***ticketInfoTail)
+{
+ krb5_cc_cursor cur;
+ krb5_creds creds;
+ krb5_principal princ = NULL;
+ krb5_flags flags;
+ krb5_error_code code;
+ char *defname = NULL;
+ char *functionName = NULL;
+ TicketList **ticketListTail;
+ TICKETINFO *ticketinfo;
- if (ClientName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, ClientName);
+ flags = 0; /* turns off OPENCLOSE mode */
+ code = pkrb5_cc_set_flags(ctx, cache, flags);
+ if (code) {
+ functionName = "krb5_cc_set_flags";
+ goto cleanup;
+ }
+ code = pkrb5_cc_get_principal(ctx, cache, &princ);
+ if (code) {
+ functionName = "krb5_cc_get_principal";
+ goto cleanup;
+ }
+ code = pkrb5_unparse_name(ctx, princ, &defname);
+ if (code) {
+ functionName = "krb5_unparse_name";
+ goto cleanup;
+ }
+ code = pkrb5_cc_start_seq_get(ctx, cache, &cur);
+ if (code) {
+ functionName = "krb5_cc_start_seq_get";
+ goto cleanup;
+ }
- ClientName = NULL;
- sServerName = NULL;
+ ticketinfo = calloc(1, sizeof(TICKETINFO));
+ if (ticketinfo == NULL) {
+ functionName = "calloc";
+ code = ENOMEM;
+ goto cleanup;
+ }
+ ticketinfo->next = NULL;
+ ticketinfo->ticket_list = NULL;
+ ticketinfo->principal = strdup(defname);
+ if (ticketinfo->principal == NULL) {
+ functionName = "strdup";
+ code = ENOMEM;
+ goto cleanup;
+ }
+ ticketinfo->ccache_name = strdup(pkrb5_cc_get_name(ctx, cache));
+ if (ticketinfo->ccache_name == NULL) {
+ functionName = "strdup";
+ code = ENOMEM;
+ goto cleanup;
+ }
+ **ticketInfoTail = ticketinfo;
+ *ticketInfoTail = &ticketinfo->next;
+ ticketListTail = &ticketinfo->ticket_list;
+ while (!(code = pkrb5_cc_next_cred(ctx, cache, &cur, &creds))) {
+ if (pkrb5_is_config_principal(ctx, creds.server))
continue;
+ CredToTicketList(ctx, creds, defname, &ticketListTail);
+ CredToTicketInfo(creds, ticketinfo);
+ pkrb5_free_cred_contents(ctx, &creds);
+ }
+ if (code == KRB5_CC_END) {
+ code = pkrb5_cc_end_seq_get(ctx, cache, &cur);
+ if (code) {
+ functionName = "krb5_cc_end_seq_get";
+ goto cleanup;
}
-
- if (!KRBv5Credentials.times.starttime)
- KRBv5Credentials.times.starttime = KRBv5Credentials.times.authtime;
-
- fill = ' ';
- memset(StartTimeString, '\0', sizeof(StartTimeString));
- memset(EndTimeString, '\0', sizeof(EndTimeString));
- memset(RenewTimeString, '\0', sizeof(RenewTimeString));
- (*pkrb5_timestamp_to_sfstring)((krb5_timestamp)KRBv5Credentials.times.starttime, StartTimeString, 17, &fill);
- (*pkrb5_timestamp_to_sfstring)((krb5_timestamp)KRBv5Credentials.times.endtime, EndTimeString, 17, &fill);
- if (KRBv5Credentials.times.renew_till >= 0)
- (*pkrb5_timestamp_to_sfstring)((krb5_timestamp)KRBv5Credentials.times.renew_till, RenewTimeString, 17, &fill);
- memset(temp, '\0', sizeof(temp));
- memcpy(temp, StartTimeString, 2);
- StartDay = atoi(temp);
- memset(temp, (int)'\0', (size_t)sizeof(temp));
- memcpy(temp, EndTimeString, 2);
- EndDay = atoi(temp);
- memset(temp, (int)'\0', (size_t)sizeof(temp));
- memcpy(temp, RenewTimeString, 2);
- RenewDay = atoi(temp);
-
- memset(temp, '\0', sizeof(temp));
- memcpy(temp, &StartTimeString[3], 2);
- StartMonth = atoi(temp);
- memset(temp, '\0', sizeof(temp));
- memcpy(temp, &EndTimeString[3], 2);
- EndMonth = atoi(temp);
- memset(temp, '\0', sizeof(temp));
- memcpy(temp, &RenewTimeString[3], 2);
- RenewMonth = atoi(temp);
-
- while (1)
- {
- if ((sPtr = strrchr(StartTimeString, ' ')) == NULL)
- break;
-
- if (strlen(sPtr) != 1)
- break;
-
- (*sPtr) = 0;
+ flags = KRB5_TC_OPENCLOSE; /* turns on OPENCLOSE mode */
+ code = pkrb5_cc_set_flags(ctx, cache, flags);
+ if (code) {
+ functionName = "krb5_cc_set_flags";
+ goto cleanup;
}
+ } else {
+ functionName = "krb5_cc_next_cred";
+ goto cleanup;
+ }
+cleanup:
+ if (code) {
+ Leash_krb5_error(code, functionName, 0, NULL, NULL);
+ }
+ if (princ)
+ pkrb5_free_principal(ctx, princ);
+ if (defname)
+ pkrb5_free_unparsed_name(ctx, defname);
+ return code ? 1 : 0;
+}
- while (1)
- {
- if ((sPtr = strrchr(EndTimeString, ' ')) == NULL)
- break;
-
- if (strlen(sPtr) != 1)
- break;
- (*sPtr) = 0;
- }
+//
+// Returns 0 for success, 1 for failure
+//
+int
+do_all_ccaches(krb5_context ctx, TICKETINFO **ticketinfotail)
+{
+ krb5_error_code code;
+ krb5_ccache cache;
+ krb5_cccol_cursor cursor;
+ int retval = 0;
+ char *functionName = NULL;
- while (1)
- {
- if ((sPtr = strrchr(RenewTimeString, ' ')) == NULL)
- break;
+ code = pkrb5_cccol_cursor_new(ctx, &cursor);
+ if (code) {
+ functionName = "krb5_cccol_cursor_new";
+ goto cleanup;
+ }
+ retval = 0;
+ while (!(code = pkrb5_cccol_cursor_next(ctx, cursor, &cache)) &&
+ cache != NULL) {
+ // Note that ticketList will be updated here to point to the tail
+ // of the list but the caller of this function will remain with a
+ // pointer to the head.
+ do_ccache(ctx, cache, &ticketinfotail);
+ pkrb5_cc_close(ctx, cache);
+ }
+ if (code)
+ functionName = "krb5_cccol_cursor_next";
+ pkrb5_cccol_cursor_free(ctx, &cursor);
+cleanup:
+ if (code) {
+ Leash_krb5_error(code, functionName, 0, NULL, NULL);
+ }
+ return retval;
+}
- if (strlen(sPtr) != 1)
- break;
+static void FreeTicketInfo(TICKETINFO *ticketinfo)
+{
+ if (ticketinfo->principal) {
+ free(ticketinfo->principal);
+ ticketinfo->principal = NULL;
+ }
+ if (ticketinfo->ccache_name) {
+ free(ticketinfo->ccache_name);
+ ticketinfo->ccache_name = NULL;
+ }
+ if (ticketinfo->ticket_list)
+ not_an_API_LeashFreeTicketList(&ticketinfo->ticket_list);
+}
- (*sPtr) = 0;
+long
+not_an_API_LeashKRB5FreeTickets(TICKETINFO *ticketinfo)
+{
+ TICKETINFO *initial = ticketinfo; // @TEMP fixme
+ TICKETINFO *next;
+ while (ticketinfo != NULL) {
+ next = ticketinfo->next;
+ FreeTicketInfo(ticketinfo);
+ // @TEMP fixme
+ if (ticketinfo != initial) {
+ free(ticketinfo);
}
+ ticketinfo = next;
+ }
+ return 0;
+}
- memset(StartTime, '\0', sizeof(StartTime));
- memcpy(StartTime, &StartTimeString[strlen(StartTimeString) - 5], 5);
- memset(EndTime, '\0', sizeof(EndTime));
- memcpy(EndTime, &EndTimeString[strlen(EndTimeString) - 5], 5);
- memset(RenewTime, '\0', sizeof(RenewTime));
- memcpy(RenewTime, &RenewTimeString[strlen(RenewTimeString) - 5], 5);
-
- memset(temp, '\0', sizeof(temp));
- strcpy(temp, ClientName);
- if (!strcmp(ClientName, PrincipalName))
- memset(temp, '\0', sizeof(temp));
+/*
+ * LeashKRB5GetTickets() treats krbv5Context as an in/out variable.
+ * If the caller does not provide a krb5_context, one will be allocated.
+ * It is up to the caller to ensure that the context is eventually freed.
+ * A context can be returned even if the function returns an error.
+ */
- memset(Buffer, '\0', sizeof(Buffer));
+long
+not_an_API_LeashKRB5GetTickets(TICKETINFO *ticketinfo,
+ krb5_context *krbv5Context)
+{
+ krb5_error_code code;
+ krb5_principal me = 0;
+ krb5_context ctx = 0;
+ krb5_ccache cache = 0;
+ char *PrincipalName = NULL;
- ticketFlag = GetTicketFlag(&KRBv5Credentials);
+ code = Leash_krb5_initialize(krbv5Context);
+ if (code)
+ return code;
- if (KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE) {
- wsprintf(Buffer,"%s %02d %s %s %02d %s [%s %02d %s] %s %s %s",
- Months[StartMonth - 1], StartDay, StartTime,
- Months[EndMonth - 1], EndDay, EndTime,
- Months[RenewMonth - 1], RenewDay, RenewTime,
- sServerName,
- temp, ticketFlag);
- } else {
- wsprintf(Buffer,"%s %02d %s %s %02d %s %s %s %s",
- Months[StartMonth - 1], StartDay, StartTime,
- Months[EndMonth - 1], EndDay, EndTime,
- sServerName,
- temp, ticketFlag);
- }
- list->theTicket = (char*) calloc(1, strlen(Buffer)+1);
- if (!list->theTicket)
- {
-#ifdef USE_MESSAGE_BOX
- MessageBox(NULL, "Memory Error", "Error", MB_OK);
-#endif /* USE_MESSAGE_BOX */
- return ENOMEM;
- }
- strcpy(list->theTicket, Buffer);
- list->name = NULL;
- list->inst = NULL;
- list->realm = NULL;
-
- if ( !pkrb5_decode_ticket(&KRBv5Credentials.ticket, &tkt)) {
- wsprintf(Buffer, "Ticket Encryption Type: %s", etype_string(tkt->enc_part.enctype));
- list->tktEncType = (char*) calloc(1, strlen(Buffer)+1);
- if (!list->tktEncType)
- {
-#ifdef USE_MESSAGE_BOX
- MessageBox(NULL, "Memory Error", "Error", MB_OK);
-#endif /* USE_MESSAGE_BOX */
- return ENOMEM;
- }
- strcpy(list->tktEncType, Buffer);
+ ctx = *krbv5Context;
- pkrb5_free_ticket(ctx, tkt);
- tkt = NULL;
- } else {
- list->tktEncType = NULL;
- }
+ // @TEMP fixme; shouldn't be necessary
+ // save default principal name in ticketinfo
+ if (ticketinfo != NULL) {
+ ticketinfo->btickets = NO_TICKETS;
+ ticketinfo->principal = NULL;
+ ticketinfo->ccache_name = NULL;
+ ticketinfo->next = NULL;
+ ticketinfo->ticket_list = NULL;
- wsprintf(Buffer, "Session Key Type: %s", etype_string(KRBv5Credentials.keyblock.enctype));
- list->keyEncType = (char*) calloc(1, strlen(Buffer)+1);
- if (!list->keyEncType)
- {
-#ifdef USE_MESSAGE_BOX
- MessageBox(NULL, "Memory Error", "Error", MB_OK);
-#endif /* USE_MESSAGE_BOX */
- return ENOMEM;
+ code = pkrb5_cc_default(ctx, &cache);
+ if (code)
+ goto cleanup;
+ ticketinfo->ccache_name = strdup(pkrb5_cc_get_name(ctx, cache));
+ if (ticketinfo->ccache_name == NULL) {
+ code = ENOMEM;
+ goto cleanup;
}
- strcpy(list->keyEncType, Buffer);
-
- if ( KRBv5Credentials.addresses && KRBv5Credentials.addresses[0] ) {
- int n = 0;
- while ( KRBv5Credentials.addresses[n] )
- n++;
- list->addrList = calloc(1, n * sizeof(char *));
- if (!list->addrList) {
-#ifdef USE_MESSAGE_BOX
- MessageBox(NULL, "Memory Error", "Error", MB_OK);
-#endif /* USE_MESSAGE_BOX */
- return ENOMEM;
+ if (!pkrb5_cc_get_principal(ctx, cache, &me)) {
+ code = (*pkrb5_unparse_name)(ctx, me, &PrincipalName);
+ if (code)
+ goto cleanup;
+ if (PrincipalName) {
+ ticketinfo->principal = strdup(PrincipalName);
+ pkrb5_free_unparsed_name(ctx, PrincipalName);
}
- list->addrCount = n;
- for ( n=0; n<list->addrCount; n++ ) {
- wsprintf(Buffer, "Address: %s", one_addr(KRBv5Credentials.addresses[n]));
- list->addrList[n] = (char*) calloc(1, strlen(Buffer)+1);
- if (!list->addrList[n])
- {
-#ifdef USE_MESSAGE_BOX
- MessageBox(NULL, "Memory Error", "Error", MB_OK);
-#endif /* USE_MESSAGE_BOX */
- return ENOMEM;
- }
- strcpy(list->addrList[n], Buffer);
- }
- }
-
- ticketinfo->issue_date = KRBv5Credentials.times.starttime;
- ticketinfo->lifetime = KRBv5Credentials.times.endtime - KRBv5Credentials.times.starttime;
- ticketinfo->renew_till = KRBv5Credentials.ticket_flags & TKT_FLG_RENEWABLE ?
- KRBv5Credentials.times.renew_till : 0;
- _tzset();
- if ( ticketinfo->issue_date + ticketinfo->lifetime - time(0) <= 0L )
- ticketinfo->btickets = EXPD_TICKETS;
- else
- ticketinfo->btickets = GOOD_TICKETS;
-
- if (ClientName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, ClientName);
-
- if (sServerName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, sServerName);
-
- ClientName = NULL;
- sServerName = NULL;
- (*pkrb5_free_cred_contents)(ctx, &KRBv5Credentials);
- }
-
- if (PrincipalName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, PrincipalName);
-
- if (ClientName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, ClientName);
-
- if (sServerName != NULL)
- (*pkrb5_free_unparsed_name)(ctx, sServerName);
-
- if ((code == KRB5_CC_END) || (code == KRB5_CC_NOTFOUND))
- {
- if ((code = pkrb5_cc_end_seq_get(ctx, cache, &KRBv5Cursor)))
- {
- functionName = "krb5_cc_end_seq_get()";
- goto on_error;
}
-
- flags = KRB5_TC_OPENCLOSE;
-#ifdef KRB5_TC_NOTICKET
- flags |= KRB5_TC_NOTICKET;
-#endif
- if ((code = pkrb5_cc_set_flags(ctx, cache, flags)))
- {
- functionName = "krb5_cc_set_flags()";
- goto on_error;
- }
- }
- else
- {
- functionName = "krb5_cc_next_cred()";
- goto on_error;
- }
-
- if (ctx != NULL)
- {
- if (cache != NULL)
- pkrb5_cc_close(ctx, cache);
}
- return(code);
+ do_all_ccaches(*krbv5Context, &ticketinfo->next);
+ // @TEMP aggregate ticket info here?
- on_error:
- Leash_krb5_error(code, functionName, 0, &(*krbv5Context), &cache);
- return(code);
-#endif //!NO_KER5
+cleanup:
+ if (code)
+ not_an_API_LeashKRB5FreeTickets(ticketinfo);
+ if (cache)
+ pkrb5_cc_close(ctx, cache);
+ if (me)
+ pkrb5_free_principal(ctx, me);
+ return code;
}
@@ -831,13 +745,15 @@ DWORD publicIP
#else
krb5_error_code code = 0;
krb5_context ctx = 0;
- krb5_ccache cc = 0;
+ krb5_ccache cc = 0, defcache = 0;
krb5_principal me = 0;
char* name = 0;
krb5_creds my_creds;
krb5_get_init_creds_opt * options = NULL;
krb5_address ** addrs = NULL;
int i = 0, addr_count = 0;
+ int cc_new = 0;
+ const char * deftype = NULL;
if (!pkrb5_init_context)
return 0;
@@ -857,12 +773,29 @@ DWORD publicIP
code = pkrb5_get_init_creds_opt_alloc(ctx, &options);
if (code) goto cleanup;
- code = pkrb5_cc_default(ctx, &cc);
+ code = pkrb5_cc_default(ctx, &defcache);
if (code) goto cleanup;
code = pkrb5_parse_name(ctx, principal_name, &me);
if (code) goto cleanup;
+ deftype = pkrb5_cc_get_type(ctx, defcache);
+ if (me != NULL && pkrb5_cc_support_switch(ctx, deftype)) {
+ /* Use an existing cache for the specified principal if we can. */
+ code = pkrb5_cc_cache_match(ctx, me, &cc);
+ if (code != 0 && code != KRB5_CC_NOTFOUND)
+ goto cleanup;
+ if (code == KRB5_CC_NOTFOUND) {
+ code = pkrb5_cc_new_unique(ctx, deftype, NULL, &cc);
+ if (code)
+ goto cleanup;
+ cc_new = 1;
+ }
+ pkrb5_cc_close(ctx, defcache);
+ } else {
+ cc = defcache;
+ }
+
code = pkrb5_unparse_name(ctx, me, &name);
if (code) goto cleanup;
@@ -957,7 +890,24 @@ DWORD publicIP
0, // start time
0, // service name
options);
+ // @TODO: make this an option
+ if ((!code) && (cc != defcache)) {
+ code = pkrb5_cc_switch(ctx, cc);
+ if (!code) {
+ const char *cctype = pkrb5_cc_get_type(ctx, cc);
+ if (cctype != NULL) {
+ char defname[20];
+ sprintf_s(defname, sizeof(defname), "%s:", cctype);
+ pkrb5int_cc_user_set_default_name(ctx, defname);
+ }
+ }
+ }
cleanup:
+ if (code && cc_new) {
+ // don't leave newly-generated empty ccache lying around on failure
+ pkrb5_cc_destroy(ctx, cc);
+ cc = NULL;
+ }
if ( addrs ) {
for ( i=0;i<addr_count;i++ ) {
if ( addrs[i] ) {
@@ -1002,7 +952,11 @@ Leash_krb5_kdestroy(
ctx = NULL;
cache = NULL;
- if (rc = Leash_krb5_initialize(&ctx, &cache))
+ rc = Leash_krb5_initialize(&ctx);
+ if (rc)
+ return(rc);
+
+ if (rc = pkrb5_cc_default(ctx, &cache))
return(rc);
rc = pkrb5_cc_destroy(ctx, cache);
@@ -1015,56 +969,62 @@ Leash_krb5_kdestroy(
#endif //!NO_KRB5
}
+krb5_error_code
+Leash_krb5_cc_default(krb5_context *ctx, krb5_ccache *cache)
+{
+ krb5_error_code rc;
+ krb5_flags flags;
+
+ char *functionName = NULL;
+ if (*cache == 0) {
+ rc = pkrb5_cc_default(*ctx, cache);
+ if (rc) {
+ functionName = "krb5_cc_default()";
+ goto on_error;
+ }
+ }
+#ifdef KRB5_TC_NOTICKET
+ flags = KRB5_TC_NOTICKET;
+#endif
+ rc = pkrb5_cc_set_flags(*ctx, *cache, flags);
+ if (rc) {
+ if (rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) {
+ if (*cache != NULL && *ctx != NULL)
+ pkrb5_cc_close(*ctx, *cache);
+ } else {
+ functionName = "krb5_cc_set_flags()";
+ goto on_error;
+ }
+ }
+on_error:
+ if (rc && functionName) {
+ Leash_krb5_error(rc, functionName, 0, ctx, cache);
+ }
+ return rc;
+}
+
/**************************************/
/* Leash_krb5_initialize(): */
/**************************************/
-int Leash_krb5_initialize(krb5_context *ctx, krb5_ccache *cache)
+int Leash_krb5_initialize(krb5_context *ctx)
{
#ifdef NO_KRB5
return(0);
#else
LPCSTR functionName = NULL;
- int freeContextFlag = 0;
krb5_error_code rc;
- krb5_flags flags;
if (pkrb5_init_context == NULL)
return 1;
if (*ctx == 0) {
- if (rc = (*pkrb5_init_context)(ctx))
- {
- functionName = "krb5_init_context()";
- goto on_error;
- }
- freeContextFlag = 1;
- }
-
- if (*cache == 0 && (rc = pkrb5_cc_default(*ctx, cache)))
- {
- functionName = "krb5_cc_default()";
- goto on_error;
- }
-#ifdef KRB5_TC_NOTICKET
- flags = KRB5_TC_NOTICKET;
-#endif
- if ((rc = pkrb5_cc_set_flags(*ctx, *cache, flags)))
- {
- if (rc != KRB5_FCC_NOFILE && rc != KRB5_CC_NOTFOUND)
- Leash_krb5_error(rc, "krb5_cc_set_flags()", 0, ctx,
- cache);
- else if ((rc == KRB5_FCC_NOFILE || rc == KRB5_CC_NOTFOUND) && *ctx != NULL)
- {
- if (*cache != NULL)
- pkrb5_cc_close(*ctx, *cache);
+ if (rc = (*pkrb5_init_context)(ctx)) {
+ functionName = "krb5_init_context()";
+ return Leash_krb5_error(rc, functionName, 0, ctx, NULL);
}
- return rc;
}
- return 0;
-
- on_error:
- return Leash_krb5_error(rc, functionName, freeContextFlag, ctx, cache);
+ return 0;
#endif //!NO_KRB5
}
@@ -1083,36 +1043,25 @@ Leash_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName,
#ifdef USE_MESSAGE_BOX
char message[256];
const char *errText;
- int krb5Error = ((int)(rc & 255));
-
- /*
- switch (krb5Error)
- {
- // Wrong password
- case 31:
- case 8:
- return;
- }
- */
errText = perror_message(rc);
_snprintf(message, sizeof(message),
"%s\n(Kerberos error %ld)\n\n%s failed",
errText,
- krb5Error,
+ rc,
FailedFunctionName);
+ message[sizeof(message)-1] = 0;
MessageBox(NULL, message, "Kerberos Five", MB_OK | MB_ICONERROR |
MB_TASKMODAL |
MB_SETFOREGROUND);
#endif /* USE_MESSAGE_BOX */
- if (*ctx != NULL)
- {
- if (*cache != NULL) {
- pkrb5_cc_close(*ctx, *cache);
- *cache = NULL;
- }
+ if (ctx != NULL && *ctx != NULL) {
+ if (cache != NULL && *cache != NULL) {
+ pkrb5_cc_close(*ctx, *cache);
+ *cache = NULL;
+ }
if (FreeContextFlag) {
pkrb5_free_context(*ctx);
@@ -1139,7 +1088,6 @@ Leash_ms2mit(BOOL save_creds)
krb5_creds creds;
krb5_cc_cursor cursor=0;
krb5_principal princ = 0;
- char *cache_name=NULL;
BOOL rc = FALSE;
if ( !pkrb5_init_context )
diff --git a/src/windows/leashdll/leash-int.h b/src/windows/leashdll/leash-int.h
index fb7617ed34..b5c0b2738b 100644
--- a/src/windows/leashdll/leash-int.h
+++ b/src/windows/leashdll/leash-int.h
@@ -162,7 +162,9 @@ BOOL IsKerberosLogon(VOID);
int Leash_krb5_error(krb5_error_code rc, LPCSTR FailedFunctionName,
int FreeContextFlag, krb5_context *ctx,
krb5_ccache *cache);
-int Leash_krb5_initialize(krb5_context *, krb5_ccache *);
+int Leash_krb5_initialize(krb5_context *);
+krb5_error_code
+Leash_krb5_cc_default(krb5_context *ctx, krb5_ccache *cache);
#endif /* NO_KRB5 */
LPSTR err_describe(LPSTR buf, long code);
diff --git a/src/windows/leashdll/leashdll.h b/src/windows/leashdll/leashdll.h
index a045583da2..63cfe234f8 100644
--- a/src/windows/leashdll/leashdll.h
+++ b/src/windows/leashdll/leashdll.h
@@ -58,6 +58,8 @@ void FAR Leash_load_com_err_callback(FARPROC,FARPROC,FARPROC);
#endif
#include <ntsecapi.h>
+#include <krb5.h>
+
#ifndef NO_KRB4
extern HINSTANCE hKrb4;
#endif
@@ -73,19 +75,6 @@ extern HINSTANCE hProfile;
#define LEASH_PRIORITY_LOW 0
#define LEASH_PRIORITY_HIGH 1
-typedef struct TicketList
-{
- char* theTicket;
- struct TicketList* next;
- char* tktEncType;
- char* keyEncType;
- int addrCount;
- char ** addrList;
- char * name;
- char * inst;
- char * realm;
-} TicketList;
-
///////////////////////////////////////////////////////////////////////////////
#ifdef _WIN64
diff --git a/src/windows/leashdll/leashw32.def b/src/windows/leashdll/leashw32.def
index 25af0e2ea8..5df8309ae4 100644
--- a/src/windows/leashdll/leashw32.def
+++ b/src/windows/leashdll/leashw32.def
@@ -106,3 +106,4 @@ EXPORTS
not_an_API_LeashKRB4GetTickets
not_an_API_LeashGetTimeServerName
not_an_API_Leash_AcquireInitialTicketsIfNeeded
+ not_an_API_LeashKRB5FreeTickets
diff --git a/src/windows/leashdll/lshfunc.c b/src/windows/leashdll/lshfunc.c
index 1a0bf14305..614bb799eb 100644
--- a/src/windows/leashdll/lshfunc.c
+++ b/src/windows/leashdll/lshfunc.c
@@ -867,26 +867,9 @@ not_an_API_LeashFreeTicketList(TicketList** ticketList)
killList = tempList;
tempList = (TicketList*)tempList->next;
- free(killList->theTicket);
- if (killList->tktEncType)
- free(killList->tktEncType);
- if (killList->keyEncType)
- free(killList->keyEncType);
- if (killList->addrCount) {
- int n;
- for ( n=0; n<killList->addrCount; n++) {
- if (killList->addrList[n])
- free(killList->addrList[n]);
- }
- }
- if (killList->addrList)
- free(killList->addrList);
- if (killList->name)
- free(killList->name);
- if (killList->inst)
- free(killList->inst);
- if (killList->realm)
- free(killList->realm);
+ free(killList->service);
+ if (killList->encTypes)
+ free(killList->encTypes);
free(killList);
}
@@ -2873,8 +2856,7 @@ acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen)
GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
}
- not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
- not_an_API_LeashFreeTicketList(&list);
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&ctx);
if ( ticketinfo.btickets != GOOD_TICKETS &&
dwMsLsaImport && Leash_importable() ) {
@@ -2939,8 +2921,8 @@ acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen)
if ( import ) {
Leash_import();
- not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
- not_an_API_LeashFreeTicketList(&list);
+ not_an_API_LeashKRB5FreeTickets(&ticketinfo);
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&ctx);
}
}
@@ -2958,7 +2940,7 @@ acquire_tkt_no_princ(krb5_context context, char * ccname, int cclen)
strncpy(ccname, ccachename, cclen);
ccname[cclen-1] = '\0';
}
-
+ not_an_API_LeashKRB5FreeTickets(&ticketinfo);
if ( !context )
pkrb5_free_context(ctx);
}
@@ -2968,7 +2950,6 @@ static void
acquire_tkt_for_princ(krb5_context context, krb5_principal desiredPrincipal,
char * ccname, int cclen)
{
- TicketList *list = NULL;
TICKETINFO ticketinfo;
krb5_context ctx;
DWORD dwMsLsaImport = Leash_get_default_mslsa_import();
@@ -2992,8 +2973,7 @@ acquire_tkt_for_princ(krb5_context context, krb5_principal desiredPrincipal,
GetEnvironmentVariable("KRB5CCNAME", ccachename, sizeof(ccachename));
}
- not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
- not_an_API_LeashFreeTicketList(&list);
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&ctx);
pkrb5_unparse_name(ctx, desiredPrincipal, &name);
@@ -3032,14 +3012,14 @@ acquire_tkt_for_princ(krb5_context context, krb5_principal desiredPrincipal,
SetEnvironmentVariable("KRB5CCNAME", ccachename);
- not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
- not_an_API_LeashFreeTicketList(&list);
+ not_an_API_LeashKRB5FreeTickets(&ticketinfo);
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&ctx);
if (ticketinfo.btickets != GOOD_TICKETS) {
Leash_import();
- not_an_API_LeashKRB5GetTickets(&ticketinfo,&list,&ctx);
- not_an_API_LeashFreeTicketList(&list);
+ not_an_API_LeashKRB5FreeTickets(&ticketinfo);
+ not_an_API_LeashKRB5GetTickets(&ticketinfo,&ctx);
}
}
}
@@ -3059,6 +3039,7 @@ acquire_tkt_for_princ(krb5_context context, krb5_principal desiredPrincipal,
ccname[cclen-1] = '\0';
}
}
+ not_an_API_LeashKRB5FreeTickets(&ticketinfo);
if (name)
pkrb5_free_unparsed_name(ctx, name);