// service sends an encrypted response // DC forwards it to AS for password validation // after confirmation, forward to TGS public bool SendResponseService(byte[] response) { string sessionId = OperationContext.Current.SessionId; UserRequest userRequest; if (!Database.usersRequestsDB.TryGetValue(sessionId, out userRequest)) { throw new FaultException <SecurityException>(new SecurityException("Domain Controller: Session failed.")); } bool authenticated = false; using (authProxy = new AuthProxy(new NetTcpBinding(), "net.tcp://localhost:10000/AuthService")) { try { authenticated = authProxy.CheckPassword(userRequest, response); } catch (FaultException <SecurityException> ex) { Console.WriteLine(ex.Detail.Message); throw new FaultException <SecurityException>(new SecurityException(ex.Detail.Message)); } catch (Exception ex) { Console.WriteLine(ex.Message); throw new FaultException <SecurityException>(new SecurityException(ex.Message)); } } if (!authenticated) { throw new FaultException <SecurityException>(new SecurityException("Authentication Service error: Service failed to authenticate.")); } else { using (tgsProxy = new TGSProxy(new NetTcpBinding(), "net.tcp://localhost:10001/TGService")) { try { string serviceAddress = tgsProxy.GetServiceAddress(userRequest.RequestedService); Console.WriteLine($"Ticket Granting Service: Requested {userRequest.RequestedService} found. Address: {serviceAddress}."); if (tgsProxy.IsServiceOnline(userRequest.RequestedService)) { return(true); } tgsProxy.ActivateService(userRequest.RequestedService, userRequest.Username); Console.WriteLine($"Ticket Granting Service: {userRequest.RequestedService} activated by {userRequest.Username}."); Console.WriteLine($"Ticket Granting Service: Sending confirmation to {serviceAddress}..."); Console.WriteLine(); return(true); } catch (FaultException <SecurityException> ex) { Console.WriteLine(ex.Detail.Message); Console.WriteLine("----------------------------------------------------------------------------------"); throw new FaultException <SecurityException>(new SecurityException(ex.Detail.Message)); } catch (CommunicationException ex) { Console.WriteLine(ex.Message); Console.WriteLine("----------------------------------------------------------------------------------"); throw new FaultException <SecurityException>(new SecurityException(ex.Message)); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine("----------------------------------------------------------------------------------"); throw new Exception(ex.Message); } } } }
// SendResponse: gets the response and then compares it to the stored hash in the database public ClientSessionData SendResponse(byte[] response) { string sessionId = OperationContext.Current.SessionId; if (!Database.usersRequestsDB.ContainsKey(sessionId)) { throw new FaultException <SecurityException>(new SecurityException("Domain Controller: Session failed.")); } bool authenticated = false; using (authProxy = new AuthProxy(new NetTcpBinding(), "net.tcp://localhost:10000/AuthService")) { try { authenticated = authProxy.CheckPassword(Database.usersRequestsDB[sessionId], response); } catch (FaultException <SecurityException> ex) { Console.WriteLine(ex.Detail.Message); throw new FaultException <SecurityException>(new SecurityException(ex.Detail.Message)); } catch (Exception ex) { Console.WriteLine(ex.Message); throw new FaultException <SecurityException>(new SecurityException(ex.Message)); } } string serviceAddress; // full address of the service string serviceUser; // username of the service account that started the requested service string serviceName = Database.usersRequestsDB[sessionId].RequestedService; //service name if (!authenticated) { throw new FaultException <SecurityException>(new SecurityException("Authentication Service error: User failed to authenticate.")); } else { using (tgsProxy = new TGSProxy(new NetTcpBinding(), "net.tcp://localhost:10001/TGService")) { try { serviceAddress = tgsProxy.GetServiceAddress(serviceName); Console.WriteLine($"Ticket Granting Service: Requested {serviceName} found. Address: {serviceAddress}."); serviceUser = tgsProxy.GetServiceUser(serviceName); Console.WriteLine($"Ticket Granting Service: {serviceName} started by {serviceUser}."); if (!tgsProxy.IsServiceOnline(serviceName)) { throw new FaultException <SecurityException>(new SecurityException($"Ticket Granting Service: {serviceName} is offline")); } Console.WriteLine($"Ticket Granting Service: {serviceAddress} is active."); Console.WriteLine("Ticket Granting Service: Generating session key ..."); key = tgsProxy.GenerateSessionKey(); // encrypting client session key byte[] pwHash = Database.usersDB[Database.usersRequestsDB[sessionId].Username]; Database.usersRequestsDB[sessionId].SessionKey = _3DESAlgorithm.Encrypt(key, pwHash); } catch (FaultException <SecurityException> ex) { Console.WriteLine(ex.Detail.Message); throw new FaultException <SecurityException>(new SecurityException(ex.Detail.Message)); } catch (Exception ex) { Console.WriteLine(ex.Message); throw new Exception(ex.Message); } } } bool keySent = false; EndpointAddress endpointAddressService = new EndpointAddress(new Uri(serviceAddress), EndpointIdentity.CreateUpnIdentity(serviceName)); // first try to send the session key to the service // save confirmation to keySent using (serviceProxy = new ServiceProxy(new NetTcpBinding(), endpointAddressService)) { try { Console.WriteLine("Domain controller: Sending session key to the service..."); // service name and service username would have to be equal //byte[] pwHash = Database.usersDB[Database.usersRequestsDB[sessionId].RequestedService]; // encrypting service session key with the password hash of the service // service name and service username do not need to be equal byte[] pwHash = Database.usersDB[serviceUser]; string user = Database.usersRequestsDB[sessionId].Username; keySent = serviceProxy.SendSessionKey(user, _3DESAlgorithm.Encrypt(key, pwHash)); } catch (FaultException <SecurityException> ex) { Console.WriteLine(ex.Detail.Message); throw new FaultException <SecurityException>(new SecurityException(ex.Detail.Message)); } catch (CommunicationException ex) { Console.WriteLine(ex.Message); serviceProxy.Abort(); } catch (Exception ex) { Console.WriteLine(ex.Message); throw new Exception(ex.Message); } } // session key successfully sent to the service // return session key to the client if (keySent) { Console.WriteLine("Domain controller: Sending session key and service address to the client..."); Console.WriteLine("----------------------------------------------------------------------------------"); return(new ClientSessionData(Database.usersRequestsDB[sessionId].SessionKey, serviceAddress)); } else { using (tgsProxy = new TGSProxy(new NetTcpBinding(), "net.tcp://localhost:10001/TGService")) { try { Console.WriteLine($"Domain controller: Deactivating {serviceName} service..."); tgsProxy.DeactivateService(serviceName); } catch (FaultException <SecurityException> ex) { Console.WriteLine(ex.Detail.Message); throw new FaultException <SecurityException>(new SecurityException(ex.Detail.Message)); } catch (Exception ex) { Console.WriteLine(ex.Message); throw new Exception(ex.Message); } } Console.WriteLine("----------------------------------------------------------------------------------"); } throw new FaultException <SecurityException>(new SecurityException("Domain controller: Service not active.")); }