querying against a particular dns server in java - java

I'm trying to query again a particular dns server both in linux shell using digg and using Java.
The dig command works. but the java way doesn't. what's wrong?
dig #dns.nic.it test.it
;; QUESTION SECTION:
;test.it. IN A
;; AUTHORITY SECTION:
test.it. 10800 IN NS dns2.technorail.com.
test.it. 10800 IN NS dns.technorail.com.
test.it. 10800 IN NS dns3.arubadns.net.
test.it. 10800 IN NS dns4.arubadns.cz.
java way
public static void rootDNSLookup(String domainName) throws NamingException{
String server="dns://dns.nic.it";
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
env.put("java.naming.provider.url", server);
DirContext ictx = new InitialDirContext(env);
Attributes attrs = ictx.getAttributes(domainName, new String[] {"A", "AAAA", "NS", "SRV"});
System.out.println(attrs);
NamingEnumeration e = attrs.getAll();
while(e.hasMoreElements()) {
Attribute a = e.next();
System.out.println(a.getID() + " = " + a.get());
}
}
java prints:
No attributes

The best way to go is to use the library dnsjava.
The particular class you are looking for is SimpleResolver. It has two constructors. When used with no parameters it will use the system's DNS settings. If you provide an IP address it will force that as the DNS server.
You can find a great example of usage here: dnsjava Examples.

Don't try and get all attributes at the same time.
Use:
Attributes attrs = ictx.getAttributes(domainName, new String[] {"A"});
Use a String array that contains all attributes you want and iterate over the call passing in the attribute.
String[] attributes = {"A", "AAAA", "NS", "SRV"};
for (String attribute : attributes) {
...
Attributes attrs = ictx.getAttributes(domainName, new String[] {attribute});
...
}

Related

Finding security vulnerabilites in my code - LDAP Search

How do i find vulnerabilites in my code here. My assignment is asking me to find the vulnerabilites using no programm so no spotbugs, etc. Is there any website and/or tips for me to find the vulnerabilites. Here's my code
I've tried to google but i've had a hard time finding solid website or doc for finding or helping me find vulnerabilites.
User search in an LDAP directory:
public class LsiLDAPUsers
{
private void searchRecord( String userSN, String userPassword ) throws NamingException
{
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
try
{
DirContext dctx = new InitialDirContext(env);
SearchControls sc = new SearchControls();
String[] attributeFilter = { "cn", "mail" };
sc.setReturningAttributes(attributeFilter);
sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
String base = "dc=lsi,dc=com";
String filter = "(&(sn=" + userSN + ")(userPassword=" + userPassword + "))";
NamingEnumeration<?> results = dctx.search(base, filter, sc);
while (results.hasMore())
{
SearchResult sr = (SearchResult) results.next();
Attributes attrs = (Attributes) sr.getAttributes();
Attribute attr = (Attribute) attrs.get("cn");
System.out.println(attr);
attr = (Attribute) attrs.get("mail");
System.out.println(attr);
}
dctx.close();
}
catch (NamingException e)
{
// Forward to handler
}
}
}
I need to make the code more secure basically. This is one of my code. But i have a lot of work on other part of it. I just need to get a good exemple and/or tips from this one, thanks !!
Just a few hints:
a major pillar of secure coding is proper verification of user input. That is the main entry point for most hacks.
using SSL or TLS for network connections is today's default
anonymous searching is disabled in most systems today

Java Active Directory query returning incomplete user list

I want to list all AD users in Java. I'm using this code:
String ldapUri = "ldap://" + serverName;
LdapContext ctx = null;
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_AUTHENTICATION, "Simple");
//it can be <domain\\userid> something that you use for windows login
//it can also be
env.put(Context.SECURITY_PRINCIPAL, adminName);
try {
env.put(Context.SECURITY_CREDENTIALS, adminPass.getBytes("UTF8"));
env.put(Context.REFERRAL, "follow");
} catch (java.io.UnsupportedEncodingException e) {
log.error("Non-Fatal exception : ", e);
/* ignore */
}
//in following property we specify ldap protocol and connection url.
//generally the port is 389
env.put(Context.PROVIDER_URL, ldapUri);
log.info("AD Server: " + ldapUri + ", admin " + adminName);
ctx = new InitialLdapContext(env, null);
DirContext ctx1 = new InitialDirContext(env);
SearchControls ctls = new SearchControls();
String[] attrIDs = {"distinguishedName", "cn", "name", "uid",
"sn",
"name",
"memberOf",
"displayName",
"userPrincipalName"};
ctls.setReturningAttributes(attrIDs);
ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration answer = ctx1.search(searchPath, "(&(objectClass=user)(objectCategory=person))", ctls);
while (answer.hasMoreElements()) {
// Process user
SearchResult rslt = (SearchResult) answer.next();
}
The code works fine in most environments but there is a customer that reports that some users are missing. I've tried to troubleshoot it but the user aren't listed but they are listed using Active Directory admin or Active Directory Explorer.
Any ideas?
I assume that account you are using has enough permissions. As far as I recall any instance of domain controller will return 1000 objects by default. It is very likely you are running into this situation. You have to use LDAP pagination In order to solve this problem. Take a look into JNDI page controls - https://docs.oracle.com/javase/tutorial/jndi/newstuff/paged-results.html.
Also, take a look into JNDI code samples from Java forum - https://community.oracle.com/thread/1157644?tstart=0.
Hope this helps.
Besides making sure that you don't hit any query limits you should consider that some of your customers might run a more complex Active Directory setup.
This might involve multiple domains. In order to address those you need to connect to the global catalog. You do so by binding to port 3268.
You should either make this your standard way of connecting or make this configurable by an administrator at your customers site.
Read more about this at Microsoft: https://technet.microsoft.com/de-de/library/cc978012.aspx

