krb5: fcc_next_cred do not return removed creds
commit a9bd3c6e50 ("Fix racy file ccache
corruption in cred_delete()") implemented krb5_cc_remove_cred() for
"FILE" ccaches by overwriting the removed credential endtime value
with zero (Unix Epoch).  However, it did not modify fcc_get_next()
to filter out these deleted entries.  As a result, invalid credentials
can be returned from the FILE ccache where endtime < starttime.
RFC4120 requires endtime >= starttime for all tickets.
MIT Kerberos since d3b39a8bac6206b5ea78b0bf6a2958c1df0b0dd5
("Implement krb5_cc_remove_cred for remaining types") modifies a
removed cred by setting
  endtime = 0
  authtime = -1
and then filters out removed creds from the fcc_next_cred() results.
In 2013 Heimdal broke interop with MIT processes that share the
FILE ccache by implementing remove by setting "endtime = 0" and
now MIT has broken interop with the Heimdal implementation of
fcc_remove_cred() by checking for both "endtime = 0" and "authtime = -1".
This change filters results from fcc_get_next() when the "endtime == 0"
which is acceptable because a KDC is not permitted to return a
ticket with an endtime == 0.
			
			
This commit is contained in:
		@@ -997,15 +997,25 @@ fcc_get_next (krb5_context context,
 | 
				
			|||||||
    if (FCC_CURSOR(*cursor) == NULL)
 | 
					    if (FCC_CURSOR(*cursor) == NULL)
 | 
				
			||||||
        return krb5_einval(context, 3);
 | 
					        return krb5_einval(context, 3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    FCC_CURSOR(*cursor)->cred_start =
 | 
					    while (1) {
 | 
				
			||||||
        krb5_storage_seek(FCC_CURSOR(*cursor)->sp, 0, SEEK_CUR);
 | 
						FCC_CURSOR(*cursor)->cred_start =
 | 
				
			||||||
 | 
						    krb5_storage_seek(FCC_CURSOR(*cursor)->sp, 0, SEEK_CUR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret = krb5_ret_creds(FCC_CURSOR(*cursor)->sp, creds);
 | 
						ret = krb5_ret_creds(FCC_CURSOR(*cursor)->sp, creds);
 | 
				
			||||||
    if (ret)
 | 
					 | 
				
			||||||
	krb5_clear_error_message(context);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    FCC_CURSOR(*cursor)->cred_end =
 | 
						FCC_CURSOR(*cursor)->cred_end =
 | 
				
			||||||
        krb5_storage_seek(FCC_CURSOR(*cursor)->sp, 0, SEEK_CUR);
 | 
						    krb5_storage_seek(FCC_CURSOR(*cursor)->sp, 0, SEEK_CUR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret) {
 | 
				
			||||||
 | 
						    krb5_clear_error_message(context);
 | 
				
			||||||
 | 
						    break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (creds->times.endtime != 0)
 | 
				
			||||||
 | 
						    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						krb5_free_cred_contents(context, creds);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user