Netty Encoding decoding error - java

I am coding a simple netty packet service. Currently I got a server and a client with a central protocol module.
My Client log looks like this:
PacketId encoded: 1
Writed packet.
Writing int: 441
My Server log:
PacketId: 8
protocol is null ? with id: 8
PacketId: 1
receiving test with id :0
Encoder:
#Override
protected void encode( ChannelHandlerContext channelHandlerContext, Packet packet, ByteBuf byteBuf ) {
final Protocol protocol = Protocol.getProtocol( packet.getClass() );
if ( protocol == null ) {
throw new IllegalStateException( "The requested packet is not registered!" );
} else {
final int packetId = protocol.getId();
if ( packetId > -1 ) {
byteBuf.writeInt( packetId );
System.out.println( "PacketId encoded: " + packetId );
packet.write( byteBuf );
System.out.println( "Writed packet." );
}
}
}
Decoder:
#Override
protected void decode( ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list ) throws Exception {
final int packetId = byteBuf.readInt();
System.out.println( "PacketId: " + packetId );
final Protocol protocol = Protocol.getProtocol( packetId );
if ( protocol == null ) {
System.out.println( "protocol is null ? with id: " + packetId );
} else {
final Class<? extends Packet> packetClass = Objects.requireNonNull( protocol ).getPacketClass();
if ( packetClass != null ) {
Packet packet = packetClass.newInstance();
packet.read( byteBuf );
list.add( packet );
}
}
}
Has somebody an idea on how to solve?
Thanks for any contribution!

Related

Writing a Jagged Array in HDF5 using the Java Native Library

I have tried numerous ways and followed some of the examples that are scattered around the web on how to write a jagged array (an array of arrays that may be of differing lengths) in HDF5.
Most of the examples are in C and rather low-level. Anyhow I can't seem to get it working and I just looked at the C-source code and it pretty much says that any variable-length datatypes that are not strings are not supported (if I understood correctly).
My miserable dysfunctional code (as is):
public void WIP_createVLenFloatDataSet( List<? extends Number> floats ) throws Exception
{
String group = "/test";
long groupId = createGroupIfNotExist( group );
MDataQualifier qualifier = new MDataQualifierImpl( group, "float", "0.0.0" );
long datasetId = openDataSet( qualifier );
long heapType = H5.H5Tcopy( MDataType.FLOAT_ARRAY.getHDFType() );
heapType = H5.H5Tvlen_create( heapType );
// heapType = H5.H5Tarray_create( heapType, 1, new long[]{1} );
if( !exists( datasetId ) )
{
long[] maxDims = new long[]{ HDF5Constants.H5S_UNLIMITED };
long dataspaceId = H5.H5Screate_simple( 1, new long[]{ 1 }, null );
// Create the dataset.
long datasetId1 = -1;
try
{
if( exists( m_fileId ) && exists( dataspaceId ) && exists( heapType ) )
{
long creationProperties = H5.H5Pcreate( HDF5Constants.H5P_DATASET_CREATE );
H5.H5Pset_chunk( creationProperties, /*ndims*/1, new long[]{ 1 } );
datasetId1 = H5.H5Dcreate( groupId, qualifier.getVersionedName(), heapType, dataspaceId, H5P_DEFAULT, creationProperties, H5P_DEFAULT );
// H5.H5Pclose( creationProperties );
}
}
catch( Exception e )
{
LOG.error( "Problems creating the dataset: " + e.getMessage(), e );
}
datasetId = datasetId1;
if( exists( datasetId ) )
{
// flushIfNecessary();
LOG.trace( "Wrote empty dataset {}", qualifier.getVersionedName() );
}
}
List<? extends Number> data = ( List<? extends Number> )floats;
// H5.H5Dwrite( datasetId, heapType, dataspaceId, memSpaceId, HDF5Constants.H5P_DEFAULT, Floats.toArray( data) );
ByteBuffer bb = ByteBuffer.allocate( data.size() * 4 );
floats.forEach( f -> bb.putFloat( f.floatValue() ) );
// H5.H5Dwrite( datasetId, heapType, H5S_ALL, H5S_ALL, H5P_DEFAULT, Floats.toArray( data ) );
H5.H5Dwrite( datasetId, heapType, H5S_ALL, H5S_ALL, H5P_DEFAULT, bb.array() );
}
Has anyone done this before and can at least confirm that it's not possible?
The most I can get out of HDF5 is the message "buf does not support variable length type".
Apparently the "glue code" of the JNI wrapper doesn't support this. If you want to use this feature you either have to implement your own JNI or wait for a newer version. The official JNI code is open source and can be found here.

