Friday, August 24, 2018

Reading values from properties file

I am trying to read a property file in a seperate "GetConfigProperties" class file and passing the value to the main function "LoginTest.java". But I am not able to get the expected property value and there is no errors displayed in the code as well.

I have the property file in src/config.properties I have the main function in src/com.automation.test -> LoginTest.java I have the java function to read property file in src/com.library.helper -> GetConfigProperties.java

My code to read Config property is given below

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties; 

public class GetConfigProperties {

//protected File file = new File("config.properties");
protected static Properties props = new Properties();
InputStream is = GetConfigProperties.class.getResourceAsStream("/config.properties");

    public static String extractUrlData(){
    String webUrl = props.getProperty("webUrl");
    return webUrl;
    }
}

-- Also, I imported this class file in the main LoginTest.java and try to access the get the data as GetConfigProperties.ExtractUrlData() but failed.

P.S - I looked into many of the questions and answers and since I am totally new to Java couldn't understand them as everything seems to be unique.

Solved

Here's how you access the properties:

GetConfigProperties.ExtractUrlData();

This calls the static method ExtractUrlData() (which should be called extractUrlData() to conform to Java naming conventions). Nowhere do you call the GetConfigProperties() method of GetConfigProperties, which is where the Properties object is populated.

You should choose: either the Properties is static, and it should be populated when the class is loaded, by a static method, or a static block:

private static Properties props = createAndPopulateProperties();

or it should be an instance field, that can be populated by the class constructor or one of its instance methods that would initialize the object.

