private async Task HandleAsync(byte[] bytes, Stream stream, DecisionEngine engine) { Gatekeeper.LdapPacketParserLibrary.Parser parser = new Gatekeeper.LdapPacketParserLibrary.Parser(); LdapPacketParserLibrary.Models.LdapMessage message = parser.TryParsePacket(bytes); List <LdapMessage> replies = await engine.GenerateReply(message); foreach (LdapMessage outMsg in replies) { if (outMsg.ProtocolOp.GetType() == typeof(Gatekeeper.LdapServerLibrary.Models.Operations.Response.UnbindDummyResponse)) { _clientIsConnected = false; break; } byte[] msg = (new Parser.PacketParser()).TryEncodePacket(outMsg); stream.Write(msg, 0, msg.Length); if (outMsg.ProtocolOp.GetType() == typeof(Gatekeeper.LdapServerLibrary.Models.Operations.Response.ExtendedOperationResponse)) { var response = ((Gatekeeper.LdapServerLibrary.Models.Operations.Response.ExtendedOperationResponse)outMsg.ProtocolOp); if (response.ResponseName == ExtendedRequestHandler.StartTLS) { _useStartTls = true; } } } }
internal async Task <List <LdapMessage> > GenerateReply(LdapPacketParserLibrary.Models.LdapMessage message) { // Authentication check List <Type> publicOperations = new List <Type> { typeof(BindRequest), typeof(UnbindRequest), typeof(ExtendedRequest), }; if (!_clientContext.IsAuthenticated && !publicOperations.Contains(message.ProtocolOp.GetType())) { return(new List <LdapMessage>() { new LdapMessage(message.MessageId, new BindResponse(new LdapResult(LdapResult.ResultCodeEnum.InappropriateAuthentication, null, null))) }); } LdapEvents eventListener = SingletonContainer.GetLdapEventListener(); Type protocolType = message.ProtocolOp.GetType(); Type handlerType = SingletonContainer.GetHandlerMapper().GetHandlerForType(protocolType); var parameters = new object[] { _clientContext, eventListener, message.ProtocolOp }; object?invokableClass = FormatterServices.GetUninitializedObject(handlerType); if (invokableClass != null) { MethodInfo?method = handlerType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance).Single(x => x.Name.EndsWith("Handle")); if (method != null) { Task resultTask = (Task)method.Invoke(invokableClass, parameters); await resultTask; PropertyInfo?propertInfo = resultTask.GetType().GetProperty("Result"); object result = propertInfo.GetValue(resultTask); if (result != null) { List <LdapMessage> messages = new List <LdapMessage>(); HandlerReply handlerReply = (HandlerReply)result; foreach (IProtocolOp op in handlerReply._protocolOps) { messages.Add(new LdapMessage(message.MessageId, op)); } return(messages); } } } throw new System.Exception(); }
public override async Task <SearchReply> ExecuteSearchRequest(SearchRequest request, ServerCallContext context) { if (!RequestIsFromLoopback(context)) { throw new Exception("Request is not from loopback"); } List <string> cns = request.UserIdentity.Cn.ToList(); List <string> ous = request.UserIdentity.Ou.ToList(); if (cns[0] != "BindUser" && ous.Count != 0) { throw new Exception("Search by Non-BindUser"); } SearchReply reply = new SearchReply { }; Guid appId = new Guid(request.UserIdentity.Dc[0]); LdapPacketParserLibrary.Parser parser = new LdapPacketParserLibrary.Parser(); LdapPacketParserLibrary.Models.LdapMessage message = parser.TryParsePacket(request.RawPacket.ToByteArray()); if (message.ProtocolOp.GetType() == typeof(LdapPacketParserLibrary.Models.Operations.Request.SearchRequest)) { LdapPacketParserLibrary.Models.Operations.Request.SearchRequest searchRequest = (LdapPacketParserLibrary.Models.Operations.Request.SearchRequest)message.ProtocolOp; int?limit = searchRequest.SizeLimit; var itemExpression = Expression.Parameter(typeof(AppUser)); SearchExpressionBuilder searchExpressionBuilder = new SearchExpressionBuilder(); var conditions = searchExpressionBuilder.Build(searchRequest.Filter, itemExpression); var queryLambda = Expression.Lambda <Func <AppUser, bool> >(conditions, itemExpression); var predicate = queryLambda.Compile(); List <AppUser> results = await _authDbContext.Users .AsNoTracking() .Include(u => u.Groups) .ThenInclude(g => g.AuthApps) .Where(queryLambda) .Where(u => u.Groups.Any(g => g.AuthApps.Any(a => a.Id == appId))) .AsSplitQuery() .ToListAsync(); SearchReply.Types.ResultEntry entry = new SearchReply.Types.ResultEntry { }; foreach (AppUser user in results) { entry.Rdn = "cn=" + user.Id.ToString() + ",ou=People,dc=" + appId; SearchReply.Types.ResultEntry.Types.ResultAttribute displayNameAttribute = new SearchReply.Types.ResultEntry.Types.ResultAttribute { Name = "displayname", }; displayNameAttribute.Value.Add(user.UserName); SearchReply.Types.ResultEntry.Types.ResultAttribute emailAttribute = new SearchReply.Types.ResultEntry.Types.ResultAttribute { Name = "email", }; emailAttribute.Value.Add(user.Email); SearchReply.Types.ResultEntry.Types.ResultAttribute objectClassAttribute = new SearchReply.Types.ResultEntry.Types.ResultAttribute { Name = "objectclass", }; objectClassAttribute.Value.Add("inetOrgPerson"); SearchReply.Types.ResultEntry.Types.ResultAttribute entryUuidAttribute = new SearchReply.Types.ResultEntry.Types.ResultAttribute { Name = "entryUuid", }; entryUuidAttribute.Value.Add(user.Id.ToString()); entry.Attributes.AddRange(new List <SearchReply.Types.ResultEntry.Types.ResultAttribute>() { displayNameAttribute, emailAttribute, objectClassAttribute, entryUuidAttribute }); reply.Results.Add(entry); } } return(reply); }