Java Properties.getProperty() with an Array of Objects

I have a configuration file formatted as this,
object1=1
object2=2
object3=3
array={
sub_object1=sub_1
sub_object2=sub_2
sub_object3=sub_3
}
object4=4
object5=5
I have been trying to process this with Properties.getProperty, but am unable to find an effective method to process the array.
try {
Properties props = new Properties();
props.load( new FileInputStream( "settings.conf" ) );
if( !props.isEmpty() )
{
props.stringPropertyNames().stream().forEach((key) ->
{
if( !key.equals( "array" ) )
{
List<Object> subkeys = props.list();
for( subkeys: subkey ) )
{
System.out.println( "Subkey: " + props.getProperty( subkey ) );
}
}
});
}
} catch ( Exception e ) {
e.printStackTrace();
}
I realize the above is errorous, but I have been unable to find a solution. Any one have an idea?

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated when trying to session.getPeerCertificateChain()

I am pretty new to working with http/certs/etc. I have my own hostnameVerifier set up for an apache httpclient. (Trying to allow FQDN to not match as long as cert FQDN is still internal to our domain - not the best I know - but better than nothing)
It works fine for most of the servers I have tested with, but there are a couple where I get
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
when I try to
session.getPeerCertificateChain().
I am able to view the certificate just fine when I go to the same link in firefox.
Below is the full code for the method.
#Override
public void verify( String arg0, SSLSocket arg1 ) throws IOException
{
String certFQDN = null;
SSLSession session = arg1.getSession();
javax.security.cert.X509Certificate[] certs = session.getPeerCertificateChain();
if ( certs.length > 0 )
{
String name = certs[ 0 ].getSubjectDN().getName();
for ( String s : name.split( "," ) )
{
String part[] = s.split( "=" );
if ( part[ 0 ].trim().equals( "CN" ) )
{
certFQDN = part[ 1 ].trim();
}
}
}
else
{
throw new IOException( "Could not find certificate chain." );
}
if ( !certFQDN.substring( certFQDN.length() - 11 ).equals( ".domain.com" ) )
{
throw new SSLException( "Not an internal host: " + certFQDN );
}
}
#Override public void verify( String arg0, SSLSocket arg1 ) throws IOException {
arg1.getSession();
javax.security.cert.X509Certificate[] certs = session.getPeerCertificateChain();
].getSubjectDN().getName();
) )
);
].trim().equals( "CN" ) )
].trim();
not find certificate chain." );
certFQDN.length() - 11 ).equals( ".domain.com" ) )
internal host: " + certFQDN );
}

Java platform independent encryption

