コード例 #1
0
        /// <summary>
        /// Resolves X509 certificates for a specific subject.  May either be an address or a domain name.
        /// </summary>
        /// <param name="srvRecord">Resolve <see cref="SRVRecord"/> to resolve. </param>
        /// /// <param name="subjectName">The <see cref="String"/> subject to resolve. </param>
        /// <returns>An <see cref="X509Certificate2Collection"/> of X509 certifiates for the address,
        /// or <c>null</c> if no certificates are found.</returns>
        X509Certificate2Collection GetCertificatesBySubect(SRVRecord srvRecord, string subjectName)
        {
            var retVal = new X509Certificate2Collection();

            // get the LDAP connection from the SRV records

            using (var connection = GetLdapConnection(srvRecord))
            {
                if (connection != null)
                {
                    // gate the base naming contexts
                    var distNames = GetBaseNamingContext(connection);

                    foreach (var dn in distNames)
                    {
                        // search each base context
                        var request = Search.MimeCertRequest(dn, subjectName);
                        try
                        {
                            SetCerts(connection, request, retVal);
                        }
                        catch (LdapCertResolverException ldapEx)
                        {
                            this.Error.NotifyEvent(this, new LdapCertResolverException(ldapEx.Error, subjectName + srvRecord, ldapEx.InnerException));
                        }
                        catch (Exception ex)
                        {
                            this.Error.NotifyEvent(this, ex);
                        }
                    }
                }
            }
            return(retVal);
        }
コード例 #2
0
        /// <summary>
        /// Creates a connection to an LDAP server based on the DNS SRV resolution of the lookup name.
        /// </summary>
        /// <param name="srvRecord">Resolver <see cref="SRVRecord"/></param>
        /// <returns>An <see cref="LdapConnection"/> to the server that will be searched for certificates.</returns>
        protected LdapConnection GetLdapConnection(SRVRecord srvRecord)
        {
            LdapConnection retVal;

            var ldapIdentifier = new LdapDirectoryIdentifier(srvRecord.Target, srvRecord.Port);

            try
            {
                retVal          = new LdapConnection(ldapIdentifier);
                retVal.AuthType = AuthType.Anonymous; // use anonymous bind
                retVal.SessionOptions.ProtocolVersion = LdapProtoVersion;

                if (Timeout.Ticks > 0)
                {
                    retVal.Timeout = Timeout;
                }
                retVal.Bind();
            }
            catch (Exception ex)
            {
                // didn't connenct.... go onto the next record
                this.Error.NotifyEvent(this, new LdapCertResolverException(LDAPError.BindFailure, srvRecord.ToString(), ex));
                retVal = null;
            }
            return(retVal);
        }
コード例 #3
0
ファイル: Address.cs プロジェクト: FilRip/IMDEV.Commun
        /// <summary>
        /// Look up a DNS SRV record, returning the best host and port number to connect to.
        /// </summary>
        /// <param name="prefix">The SRV prefix, ending with a dot.  Example: "_xmpp-client._tcp."</param>
        /// <param name="domain">The domain to check</param>
        /// <param name="host">The host name to connect to</param>
        /// <param name="port">The port number to connect to</param>
        public static void LookupSRV(string prefix, string domain, ref string host, ref int port)
        {
            if (prefix == null)
            {
                throw new ArgumentNullException("prefix");
            }
            if (domain == null)
            {
                throw new ArgumentNullException("domain");
            }
            if (!prefix.EndsWith("."))
            {
                throw new ArgumentOutOfRangeException("Prefix must end in '.'", "prefix");
            }
            try
            {
                DnsRequest  request  = new DnsRequest(prefix + domain);
                DnsResponse response = request.GetResponse(DnsRecordType.SRV);

                SRVRecord record = PickSRV(response.SRVRecords);
                host = record.NameNext;
                port = record.Port;
                Debug.WriteLine(string.Format("SRV found: {0}:{1}", host, port));
            }
            catch
            {
                host = domain;
            }
        }