Another problem is that there is a very low chance that the user running your app has the file in exactly the same folder as you (if he's even running Windows). You should bundle the properties file with the .class files of the app (in the same jar, or the same directory), and use the class loader to load the resource:

InputStream is = GetConfigProperties.class.getResourceAsStream("/config.properties");

Monday, August 20, 2018

How do you use asymmetric keys or certificate authentication in SNMP4J?

I am working on a project that would like to be able to use certificates or keys as a method of authentication for SNMPv3. We are using the java library SNMP4J.

During my research I have found that SNMP uses TLS/DTLS for message encryption and supposedly also for authentication. Source 1 | Source 2 | Source 3

Looking into the little documentation SNMP4J has, I found that it allows the usage of TLS certificates for encrypting traffic. But I am not sure how the authentication is done, if possible, using a public/private key pair. TLS Traffic Encryption Example | SNMP4J Documentation

Any help would be appreciated.

Solved

I was able to authenticate using a similar method as described in the example TLS Traffic Encryption Example.

So as one would expect from the example, I can confirm that SNMP4J uses the keystore set in the Java Property javax.net.ssl.keystore, javax.net.ssl.keyStorePassword, javax.net.ssl.trustStore, and javax.net.ssl.trustStorePassword.

Below are the changes I made to the example to make it work.

The alias (or security name in the documentation) needs to be set in the CertifiedTarget constructor so it knows which certificate to use.

 CertifiedTarget ct = new CertifiedTarget(new OctetString(alias));

The security level must be set or the SNMP agent will complain and fail authentication.

 ct.setSecurityLevel(SecurityLevel.AUTH_PRIV);

The SecurityCallback subject DN must match the server certificate subject EXACTLY the way it wants otherwise it will deny all responses.

 securityCallback.addAcceptedSubjectDN("EMAILADDRESS=admin@net-snmp.org, CN=snmpagent, OU=Development, O=Net-SNMP, L=Davis, ST=CA, C=US");

Lastly, you must register the server public certificate alias (Security Name) with the address.

 securityCallback.addLocalCertMapping(ct.getAddress(), "snmpagent");

It comes together to look something like this.

// Set java keystore manually
System.setProperty("javax.net.ssl.keyStore", KEYSTORE_DIR);
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
System.setProperty("javax.net.ssl.trustStore", KEYSTORE_DIR);
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

// create the TLS transport mapping:
TLSTM transport = new TLSTM();

// set the security callback (only required for command responder,
// but also recommended for command generators) -
// the callback will be configured later:
DefaultTlsTmSecurityCallback securityCallback = new DefaultTlsTmSecurityCallback();
((TLSTM) transport).setSecurityCallback(securityCallback);
MessageDispatcher md = new MessageDispatcherImpl();
// we need MPv3 for TLSTM:
MPv3 mpv3 = new MPv3();
md.addMessageProcessingModel(mpv3);

Snmp snmp = new Snmp(md, transport);

// create and initialize the TransportSecurityModel TSM:
SecurityModels.getInstance().addSecurityModel(new TSM(new OctetString(mpv3.getLocalEngineID()), false));

// do not forget to listen for responses:
snmp.listen();

CertifiedTarget ct = new CertifiedTarget(new OctetString("alias"));
ct.setVersion(SnmpConstants.version3);
ct.setSecurityModel(SecurityModel.SECURITY_MODEL_TSM);
ct.setAddress(GenericAddress.parse(myAddress));
ct.setSecurityLevel(SecurityLevel.AUTH_PRIV);

securityCallback.addAcceptedSubjectDN("EMAILADDRESS=admin@net-snmp.org, CN=snmpagent, OU=Development, O=Net-SNMP, L=Davis, ST=CA, C=US");
securityCallback.addLocalCertMapping(ct.getAddress(), "snmpagentalias");

PDU pdu = new ScopedPDU();
pdu.add(new VariableBinding(new OID(someOid)));
pdu.setType(PDU.GET);

ResponseEvent response = snmp.send(pdu, ct);

You also have to make sure all the certificates are properly configured so that it actually takes them.

As a side-note, in the discovery of this my team and I discovered several bugs in the TLS handling by SNMP4J, mostly in the transport layer. It seems to be a timing issue (race condition maybe?) where it will get the SNMP data but then ignore it. We were able to get around it by setting the CertifiedTarget timeout and retries really high. We will officially report on this when we have more information.


Sunday, August 19, 2018

Eclipse modeling

I search for tool that can generate code from UML diagram for Eclipse. The tool should generate code from UML diagram, reverse engeneering to see code changes, and merge option to prevent the deletion of the file for any change.

Is there tool that do that, or is it too much to ask?

Solved

If you like Eclipse based tools, I could recommend the free Uml to Java generator from Obeo, which may be downloaded from the Marketplace:

Help -> Eclipse Marketplace...

enter image description here However, I think that it doesn´t completely fit your needs, since I believe that it doesn´t provide reverse engineering facilities. Also note that they use Acceleo for code generation, which is the reference OMG specification implementation.


Saturday, August 18, 2018

Angular2: Central Session Service?

I am working on an Angular2 app where the user can regsiter and log in. To handle the session - for the purpose of this discussion this mean only a flag if the user if logged in or not - I created a Service which looks like this:

import {Injectable} from 'angular2/core';

@Injectable()
export class SessionService {
  private _status:boolean;

  constructor () {
    if(1 == 1) {
      this._status = true;
    }
    console.log("New SessionService");
  }

  isLoggedIn() {
    return this._status;
  }

  logOut() {
    this._status = !this._status;
  }
}

Now I want to use the isLoggedIn() method in my template to show or hide certain UI elements / menu items. Question is simply: how can I use one central instance of this service throughout my whole application?

I tried something like this for my AppComponent:

(...)
import {SessionService} from '../services/session.service';

@Component({
    selector: 'my-app',
    templateUrl: 'app/app/app.component.html',
    directives: [ROUTER_DIRECTIVES],
    providers: [SessionService]
})
@RouteConfig([
  ...
])
export class AppComponent {
  constructor(private _userService: UserService, private _sessionService: SessionService) {}
}

And basically the same for on other (child) component:

(...)
import {SessionService} from '../services/session.service';

@Component({
  templateUrl: 'app/user/login.component.html',
  directives: [ROUTER_DIRECTIVES],
  providers: [HTTP_PROVIDERS, UserService, SessionService]
})
export class LoginComponent {
  model = {email: "", password: ""}

  constructor(private _userService: UserService, private _sessionService: SessionService) {}

  onSubmit() {
      this._sessionService.logOut();
  }
}

My observations with this are: - In the console I see the output "New SessionService" twice (see constructor of SessionService) - When I trigger the method this._sessionService.logOut() in the LoginComponent all elements bound to _sessionService.isLoggedIn() of the template of LoginComponent disappear/appear, but for other bound elements in the App template, nothing changes.

Do I have a basic misunderstanding of Angular2 here? Is this approach reasonable? If no, what would be an alternative?

Thanks a lot!

PS: I hope the amount of code is not too much...

Solved

Your problem is in your LoginComponent. Don't put the SessionService in the providers array. This creates a second instance.

Put the SessionService in the providers of the parent component that is common to all of the components that will use the service. This will make it available to all of its child components. In this case, just the AppComponent.

Then, you can just put the SessionService in the constructor of each child component that will use it.