I am currently using Jasypt for my web application. It works fine, but the encryption is different depending which server it is hosted on.
For this reason, I can't just get the data in the live DB and use it for debugging in my dev environment. It would be helpful, but I can live without it.
What worries me is that at the moment I am using a hosting provider. All has been ok so far, but I worry that if at some point they replace the server, or move my application on to another one, the encrypted data ( such as emails and passwords for the login, and more ) will not be encrypted in the same way and all the data will become unusable.
Does anybody know an alternative to Jasypt which is platform independent?
Or is there a way to make Jasypt itself platform independent?
Thanks, Dan
PS : I would need a method that has these basic functionalities: string encryption ( reversible ), password encryption ( not reversible but comparable ) and "SHA-1" encryption. Apologies if the terminology in the last paragraph is not the most correct, but I am not an encryption expert at all.
Thanks!
Edited to add code, results and exceptions:
public class Test
{
public static void main ( String [] args )
{
System.out.println ( "String encryption = " + new EncryptionUtil ( ).encryptString ( "test string" ) );
System.out.println ( "Password encryption = " + new EncryptionUtil ( ).encryptPassword ( "test password" ) );
}
}
produces this in the dev environment :
String encryption = ybXukKBN57QSY8ITPgu9RmJQrZP4Py6g
Password encryption = nNX82PuKx5TrqBFSCy6yzNpco7Asov2S
Everytime the output is different, but it is possible to decrypt the string, and compare the password by doing this:
public class Decryption
{
public static void main ( String [] args )
{
System.out.println ( new EncryptionUtil ( ).decryptString ( "ybXukKBN57QSY8ITPgu9RmJQrZP4Py6g" ) );
System.out.println ( new EncryptionUtil ( ).passwordsMatch ( "test password", "nNX82PuKx5TrqBFSCy6yzNpco7Asov2S" ) );
}
}
Which gives this output:
test string
true
This is the encryption util class that I created:
public class EncryptionUtil
{
private String password = "<<=Encryption-Password=>>";
// ============================================================ Encrypt password string
public String encryptPassword ( String pwd )
{
if ( null != pwd && ! "".equals ( pwd ) )
{
return new BasicPasswordEncryptor ().encryptPassword ( pwd );
}
else
{
return "";
}
}
// ====================================== Check if password entered matches that stored
public boolean passwordsMatch ( String enteredPassword, String storedPassword )
{
return new BasicPasswordEncryptor().checkPassword ( enteredPassword, storedPassword );
}
//===================================================================== Encrypt string
public String encryptString ( String text )
{
if ( null != password && ! "".equals ( password ) )
{
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword ( password );
return textEncryptor.encrypt ( text );
}
else
{
return "";
}
}
// ===================================================================== Decrypt string
public String decryptString ( String text )
{
try
{
if ( null != text && ! "".equals ( text ) )
{
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword ( password );
return textEncryptor.decrypt ( text );
}
else
{
return "";
}
}
catch ( Exception e )
{
return text;
}
}
// =============== Encrypt email. Used for login and registration only, not decryptable
public String encryptEmail ( String email )
{
if ( null != email && ! "".equals ( email ) )
{
return new String ( new Digester("SHA-1").digest ( email.getBytes () ) );
}
else
{
return "";
}
}
}
The same in the LIVE environment gives me this:
String encryption = L/UlkJjYhLnYiov7XeDjb9W7+k8Gduvz
Password encryption = P+LJM7VJHu/hudSQOrmvcvV/DrzCv+pj
When I try to decrypt the string and check the password, I get this:
public class Decryption
{
public static void main ( String [] args )
{
System.out.println ( new EncryptionUtil ( ).decryptString ( "L/UlkJjYhLnYiov7XeDjb9W7+k8Gduvz" ) );
System.out.println ( new EncryptionUtil ( ).passwordsMatch ( "test password", "P+LJM7VJHu/hudSQOrmvcvV/DrzCv+pj" ) );
}
}
The result with the strings obtained from LIVE ( those above ) gives this:
test string
false
This time the encryption of the string works ( I had it not working in the past, I am a bit surprised and confused to be honest ), but the password fails.
New edit - some strings, when encrypted, end with ==. The strings that do not have "==" at the end, are decryptable across systems. Those which do do not work. Maybe this can be a clue?
I am not sure what the problem was - anyway I managed to solve it with a random attempt which somehow worked...
If anybody finds him / her self in the same situation, an attempt ( lucky random one in my case ) is to change the password used for the text encryptor.
I cannot give any explanation on why it worked.
You should take a look at BouncyCastle
ThereĀ“s an example here