コード例 #4
0
ファイル: ResourceRecord.cs プロジェクト: dutysok/Sightstone
        // private, constructor initialised fields

        /// <summary>
        ///     Construct a resource record from a pointer to a byte array
        /// </summary>
        /// <param name="pointer">the position in the byte array of the record</param>
        internal ResourceRecord(Pointer pointer)
        {
            // extract the domain, question type, question class and Ttl
            Domain = pointer.ReadDomain();
            Type   = (DnsType)pointer.ReadShort();
            Class  = (DnsClass)pointer.ReadShort();
            Ttl    = pointer.ReadInt();

            // the next short is the record length, we only use it for unrecognised record types
            int recordLength = pointer.ReadShort();

            // and create the appropriate RDATA record based on the dnsType
            switch (Type)
            {
            case DnsType.SRV:
                Record = new SRVRecord(pointer);
                break;

            default:
            {
                // move the pointer over this unrecognised record
                pointer.Position += recordLength;
                break;
            }
            }
        }
コード例 #5
0
        /// <summary>
        /// Look up a DNS SRV record, returning the best host and port number to connect to.
        /// </summary>
        /// <param name="prefix">The SRV prefix, ending with a dot.  Example: "_xmpp-client._tcp."</param>
        /// <param name="domain">The domain to check</param>
        /// <param name="host">The host name to connect to</param>
        /// <param name="port">The port number to connect to</param>
        public static void LookupSRV(string prefix, string domain, ref string host, ref int port)
        {
            if (prefix == null)
            {
                throw new ArgumentNullException("prefix");
            }
            if (domain == null)
            {
                throw new ArgumentNullException("domain");
            }
            if (!prefix.EndsWith("."))
            {
                throw new ArgumentOutOfRangeException("Prefix must end in '.'", "prefix");
            }
            try
            {
                IList <SRVRecord> srvRecords = DnsServiceFactory.Create().GetSrvRecords(prefix + domain);

                SRVRecord record = PickSRV(srvRecords.ToArray());
                host = record.NameNext;
                port = record.Port;
                Debug.WriteLine(string.Format("SRV found: {0}:{1}", host, port));
            }
            catch
            {
                host = domain;
            }
        }
コード例 #6
0
        private void AnswerReceived(Message message)
        {
            List <PTRRecord> answers = message.Answers.Where(a => a.Name == AtemDeviceInfo.ServiceName).OfType <PTRRecord>().ToList();
            PTRRecord        answer  = answers.FirstOrDefault();

            if (answer == null)
            {
                return;
            }

            if (_debug && answers.Count != 1)
            {
                Console.WriteLine("Too many answers!");
            }

            List <ResourceRecord> records = message.AdditionalRecords;
            SRVRecord             srvRec  = records.OfType <SRVRecord>().FirstOrDefault(r => r.Type == DnsType.SRV && r.Name == answer.DomainName);

            if (srvRec == null)
            {
                if (_debug)
                {
                    Console.WriteLine("Missing SRV record for " + answer.DomainName);
                }
                return;
            }

            AddressRecord aRec = records.OfType <AddressRecord>().FirstOrDefault(r => r.Type == DnsType.A && r.Name == srvRec.Target);

            if (aRec == null)
            {
                if (_debug)
                {
                    Console.WriteLine("Missing A record for " + answer.DomainName);
                }
                return;
            }

            TXTRecord     txtRec  = records.OfType <TXTRecord>().FirstOrDefault(r => r.Type == DnsType.TXT && r.Name == answer.DomainName);
            List <string> strings = txtRec == null ? new List <string>() : txtRec.Strings;

            string name = string.Join(".", answer.DomainName.Labels);

            if (name.EndsWith(AtemDeviceInfo.ServiceName))
            {
                name = name.Substring(0, name.Length - AtemDeviceInfo.ServiceName.Length - 1);
            }

            var dev = new AtemDeviceInfo(name, srvRec.Target.ToString(), DateTime.Now, aRec.Address.ToString(), srvRec.Port, strings);

            lock (_knownDevices) {
                _knownDevices[dev.DeviceId] = dev;
            }

            OnDeviceSeen?.Invoke(this, dev);
        }
