def app_auth(self, svc_ip, svc_port): """Authenticates to a requested application""" saddr = (svc_ip, svc_port) if not self.stkt or not self.ssession: raise KrbException("Service session key or ticket are blank, run request_svc_tkt") auth = Authenticator(user_id=self.name_realm) auth.send(self.sock, self.ssession.session_key, saddr) self.sock.sendto(self.stkt, saddr) authblob = self.recv(saddr) self.svcauth = Authenticator(blob=decrypt_data(authblob[1], self.ssession.session_key))
def datagramReceived(self, data, addr): """Handle a received datagram""" print("Connection from {}".format(addr[0])) sock = self.transport.socket # get the data type and keep track of clients dtype = unpack("!b", data[0])[0] if not addr[0] in self.clients.keys(): self.clients[addr[0]] = dict() # client authenticator received if dtype == CLI_AUTH: print("Got client auth") self.clients[addr[0]]["CLI_AUTH_BLOB"] = data[1:] # Encrypted service ticket received elif dtype == SVC_TKT_RESP: try: stkt = ServiceTicket( blob=decrypt_data(data[1:], self.secret_key)) except: KrbError("Cannot decrypt service ticket").send(sock, addr) return try: cliauth = Authenticator(blob=decrypt_data( self.clients[addr[0]]["CLI_AUTH_BLOB"], stkt.session_key)) except: KrbError("Cannot decrypt client authenticator").send( sock, addr) return if cliauth.user_id != stkt.client_id: KrbError( "Client authenticator user id does not match service ticket id" ).send(sock, addr) elif stkt.net_addr != '0.0.0.0' and stkt.net_addr != addr[0]: KrbError( "Network addresses of the client and the service ticket do not match" ).send(sock, addr) else: svcauth = Authenticator(user_id=self.name_realm) print("Sending svcauth") svcauth.send(sock, stkt.session_key, addr) self.clients[addr[0]]["AUTHENTICATED"] = True print("Client " + addr[0] + " authenticated successfully") # unknown type else: KrbError("Unknown or incorrect protocol").send(sock, addr)
def request_svc_tkt(self, svc_name, svc_realm): """Communicates with the TGS to get the service ticket and the service session key""" if not self.ksession or not self.tgt: raise KrbException("TGS Session key or TGT are blank, run kinit") self.sock.sendto(self.tgt, self.auth_addr) auth = Authenticator(user_id=self.name_realm) auth.send(self.sock, self.ksession.session_key, self.auth_addr) req = ServiceTicketRequest(svc_id='@'.join([svc_name, svc_realm])) req.send(self.sock, self.auth_addr) data = [] data.append(self.recv(self.auth_addr)) data.append(self.recv(self.auth_addr)) for i in data: if i[0] == SVC_SESS_KEY: self.ssession = ServiceSessionKey(blob=decrypt_data(i[1], self.ksession.session_key)) if i[0] == SVC_TKT_RESP: self.stkt = pack("!b", SVC_TKT_RESP) + i[1]
def datagramReceived(self, data, addr): """Handle a received datagram""" print("Connection from {}".format(addr[0])) sock = self.transport.socket # get the data type and keep track of clients dtype = unpack("!b", data[0])[0] if not addr[0] in self.clients.keys(): self.clients[addr[0]] = dict() # client authenticator received if dtype == CLI_AUTH: print("Got client auth") self.clients[addr[0]]["CLI_AUTH_BLOB"] = data[1:] # Encrypted service ticket received elif dtype == SVC_TKT_RESP: try: stkt = ServiceTicket(blob=decrypt_data(data[1:], self.secret_key)) except: KrbError("Cannot decrypt service ticket").send(sock, addr) return try: cliauth = Authenticator(blob=decrypt_data(self.clients[addr[0]]["CLI_AUTH_BLOB"], stkt.session_key)) except: KrbError("Cannot decrypt client authenticator").send(sock, addr) return if cliauth.user_id != stkt.client_id: KrbError("Client authenticator user id does not match service ticket id").send(sock, addr) elif stkt.net_addr != '0.0.0.0' and stkt.net_addr != addr[0]: KrbError("Network addresses of the client and the service ticket do not match").send(sock, addr) else: svcauth = Authenticator(user_id=self.name_realm) print("Sending svcauth") svcauth.send(sock, stkt.session_key, addr) self.clients[addr[0]]["AUTHENTICATED"] = True print("Client "+addr[0]+" authenticated successfully") # unknown type else: KrbError("Unknown or incorrect protocol").send(sock, addr)
def datagramReceived(self, data, addr): """Receives a datagram from the reactor and decides what to do with it""" print("Connection from {}".format(addr[0])) sock = self.transport.socket # Get data type and maintain clients dict dtype = unpack("!b", data[0])[0] if not addr[0] in self.clients.keys(): self.clients[addr[0]] = dict() # Ticket Granting Ticket Request packet received if dtype == TGT_REQ: print("Got tgt req") try: tgtreq = TGTRequest(blob=data[1:]) except: KrbError("Malformed TGT Request").send(sock, addr) self.clients[addr[0]]["TGT_REQ"] = tgtreq try: # lookup the client in the KDC database name, realm = tgtreq.user_id.split("@") client = self.session.query(KDC).filter_by(name=name, realm=realm).one() except: KrbError("Client is not in the KDC database or name is invalid").send(sock, addr) return # create and send the TGS session key and TGT to the client skey = TGSSessionKey(tgs_id=self.tgs.name, valid_until=tgtreq.req_validity) tgt = TGT(client_id=client.name_realm, tgs_id=self.tgs.name, net_addr=tgtreq.net_addr, valid_until=tgtreq.req_validity, session_key=skey.session_key) skey.send(sock, client.secret_key_raw, addr) tgt.send(sock, self.tgs.secret_key_raw, addr) # Client Authenticator packet received, store it for later elif dtype == CLI_AUTH: print("Got cli_auth") self.clients[addr[0]]["CLI_AUTH_BLOB"] = data[1:] # Service ticket request received elif dtype == SVC_TKT_REQ: print("Got svc tkt req") try: # Decrypt the authenticator that was received previously auth = Authenticator(blob=decrypt_data(self.clients[addr[0]]["CLI_AUTH_BLOB"], self.clients[addr[0]]["TGT"].session_key)) except: KrbError("Cannot decrypt client authenticator").send(sock, addr) return # do some checks if self.clients[addr[0]]["TGT"].client_id != auth.user_id: KrbError("Authenticator user ID does not match user id in the TGT").send(sock, addr) elif (self.clients[addr[0]]["TGT_REQ"].net_addr != '0.0.0.0' and self.clients[addr[0]]["TGT"].net_addr != addr[0]): KrbError("Network addresses of the client and the TGT do not match").send(sock, addr) else: # checks passed, parse service ticket request from client svctktreq = ServiceTicketRequest(blob=data[1:]) svcname, svcrealm = svctktreq.svc_id.split("@") try: # look up the service in the KDC database svc = self.session.query(KDC).filter_by(name=svcname, realm=svcrealm).one() except: KrbError("The requested service does not exist in the database").send(sock, addr) # create and send the service ticket and service session key to the client svctkt = ServiceTicket(client_id=self.clients[addr[0]]["TGT"].client_id, svc_id=svc.name_realm, net_addr=self.clients[addr[0]]["TGT"].net_addr, valid_until=self.clients[addr[0]]["TGT"].valid_until) svc_sess_key = ServiceSessionKey(svc_id=svc.name_realm, session_key=svctkt.session_key, valid_until=self.clients[addr[0]]["TGT"].valid_until) svctkt.send(sock, svc.secret_key_raw, addr) svc_sess_key.send(sock, self.clients[addr[0]]["TGT"].session_key, addr) # TGT received from client elif dtype == TGT_RESP: print("Got tgt resp") try: self.clients[addr[0]]["TGT"] = TGT(blob=decrypt_data(data[1:], self.tgs.secret_key_raw)) except: KrbError("Cannot decrypt received TGT").send(sock, addr) # Unknown packet type received else: print("Unknown packet type: " + str(dtype)) KrbError("Unknown packet type").send(sock, addr)