LDAP Authentication with Java, explanation needed

if you could please explain to me one piece of the following code that I don't quite understand I would be grateful:
What does (&(cn=*)({0}={1})) mean in the filter field?
I know that cn means search for the cn attribute and then ADD the result to ({0}={1}).
What is the meaning of ({0}={1})?
Here's the code:
try {
// Create initial context
ctx = new InitialDirContext(env);
Attributes matchAttrs = new BasicAttributes(true);
matchAttrs.put(new BasicAttribute(ldap_id_field, netid));
String attlist[] = {ldap_email_field, ldap_givenname_field,
ldap_surname_field, ldap_phone_field};
// look up attributes
try {
SearchControls ctls = new SearchControls();
ctls.setReturningAttributes(attlist);
NamingEnumeration answer =
ctx.search(ldap_search_context, "(&(cn=*)({0}={1}))", new Object[] {ldap_id_field,netid},ctls);
}
...
It looks wrong to me. All that filter does is find entries which have any CN and which match an attribute name/value pair specified as arguments to the search, in ldap_id_field and netid respectively. There is no 'adding' going on: the & means that both filter-expressions must match.

Java properties containing dollar delimited variables

I'm storing my app settings in properties file that I use in Ant and in the Java app. Maybe it's not good pratice, but I find it very handy to avoid duplications. The file contains variables such as:
usefulstuff.dir = ${user.home}/usefulstuff
So that other people can run the program on *nix systems, provided that they have the usefulstuff folder in their home directory.
Now, the fascinating thing is that this properties file works fine in Ant (the variable gets resolved to /home/username), while when I load the same file directly in the Java app, I get a string containing ${user.home}/usefulstuff, which is not very useful indeed.
I load the props with this code in Ant:
<loadproperties srcFile="myProps.properties"/>
And in the Java app:
FileInputStream ins = new FileInputStream(propFilePath);
myProps.load(ins);
ins.close();
Am I missing anything? Maybe is there a better way to load properties in a Java app than load()?
I don't think it's particularly "fascinating" that this works in Ant - Ant is deliberately written to do so:
Properties are key-value-pairs where Apache Ant tries to expand ${key} to value at runtime.
and
Ant provides access to all system properties as if they had been defined using a <property> task. For example, ${os.name} expands to the name of the operating system.
If you want the same behaviour, you'll need to implement the same sort of logic. It's possible that you could use the classes from Ant directly, if they do what you want - and if you're happy to ship the relevant binaries (and abide by the licence).
Otherwise, you might want to use a regular expression to find all the matches - or (probably simpler) iterate over all of the system properties and do a simple replacement on them.
As Jon said, it should be straighforward to write the property handling yourself. For eg:
import java.util.*;
public class PropertiesTest
{
public static void main(String[] args)
{
Properties props = new Properties();
props.setProperty("foo", "foo/${os.name}/baz/${os.version}");
props.setProperty("bar", "bar/${user.country}/baz/${user.country}");
System.out.println("BEFORE:");
printProperties(props);
resolveSystemProperties(props);
System.out.println("\n\nAFTER:");
printProperties(props);
}
static void resolveSystemProperties(Properties props)
{
Map<String, String> sysProps = readSystemProperties();
Set<String> sysPropRefs = sysProps.keySet();
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
for (String ref : sysPropRefs)
{
if (value.contains(ref))
{
value = value.replace(ref, sysProps.get(ref));
}
}
props.setProperty(name, value);
}
}
static Map<String, String> readSystemProperties()
{
Properties props = System.getProperties();
Map<String, String> propsMap =
new HashMap<String, String>(props.size());
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
propsMap.put("${" + name + "}", props.getProperty(name));
}
return propsMap;
}
static void printProperties(Properties props)
{
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
System.out.println(name + " => " + value);
}
}
}

Obtain nameserver information for DNS lookups in Java

If I look up a IP address from a DNS name as follows:
InetAddress inetAddress = InetAddress.getByName(name);
String address = inetAddress.getHostAddress();
Can I find out which nameserver gave me the information?
I'm not sure if this is what you want, but there's a DNSJava library which provides DNS functionality in Java. Perhaps you can use this to either get a better understanding of your issues, or to implement a particular solution ? Like I say, not a perfect match for you, but perhaps helpful.
For a given InetAddress, try the following:
// get the default initial Directory Context
InitialDirContext idc = new InitialDirContext();
// get the DNS records for inetAddress
Attributes attributes = idc.getAttributes("dns:/" + inetAddress.getHostName());
// get an enumeration of the attributes and print them out
NamingEnumeration attributeEnumeration = attributes.getAll();
System.out.println("-- DNS INFORMATION --");
while (attributeEnumeration.hasMore()) {
System.out.println("" + attributeEnumeration.next());
}
attributeEnumeration.close();
Adapt it to pick up what you're looking for.
you need an Naming Context. Optional you can Specify the DNS Server.
And even then you need to select that you are looking for. Here is an example.
final String ADDR_ATTRIB = "A";
final String[] ADDR_ATTRIBS = {ADDR_ATTRIB};
final Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
idc = new InitialDirContext(env);
env.put(Context.PROVIDER_URL, "dns://"+dnsServer);
final List<String> ipAddresses = new LinkedList<>();
final Attributes attrs = idc.getAttributes(hostname, ADDR_ATTRIBS);
final Attribute attr = attrs.get(ADDR_ATTRIB);
if (attr != null) for (int i = 0; i < attr.size(); i++) ipAddresses.add((String) attr.get(i));

Categories