コード例 #7
0
ファイル: Address.cs プロジェクト: krbysn/jabber-net
        private static SRVRecord PickSRV(SRVRecord[] srv)
        {
            // TODO: keep track of connection failures, and try the next priority down.

            if ((srv == null) || (srv.Length == 0))
                throw new ArgumentException();
            if (srv.Length == 1)
                return srv[0];

            // randomize order.  One might wish that the OS would have done this for us.
            // cf. Bob Schriter's Grandfather.
            Random rnd = new Random();
            byte[] keys = new byte[srv.Length];
            rnd.NextBytes(keys);
            Array.Sort(keys, srv);  // Permute me, Knuth!  (I wish I had a good anagram for that)

            int minpri = int.MaxValue;
            foreach (SRVRecord rec in srv)
            {
                if (rec.Priority < minpri)
                {
                    minpri = rec.Priority;
                }
            }

            int weight = 0;
            foreach (SRVRecord rec in srv)
            {
                if (rec.Priority == minpri)
                {
                    weight += rec.Weight;
                }
            }

            int pos = rnd.Next(weight);
            weight = 0;
            foreach (SRVRecord rec in srv)
            {
                if (rec.Priority == minpri)
                {
                    weight += rec.Weight;
                    if ((pos < weight) || (weight == 0))
                    {
                        return rec;
                    }
                }
            }

            throw new DnsException("No matching SRV");
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: zakharov-94/net-mdns
 private void ParseRecords(List <ResourceRecord> records)
 {
     foreach (ResourceRecord record in records)
     {
         if (record is SRVRecord)
         {
             if (!((SRVRecord)record).Name.ToString().Contains("_" + this.tag))
             {
                 continue;
             }
             this.srvRec = (SRVRecord)record;
             this.ForMe  = true;
         }
     }
 }
コード例 #9
0
ファイル: LdapCertResolver.cs プロジェクト: blinds52/nhind
        private void SetCerts(SRVRecord srvRecord, LdapConnection connection, List <string> distNames, string subject, X509Certificate2Collection retVal)
        {
            foreach (var dn in distNames)
            {
                // search each base context

                try
                {
                    var request = Search.MimeCertRequest(dn, subject);
                    SetCerts(connection, request, retVal, srvRecord, subject);
                }
                catch (Exception ex)
                {
                    Error.NotifyEvent(this, ex);
                }
            }
        }
コード例 #10
0
        public DnsRecord ParseSRV(string[] args)
        {
            string domainName = args.GetRequiredValue(0);
            ushort weight     = args.GetRequiredValue <ushort>(1);
            ushort port       = args.GetRequiredValue <ushort>(2);
            string target     = args.GetRequiredValue(3); //target
            ushort priority   = args.GetOptionalValue <ushort>(4, 0);
            int    ttl        = this.ValidateTTL(args.GetOptionalValue <int>(5, 0));
            string notes      = args.GetOptionalValue(6, string.Empty);

            SRVRecord srvRecord = new SRVRecord(domainName, weight, port, target, priority)
            {
                TTL = ttl
            };
            DnsRecord dnsRecord = new DnsRecord(domainName, DnsStandard.RecordType.SRV, srvRecord.Serialize(), notes);

            return(dnsRecord);
        }
コード例 #11
0
ファイル: Program.cs プロジェクト: blubbfish/dns-sd-tester
        private String ParseDNSAnswer(Dictionary <DnsType, ResourceRecord> answer)
        {
            Console.WriteLine("Parse the DNS Answer");
            if ((answer.ContainsKey(DnsType.A) || answer.ContainsKey(DnsType.AAAA)) && answer.ContainsKey(DnsType.SRV) && answer.ContainsKey(DnsType.TXT))
            {
                TXTRecord txt_item = answer[DnsType.TXT] as TXTRecord;
                Dictionary <String, String> text_dic = new Dictionary <String, String>();
                foreach (String item in txt_item.Strings)
                {
                    String[] item_split = item.Split("=");
                    text_dic.Add(item_split[0], item_split[1]);
                }
                if (text_dic.ContainsKey("td"))
                {
                    Console.WriteLine($"{txt_item.Type}: " + $"'{txt_item.Name}' {String.Join(" ", txt_item.Strings.ToArray())}");

                    Boolean using_a = false;
                    if (answer.ContainsKey(DnsType.A))
                    {
                        using_a = true;
                    }

                    AddressRecord aa_item;
                    if (using_a)
                    {
                        aa_item = answer[DnsType.A] as AddressRecord;
                        Console.WriteLine($"{aa_item.Type}: " + $"host '{aa_item.Name}' at '{aa_item.Address}'");
                    }
                    else
                    {
                        aa_item = answer[DnsType.AAAA] as AddressRecord;
                        Console.WriteLine($"{aa_item.Type}: " + $"host '{aa_item.Name}' at '{aa_item.Address}'");
                    }

                    SRVRecord srv_item = answer[DnsType.SRV] as SRVRecord;
                    Console.WriteLine($"{srv_item.Type}: " + $"service '{srv_item.Name}' on '{srv_item.Target}' at '{srv_item.Port}'");

                    String ret = $"http://{aa_item.Address}:{srv_item.Port}{text_dic["td"]}";
                    Console.WriteLine($"Combine Answer to {ret}\n");
                    return(ret);
                }
            }
            return("");
        }
コード例 #12
0
        private NetService ProcessSRVRecord(SRVRecord record)
        {
            string serviceInstanceName = record.Name;

            if (_discoveredServices.ContainsKey(serviceInstanceName))
            {
                NetService service = _discoveredServices[serviceInstanceName];
                service.Hostname = record.Target;
                service.Port     = record.Port;
                service.IPAddresses.Clear();
                if (_discoveredIPs.ContainsKey(service.Hostname))
                {
                    service.IPAddresses.AddRange(_discoveredIPs[service.Hostname]);
                }
                return(service);
            }

            return(null);
        }
コード例 #13
0
ファイル: LdapCertResolver.cs プロジェクト: blinds52/nhind
        /// <summary>
        /// Resolves X509 certificates for a specific subject.  By domain name.
        /// </summary>
        /// <param name="connection">Active LDAP connection</param>
        /// <param name="srvRecord">Resolve <see cref="SRVRecord"/> to resolve. </param>
        /// /// <param name="domain">The <see cref="String"/> domain to resolve. </param>
        /// <returns>An <see cref="X509Certificate2Collection"/> of X509 certifiates for the address,
        /// or <c>null</c> if no certificates are found.</returns>
        X509Certificate2Collection GetCertificatesByDomain(LdapConnection connection, SRVRecord srvRecord, string domain)
        {
            var retVal = new X509Certificate2Collection();

            // gate the base naming contexts
            var distNames = GetBaseNamingContext(connection);

            SetCerts(srvRecord, connection, distNames, domain, retVal);

            return(retVal);
        }
コード例 #14
0
ファイル: NetService.cs プロジェクト: misenhower/WPRemote
        private Message GetPublishMessage(PublishMessageType type)
        {
            Message        message = new Message();
            ResourceRecord record;

            // This message is a response
            message.QueryResponse = true;
            // This is an authoritative response
            message.AuthoritativeAnswer = true;

            // SRV Record
            record = new SRVRecord()
            {
                TimeToLive = (type == PublishMessageType.Stop) ? TimeSpan.Zero : BroadcastTTL,
                CacheFlush = true,
                Name       = FullServiceInstanceName,
                Target     = Hostname,
                Port       = Port,
            };
            message.AnswerRecords.Add(record);

            // TXT Record
            if (TXTRecordData != null && TXTRecordData.Count > 0)
            {
                record = new TXTRecord()
                {
                    TimeToLive = (type == PublishMessageType.Stop) ? TimeSpan.Zero : BroadcastTTL,
                    CacheFlush = true,
                    Name       = FullServiceInstanceName,
                    Data       = TXTRecordData,
                };
                message.AnswerRecords.Add(record);
            }

            // PTR Record for DNS-SD Service Type Enumeration
            if (type == PublishMessageType.Normal)
            {
                record = new PTRRecord()
                {
                    TimeToLive = BroadcastTTL,
                    Name       = BonjourUtility.DNSSDServiceTypeEnumerationName,
                    DomainName = Type,
                };
                message.AnswerRecords.Add(record);
            }

            // Service PTR Record
            if (type != PublishMessageType.Initial)
            {
                record = new PTRRecord()
                {
                    TimeToLive = (type == PublishMessageType.Stop) ? TimeSpan.Zero : BroadcastTTL,
                    Name       = Type,
                    DomainName = FullServiceInstanceName,
                };
                message.AnswerRecords.Add(record);
            }

            // A Records
            if (type != PublishMessageType.Stop)
            {
                foreach (var ip in IPAddresses)
                {
                    record = new ARecord()
                    {
                        TimeToLive = BroadcastTTL,
                        CacheFlush = true,
                        Name       = Hostname,
                        Address    = ip,
                    };
                    message.AdditionalRecords.Add(record);
                }
            }

            return(message);
        }
コード例 #15
0
ファイル: LdapCertResolver.cs プロジェクト: blinds52/nhind
        private void SetCerts(LdapConnection connection, SearchRequest request, X509Certificate2Collection retVal, SRVRecord srvRecord, string subjectName)
        {
            // send the LDAP request using the mail attribute as the search filter and return the userCertificate attribute
            var response = (SearchResponse)connection.SendRequest(request);

            if (response != null && response.Entries.Count > 0)
            {
                foreach (SearchResultEntry entry in response.Entries)
                {
                    SetCerts(entry, retVal, srvRecord, subjectName);
                }
            }
        }
コード例 #16
0
ファイル: LdapCertResolver.cs プロジェクト: blinds52/nhind
 private void SetCerts(SearchResultEntry entry, X509Certificate2Collection retVal, SRVRecord srvRecord, string subjectName)
 {
     if (entry.Attributes.Values == null || entry.Attributes.Count <= 0)
     {
         StringBuilder sb = new StringBuilder();
         sb.Append(subjectName).Append(" SRV:").Append(srvRecord).Append(" LDAP:").Append(entry.DistinguishedName);
         Error.NotifyEvent(this, new LdapCertResolverException(LDAPError.NoUserCertificateAttribute, sb.ToString()));
         return;
     }
     foreach (DirectoryAttribute entryAttr in entry.Attributes.Values)
     {
         if (entryAttr.Count > 0)
         {
             // search could possibly return more than one entry and each entry may contain
             // more that one certificates
             foreach (object t in entryAttr)
             {
                 try
                 {
                     var cert = new X509Certificate2((byte[])t);
                     retVal.Add(cert);
                 }
                 catch (Exception ex)
                 {
                     Error.NotifyEvent(this, ex);
                 }
             }
         }
     }
 }
コード例 #17
0
        public static SRVRecord[] ResolveSRV(string query)
        {
            byte[]           buffer = new byte[1024];
            byte[]           name = new byte[256];
            ushort           type, dlen, priority, weight, port;
            int              size;
            GCHandle         handle;
            List <SRVRecord> results = new List <SRVRecord>();

            size = res_query(query, C_IN, T_SRV, buffer, buffer.Length);

            handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);

            try
            {
                HEADER header = (HEADER)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(HEADER));

                int qdcount = ntohs(header.qdcount);
                int ancount = ntohs(header.ancount);

                int headerSize = Marshal.SizeOf(header);

                unsafe
                {
                    fixed(byte *pBuffer = buffer)
                    {
                        byte *pos = pBuffer + headerSize;
                        byte *end = pBuffer + size;

                        // We don't care about the question section.
                        while (qdcount-- > 0 && pos < end)
                        {
                            size = dn_expand(pBuffer, end, pos, name, 256);
                            if (size < 0)
                            {
                                return(null);
                            }
                            pos += size + 4;
                        }

                        // The answers, however, we do care about!
                        while (ancount-- > 0 && pos < end)
                        {
                            size = dn_expand(pBuffer, end, pos, name, 256);
                            if (size < 0)
                            {
                                return(null);
                            }

                            pos += size;

                            type = GETSHORT(ref pos);

                            // Skip TTL
                            pos += 6;

                            dlen = GETSHORT(ref pos);

                            if (type == T_SRV)
                            {
                                priority = GETSHORT(ref pos);
                                weight   = GETSHORT(ref pos);
                                port     = GETSHORT(ref pos);

                                size = dn_expand(pBuffer, end, pos, name, 256);
                                if (size < 0)
                                {
                                    return(null);
                                }

                                string nameStr = null;
                                fixed(byte *pName = name)
                                {
                                    nameStr = new String((sbyte *)pName);
                                }

                                var record = new SRVRecord();
                                record.NameNext = nameStr;
                                record.Priority = priority;
                                record.Weight   = weight;
                                record.Port     = port;
                                results.Add(record);

                                pos += size;
                            }
                            else
                            {
                                pos += dlen;
                            }
                        }
                    }
                }
            }
            finally
            {
                handle.Free();
            }

            return(results.ToArray());
        }
