@@ -358,16 +358,25 @@ def open_file(self, fname):
358358 with open (self .fname , "rb" ) as fd :
359359 self .ccache = CCache (fd .read ())
360360
361- def save (self , fname = None ):
361+ def save (self , fname = None , i = None ):
362362 """
363363 Save opened CCache file
364+
365+ :param fname: if provided, save to a specific file.
366+ :param i: if provided, only save the ticket n°i.
364367 """
365368 if fname :
366369 self .fname = fname
367370 if not self .fname :
368371 raise ValueError ("No file opened. Specify the 'fname' argument !" )
372+ if i is not None :
373+ ccache = self .ccache .copy ()
374+ ccache .credentials = [ccache .credentials [i ]]
375+ data = bytes (ccache )
376+ else :
377+ data = bytes (self .ccache )
369378 with open (self .fname , "wb" ) as fd :
370- return fd .write (bytes ( self . ccache ) )
379+ return fd .write (data )
371380
372381 def show (self , utc = False ):
373382 """
@@ -502,6 +511,14 @@ def update_ticket(self, i, decTkt, resign=False, hash=None, kdc_hash=None):
502511 decTkt ,
503512 )
504513
514+ def remove_krb (self , i ):
515+ """
516+ Remove a ticket from the store.
517+
518+ :param i: the ticket to remove.
519+ """
520+ del self .ccache .credentials [i ]
521+
505522 def import_krb (self , res , key = None , hash = None , _inplace = None ):
506523 """
507524 Import the result of krb_[tgs/as]_req or a Ticket into the CCache.
@@ -2151,12 +2168,20 @@ def request_st(
21512168 additional_tickets = [],
21522169 fast = False ,
21532170 armor_with = None ,
2171+ for_user = None ,
2172+ s4u2proxy = None ,
21542173 ** kwargs ,
21552174 ):
21562175 """
2157- Request a Kerberos TS and add it to the local CCache using another ticket
2176+ Request a Kerberos TS and add it to the local CCache using another ticket.
21582177
2159- :param i: the ticket/sessionkey to use in the TGS request
2178+ :param i: the index of the ticket/sessionkey to use in the TGS request.
2179+ :param spn: the SPN to request a ticket for.
2180+ :param armor_with: the index of the ticket/sessionkey to armor this request.
2181+ :param s4u2proxy: if an index, the index of the additional ticket to send along
2182+ a S4U2PROXY request. If True, it will use additional_tickets
2183+ as usual.
2184+ :param for_user: if provided, requests S4U2SELF for that user.
21602185
21612186 See :func:`~scapy.layers.kerberos.krb_tgs_req` for the the other parameters.
21622187 """
@@ -2170,6 +2195,11 @@ def request_st(
21702195 armor_with
21712196 )
21722197
2198+ # If `s4u2proxy` is an index, get the ticket to armor with
2199+ if isinstance (s4u2proxy , int ):
2200+ additional_tickets .append (self .export_krb (s4u2proxy )[0 ])
2201+ s4u2proxy = True
2202+
21732203 res = krb_tgs_req (
21742204 upn ,
21752205 spn ,
@@ -2180,6 +2210,7 @@ def request_st(
21802210 realm = realm ,
21812211 additional_tickets = additional_tickets ,
21822212 fast = fast ,
2213+ for_user = for_user ,
21832214 armor_ticket = armor_ticket ,
21842215 armor_ticket_upn = armor_ticket_upn ,
21852216 armor_ticket_skey = armor_ticket_skey ,
@@ -2190,7 +2221,7 @@ def request_st(
21902221
21912222 self .import_krb (res )
21922223
2193- def kpasswdset (self , i , targetupn = None ):
2224+ def kpasswdset (self , i , targetupn = None , newpassword = None ):
21942225 """
21952226 Use kpasswd in 'Set Password' mode to set the password of an account.
21962227
@@ -2203,6 +2234,7 @@ def kpasswdset(self, i, targetupn=None):
22032234 setpassword = True ,
22042235 ticket = ticket ,
22052236 key = sessionkey ,
2237+ newpassword = newpassword ,
22062238 )
22072239
22082240 def renew (self , i , ip = None , additional_tickets = [], ** kwargs ):
0 commit comments