I am using ColdFusion 11 and I have an eSignWeb.jar file (created in java obviously) in my class path. What this .jar does is to receive a path where a file is located on the client's computer and then analyze that file using Bouncy Castle.
But when I run it, I get the following error:
Code: java.io.FileNotFoundException:
C:\Users\name\Documents\clientfile.cer (The system can not find the
specified path)
The error is because my .jar file tries to look for the clientfile.cer file on the server and not the client machine.What I need is that this .jar running on the server can search this file on the client's computer.
Important:
The clientfile.cer file can never upload to the server, so it has to be analyzed on the client side.
I have to use ColdFusion with java
My code in ColdFusion is simple:
<cfset eSign = createObject("java","eSignWeb.SignAB") />
<cfoutput>
<!--- TEST1--->
<cfdump var="#eSign#">
#eSign.callsignCF()#
<hr />
<!--- TEST2 WITH cfscript --->
<cfscript>
classLoader = createObject("java","eSignWeb.SignAB");
response = classLoader.callsignCF();
WriteOutput("Test whith CFSCRIPT " & response);
</cfscript>
</cfoutput>
The code in my .jar file:
package eSignWeb;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;
import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class SignAB {
public String callsignCF(){
String vCer;
vCer = "C:\\Users\\name\\Documents\\clientfile.cer"; //Path where the .cer file is located on the client side
Security.addProvider(new BouncyCastleProvider()); // add bc as provider
String archivoCer;
X509Certificate certificado = null;
Date fechaFinal;
Date fechaInicial;
Date fechaActual;
//start cer
archivoCer = vCer;
try {
FileInputStream is = new FileInputStream(archivoCer);
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
certificado = (X509Certificate)cf.generateCertificate(is);
fechaFinal = certificado.getNotAfter();
fechaInicial = certificado.getNotBefore();
fechaActual = new Date();
if(fechaActual.before(fechaInicial) && fechaActual.after(fechaFinal)){
return "Invalid date";
}else{
String myVarConRFC = "2.5.4.45";
String dn = certificado.getSubjectX500Principal().getName();
LdapName ldapDN = new LdapName(dn);
ldapDN.getRdns().forEach((index) -> {
if(index.getType().equals(myVarConRFC)){
//RFC
String myRFC = new String((byte[]) index.getValue());
}
});
}
}
catch (InvalidNameException ex) {
return "E0: Error on cer. Code: "+ ex;
}
catch(CertificateException a) {
return "E1: The specified file is not a valid certificate file. Code: " +a;
}
}
catch(FileNotFoundException fnfe) {
return "E2: Certificate file does not exist. Code: " +fnfe;
}
// End cer
return "Unknown error";
}
}
As you can see, the .jar runs on the server and that's why it does not find the .cer file. Any idea of how to get a functionality that allows .jar to search the file on the client's machine?
If I could upload the .cer file to the server, it would be very easy, but that is forbidden. The .cer file should never leave the client's machine.
Thank you very much for any guidance in this regard!
CF alone won't work for that type of task, because it only operates on the CF server. It can't access client files at all. Only files uploaded to the server or a location accessible to the server (which you said you can't do).
In order to access files on a client machine, you need something like a signed Java Applet or Web Start Application, which does run on the client. The "signed" part is important. For security reasons, applets and the like can't just access files on the client machine whenever they wish. The user must explicitly grant the Applet or Web Start application permission to do so.
Related
I'd like to combine HiveMQ Client and HiveMQ Community Edition which is the implementation for the broker into one project. I tried adding the HiveMQ client as a dependency to the build.gradle file in the Hive MQ Community Edition (broker). It was able to build successfully but I'm not sure if I did it correctly. When I tried to reference client classes inside the Community Edition it gives me errors. Am I missing something? I want to be able to just put put the client project inside of the broker community edition and be able to create a client and access all of the classes I could in HiveMQ client. I left the instructions from the HiveMQ Client website, links, and also what the build.gradle file looks like the HiveMQ community edition.
Error I'm getting: The import com.hivemq.client cannot be resolved (Happens to all imports referencing anything in the HiveMQ Client project)
Link to the HiveMQ GitHubs:
https://github.com/hivemq/hivemq-mqtt-client
https://github.com/hivemq/hivemq-community-edition
Code from Main.Java that produces the error
package com.main;
import java.util.UUID;
import com.hivemq.client.mqtt.MqttGlobalPublishFilter;
import com.hivemq.client.mqtt.datatypes.MqttQos;
import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient;
import com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient.Mqtt5Publishes;
import com.hivemq.client.mqtt.mqtt5.Mqtt5Client;
import com.hivemq.client.mqtt.mqtt5.message.publish.Mqtt5Publish;
import java.util.logging.Logger;
import java.nio.ByteBuffer;
import java.util.Optional;
import java.util.logging.Level;
import java.util.concurrent.TimeUnit;
public class Main {
private static final Logger LOGGER = Logger.getLogger(Main.class.getName()); // Creates a logger instance
public static void main(String[] args) {
// Creates the client object using Blocking API
Mqtt5BlockingClient client1 = Mqtt5Client.builder()
.identifier(UUID.randomUUID().toString()) // the unique identifier of the MQTT client. The ID is randomly generated between
.serverHost("0.0.0.0") // the host name or IP address of the MQTT server. Kept it 0.0.0.0 for testing. localhost is default if not specified.
.serverPort(1883) // specifies the port of the server
.buildBlocking(); // creates the client builder
client1.connect(); // connects the client
System.out.println("Client1 Connected");
String testmessage = "How is it going";
byte[] messagebytesend = testmessage.getBytes(); // stores a message as a byte array to be used in the payload
try {
Mqtt5Publishes publishes = client1.publishes(MqttGlobalPublishFilter.ALL); // creates a "publishes" instance thats used to queue incoming messages
client1.subscribeWith() // creates a subscription
.topicFilter("test/topic")
.send();
System.out.println("The client has subscribed");
client1.publishWith() // publishes the message to the subscribed topic
.topic("test/topic")
.payload(messagebytesend)
.send();
Mqtt5Publish receivedMessage = publishes.receive(5,TimeUnit.SECONDS).orElseThrow(() -> new RuntimeException("No message received.")); // receives the message using the "publishes" instance
LOGGER.info("Recieved: " + receivedMessage);
byte[] getdata = receivedMessage.getPayloadAsBytes();
System.out.println(getdata.toString());
System.out.println(receivedMessage);
}
catch (Exception e) { // Catches all exceptions using the "base exception"
LOGGER.log(Level.SEVERE, "Something went wrong.", e);
}
}
}
I didn't have the HiveMQ client in my build path. On the line with red errors Eclipse gave me the option of fixing the project set up and I click on it and it automatically added the HiveMQ client to the build path. I posted a screenshot below.
I'm accessing a specific hostname in my Java application which I don't want to be redirected to somewhere else. It is using HTTP and not HTTPS. Is a redirect from the outside even possible? I thought of checking if the hosts file on Windows contains an entry that may redirect the hostname:
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.SystemUtils;
import java.io.File;
import java.io.IOException;
public class HostsFileChecker
{
public static boolean isPossiblyRedirecting(String hostName) throws IOException
{
if (!SystemUtils.IS_OS_WINDOWS)
{
return false;
}
File hostsFile = new File("C:\\Windows\\System32\\drivers\\etc\\hosts");
String hostsFileContents = FileUtils.readFileToString(hostsFile).toLowerCase();
return hostsFileContents.contains(hostName.toLowerCase());
}
}
Is there something else that should be checked or does this make no sense to even do? Java is definitely "fooled" by a redirect in this Windows hosts file and access my local web server instead:
127.0.0.1 example.com
When I try to connect our alfresco through SFTP it is not able to connect alfresco. It hangs the explorer and no error goes in the logger file also.
public void FTPTest()throws SocketException, IOException, NoSuchAlgorithmException
{
FTPSClient ftp = new FTPSClient("SSL");
System.out.println("1");
ftp.connect("172.17.178.144",2121); // or "localhost" in your case
System.out.println("2"+ftp.getReplyString());
System.out.println("login: "+ftp.login("admin", "admin"));
System.out.println("3"+ ftp.getReplyString());
ftp.changeWorkingDirectory("/alfresco");
// list the files of the current directory
FTPFile[] files = ftp.listFiles();
System.out.println("Listed "+files.length+" files.");
for(FTPFile file : files) {
System.out.println(file.getName());
}
// lets pretend there is a JPEG image in the present folder that we want to copy to the desktop (on a windows machine)
ftp.setFileType(FTPClient.BINARY_FILE_TYPE); // don't forget to change to binary mode! or you will have a scrambled image!
FileOutputStream br = new FileOutputStream("C:\\Documents and Settings\\casonkl\\Desktop\\my_downloaded_image_new_name.jpg");
ftp.retrieveFile("name_of_image_on_server.jpg", br);
ftp.disconnect();
}
I got output in our console only
1
at the execution of ftp.connect("172.17.178.144",2121); this code system will be hang no error got in our console
I am able to connect to my Alfresco through SFTP with the Filezila FTP client software. Can any one help me resolve this issue?
If I'm not mistaken then Alfresco chose for FTPS.
So try it with the following code here: http://alvinalexander.com/java/jwarehouse/commons-net-2.2/src/main/java/examples/ftp/FTPSExample.java.shtml
import com.jcraft.jsch.*;
import com.jcraft.jsch.JSchException;
import oracle.jdbc.driver.OracleDriver;
import java.io.*;
import java.util.*;
import java.sql.*;
import java.net.*;
public class SecureFTP {
public static void main(String[] args) throws IOException , ClassNotFoundException, JSchException, SftpException{
JSch jsch = new JSch();
File file = new File("/home/xxxxx/.ssh/id_rsa");
Session session = null;
URL keyFileURL = null;
URI keyFileURI = null;
if (file.exists())
{
keyFileURL = file.toURL();
if (keyFileURL == null)
{
System.out.println("what");
throw new RuntimeException("Key file not found in classpath");
}
}
else System.out.println("FIle not found");
try{
keyFileURI = keyFileURL.toURI();
}
catch(Exception URISyntaxException)
{
System.out.println("Wrong URL");
}
String privateKey = ".ssh/id_rsa";
//jsch.addIdentity(privateKey);
jsch.addIdentity(new File(keyFileURI).getAbsolutePath());
System.out.println(new File(keyFileURI).getAbsolutePath() + " LOL");
session = jsch.getSession("username", "servername");
//session.setPassword("password");
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
// connect
session.connect();
// get SFTP channel
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp schannel = (ChannelSftp) channel;
FileInputStream fis = new FileInputStream(sourcefile);
schannel.put(fis, destinationfile );
fis.close();
}
schannel.exit();
session.disconnect();
}
}
As you can see from the code I have commented out, I have tried everything possible to get this working and the only thing that works is if I set the password directly. I am trying to use the RSA private key generated, but I keep getting an auth fail.
I have added the public key to the list of authorized keys on the target server. And there is no passphrase.
Is there something else I am supposed to do? Like say, while generating the keys? Is there a step I am missing?
Is there another library I can use to implement the same function?
Make sure the necessary files exist (id_rsa and id_rsa.pub on the client, authorized_keys on the server). Make sure you can use public key authentication with another tool, like ssh, using these files.
If that looks alright, the problem may be with your Java security provider. Read on if you think you have the right files in place.
There are different formats for RSA private key storage, and SSH uses one that is not standard. Most providers expect something called a CRT RSA key, and when JSch doesn't give them a key in that format, they raise an exception which JSch silently eats and goes on to the next authentication method.
What is your provider? The following snippet will help you find out:
import java.security.KeyFactory;
…
KeyFactory f = KeyFactory.getInstance("RSA");
System.out.println(f.getProvider().getName());
Update: I did some checking around, and as of Java 5, the SunPKCS11 provider is installed with the highest precedence on Solaris systems, for performance. Since I don't run Solaris, I can't test it, but I believe this may be causing the problem.
JSch doesn't allow you to specify the provider to use for this operation through its API, so you will have to change the precedence of the installed providers. In fact, I'd suggest trying to remove the SunPKCS11 from this application; run this code once when your application starts up:
Security.removeProvider("SunPKCS11-Solaris");
Have you have copied the key into the file $HOME/.ssh/authorized_keys on the target server? If so, you should probably mention that. If not, that is required for this to work. Also, are you generating the key without a password? If the private key is password protected, you will need to provide that password to addIdentity.
After verifying those things, I'd recommend trying to connect via the command line using OpenSSH, as the Java code you have here looks correct. If the command line does not work, invoke it with -vvv to get verbose output about what it is doing. It is possible that the server is configured with PubkeyAuthentication set to no.
I use the library from apache.org and use the code from java2s.com:
import org.apache.commons.net.ftp.FTPClient;
import java.io.IOException;
import java.io.FileOutputStream;
public class Main {
public static void main(String[] args) {
FTPClient client = new FTPClient();
FileOutputStream fos = null;
client.connect("ftp.domain.com");
client.login("admin", "secret");
client.enterLocalPassiveMode();
String filename = "sitemap.xml";
fos = new FileOutputStream(filename);
client.retrieveFile("/" + filename, fos);
fos.close();
client.disconnect();
}
}
I downloaded the library, moved it to the lib folder and renamed it to cn.jar.
compiling: (under Windows 7)
javac -cp ".;lib\cn.jar" Main.java
running: (under Windows 7)
java -cp ".;lib\cn.jar" Main
and I've got: http://freelifer.narod.ru/some.png
How to fix it? What is wrong?
My guess: the FTP protocol defines two connections - a data connection and a control connection. Your sample code established the control connection successfully:
client.connect("ftp.domain.com");
client.login("admin", "secret");
The default constructor of FTPClient defines that the data connection should be established in active mode (meaning that the server will try to open a connection to your client when you request a file). I think that the data connection cannot be opened due to your firewall or some other network issue. The data connection is opened here:
client.retrieveFile("/" + filename, fos);
You may try passive mode or you may check your network settings again. Passive mode is entered by calling the enterLocalPassiveMode method of FTPClient. This method causes a PASV (or EPSV) command to be issued to the server. Example:
client.connect("ftp.domain.com");
client.login("admin", "secret");
client.enterLocalPassiveMode();
Cheers!