コード例 #18
0
ファイル: LdapCertResolver.cs プロジェクト: blinds52/nhind
        /// <summary>
        /// Resolves X509 certificates for a specific subject.  Will search address and then domain.
        /// </summary>
        /// <param name="connection">Active LDAP connection</param>
        /// <param name="srvRecord">Resolve <see cref="SRVRecord"/> to resolve. </param>
        /// /// <param name="address">The <see cref="String"/> address to resolve. </param>
        /// <returns>An <see cref="X509Certificate2Collection"/> of X509 certifiates for the address,
        /// or <c>null</c> if no certificates are found.</returns>
        X509Certificate2Collection GetCertificatesBySubect(LdapConnection connection, SRVRecord srvRecord, MailAddress address)
        {
            var retVal = new X509Certificate2Collection();

            // gate the base naming contexts
            var distNames = GetBaseNamingContext(connection);

            SetCerts(srvRecord, connection, distNames, address.Address, retVal);
            if (retVal.Count == 0)
            {
                SetCerts(srvRecord, connection, distNames, address.Host, retVal);
            }

            return(retVal);
        }
コード例 #19
0
        public static SRVRecord[] ResolveSRV(string query)
        {
            byte[] buffer = new byte[1024];
            byte[] name = new byte[256];
            ushort type, dlen, priority, weight, port;
            int size;
            GCHandle handle;
            List<SRVRecord> results = new List<SRVRecord>();

            size = res_query(query, C_IN, T_SRV, buffer, buffer.Length);

            handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);

            try {
                HEADER header = (HEADER)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(HEADER));

                int qdcount = ntohs(header.qdcount);
                int ancount = ntohs(header.ancount);

                int headerSize = Marshal.SizeOf(header);

                unsafe {
                    fixed (byte* pBuffer = buffer) {

                        byte *pos = pBuffer + headerSize;
                        byte *end = pBuffer + size;

                        // We don't care about the question section.
                        while (qdcount-- > 0 && pos < end) {
                            size = dn_expand(pBuffer, end, pos, name, 256);
                            if (size < 0) return null;
                            pos += size + 4;
                        }

                        // The answers, however, we do care about!
                        while (ancount-- > 0 && pos < end) {
                            size = dn_expand(pBuffer, end, pos, name, 256);
                            if (size < 0) return null;

                            pos += size;

                            type = GETSHORT(ref pos);

                            // Skip TTL
                            pos += 6;

                            dlen = GETSHORT(ref pos);

                            if (type == T_SRV) {
                                priority = GETSHORT(ref pos);
                                weight = GETSHORT(ref pos);
                                port = GETSHORT(ref pos);

                                size = dn_expand(pBuffer, end, pos, name, 256);
                                if (size < 0) return null;

                                string nameStr = null;
                                fixed (byte* pName = name) {
                                    nameStr = new String((sbyte*)pName);
                                }

                                var record = new SRVRecord();
                                record.NameNext = nameStr;
                                record.Priority = priority;
                                record.Weight = weight;
                                record.Port = port;
                                results.Add(record);

                                pos += size;
                            } else {
                                pos += dlen;
                            }
                        }
                    }
                }

            } finally {
                handle.Free();
            }

            return results.ToArray();
        }