Authenticating from Java (Linux) to Active Directory using LDAP WITHOUT servername

Our developers use Java on Linux for various things (like checking membership of groups etc). It works - no problem with that!
The problem is that they have hardcoded the servernames of our Domain Controllers (LDAP-servers) in their code. So now when we need to replace them with newer DCs, they need to change the code.
Active Directory by nature is redundant. The domain name (example: domain.local) is a round-robin of all the DC:s available for our AD.
Is there any way for the developer to NOT specify Domain Controller server names but simply the Active Directory domain name and then their Linux server will find the DC:s available and use whichever one is up and running?
Examples/links appreciated. Thanks!
Obviously, the server name should at least be configurable, not hard coded into the application.
However, you should be able to find the server by looking up a special DNS record, namely a SRV record for _ldap._tcp.DOMAINNAME. The linux servers have to be configured to use the same DNS server as your AD updates.
To determine whether this is feasible, run the command host -t srv _ldap._tcp.DOMAINNAME on your linux server
See also Querying the DNS service records to find the hostname and TCP/IP provides some info on how to look up SRV records in java, and https://community.oracle.com/blogs/kohsuke/2008/06/12/more-active-directory-integration-java
We use the follow code that work on a large amount of systems:
/**
* Detect the default LDAP server
* #return server:port or null
*/
String getDefaultLdapHost() {
try {
Hashtable<String, String> env = new Hashtable();
env.put( "java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory" );
DirContext dns = new InitialDirContext( env );
InetAddress address = InetAddress.getLocalHost();
String domain = address.getCanonicalHostName();
if( domain.equals( address.getHostAddress() ) ) {
//domain is a ip address
domain = getDnsPtr( dns );
}
int idx = domain.indexOf( '.' );
if( idx < 0 ) {
//computer is not in a domain? We will look in the DNS self.
domain = getDnsPtr( dns );
idx = domain.indexOf( '.' );
if( idx < 0 ) {
//computer is not in a domain
return null;
}
}
domain = domain.substring( idx + 1 );
Attributes attrs = dns.getAttributes( "_ldap._tcp." + domain, new String[] { "SRV" } );
Attribute attr = attrs.getAll().nextElement();
String srv = attr.get().toString();
String[] parts = srv.split( " " );
return parts[3] + ":" + parts[2];
} catch( Exception ex ) {
ex.printStackTrace();
return null;
}
}
/**
* Look for a reverse PTR record on any available ip address
* #param dns DNS context
* #return the PTR value
* #throws Exception if the PTR entry was not found
*/
private String getDnsPtr( DirContext dns ) throws Exception {
Exception exception = null;
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while(interfaces.hasMoreElements()) {
NetworkInterface nif = interfaces.nextElement();
if( nif.isLoopback() ) {
continue;
}
Enumeration<InetAddress> adresses = nif.getInetAddresses();
while(adresses.hasMoreElements()) {
InetAddress address = adresses.nextElement();
if( address.isLoopbackAddress() || address instanceof Inet6Address) {
continue;
}
String domain = address.getCanonicalHostName();
if( !domain.equals( address.getHostAddress() ) && (domain.indexOf( '.' ) > 0) ) {
return domain;
}
String ip = address.getHostAddress();
String[] digits = ip.split( "\\." );
StringBuilder builder = new StringBuilder();
builder.append( digits[3] ).append( '.' );
builder.append( digits[2] ).append( '.' );
builder.append( digits[1] ).append( '.' );
builder.append( digits[0] ).append( ".in-addr.arpa." );
try {
Attributes attrs = dns.getAttributes( builder.toString(), new String[] { "PTR" } );
return attrs.get( "PTR" ).get().toString();
} catch( Exception ex ) {
exception = ex;
}
}
}
if( exception != null ) {
throw exception;
}
throw new IllegalStateException("No network");
}

Categories