Java SFTP (apache vfs2) - password with # - java

I'm trying to use the org.apache.commons.vfs2 to download a file via SFTP.
The problem is, the password contains the '#' char, so this causes the URI to be parsed incorrectly:
org.apache.commons.vfs2.FileSystemException: Expecting / to follow the hostname in URI
Does anyone has an idea how to get around this issue? (I can't change the password, obviously). This is the code I'm using:
String sftpUri = "sftp://" + userName + ":" + password + "#"
+ remoteServerAddress + "/" + remoteDirectory + fileName;
String filepath = localDirectory + fileName;
File file = new File(filepath);
FileObject localFile = manager.resolveFile(file.getAbsolutePath());
FileObject remoteFile = manager.resolveFile(sftpUri, opts);
localFile.copyFrom(remoteFile, Selectors.SELECT_SELF);

Use an actual URI constructor instead of hand-rolling your own:
String userInfo = userName + ":" + password;
String path = remoteDirectory + filename; // Need a '/' between them?
URI sftpUri = new URI("sftp", userInfo, remoteServerAddress, -1, path, null, null);
...
FileObject remoteFile = manager.resolveFile(sftpUri.toString(), opts);

You need to encode the your password by UriParser.encode(), you can change your code like below:
you code:
String sftpUri = "sftp://" + userName + ":" + password + "#"
+ remoteServerAddress + "/" + remoteDirectory + fileName;
change to:
String sftpUri = "sftp://" + userName + ":" + **UriParser.encode(password, "#".toCharArray())**+ "#"
+ remoteServerAddress + "/" + remoteDirectory + fileName;
Hope it help, thank you.

Related

setting s3 bucket policy while PutObject

public String getPolicy() throws Exception {
String policy_document = "{\"expiration\": \"2020-01-01T00:00:00Z\",\n" +
" \"conditions\": [ \n" +
" {\"bucket\": \"bucket\"}, \n" +
" [\"starts-with\", \"$Content-Type\", \"image/\"],\n" +
" [\"content-length-range\", 0, 100]\n" +
" ]\n" +
"}";
String aws_secret_key = "xxxxx";
String policy = (new BASE64Encoder()).encode(policy_document.getBytes("UTF-8"))
.replaceAll("\n", "").replaceAll("\r", "");
Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(new SecretKeySpec(
aws_secret_key.getBytes("UTF-8"), "HmacSHA1"));
String signature = (new BASE64Encoder()).encode(
hmac.doFinal(policy.getBytes("UTF-8")))
.replaceAll("\n", "");
return policy;
}
While uploading -
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setHeader("policy", getPolicy());
s3Client.putObject(bucket, key, inputStream, objectMetadata);
Can we pass policy header like above to reject s3 putObject requests that violate policy conditions ?
I think it is possible via s3Client.setBucketPolicy but is there a way to set these policies for each put request ?

Cannot write correctly a link inside an .json file

I have a Dynamic Web Project + Maven deployed on WebSphere 8.5 with java 1.6 and I'm using the following library in the pom.xml:
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
I get the environment's url and I'm trying to write it on a .json file.
Here is the code:
InetAddress ip;
try {
ip = InetAddress.getLocalHost();
ip.getHostAddress();
JSONObject obj = new JSONObject();
obj.put("name", "https:" + File.separatorChar + File.separatorChar + ip.getHostAddress() + ":443"
+ File.separatorChar + "authorizer" + File.separatorChar);
obj.put("debugging", "true");
FileWriter file = new FileWriter(ctx.getServletContext().getRealPath("/") + "/assets/conf.json");
file.write(obj.toJSONString());
file.flush();
file.close();
} catch (UnknownHostException e) {
e.printStackTrace();
}
Well it works, but I get this on conf.json:
{"name":"https:\/\/126.0.0.0:443\/authorizer\/","debugging":"true"}
As you see, it is not formatted but when I have tested it on Windows just worked fine.
The thing is when I deployed on WebSphere I got the url wrong and the problem It's on the way of the forward slash. How can I write the url correctly?
I have tried already with File.separator, or simply writing "/" or "\\" but neither worked.
Don't use File.separator to construct URLs, simply use /. The path-separator for URLs is the same regardless of the OS. File.separator is different depending on the OS (Windows is \, most other OSs are /). I rewrote a portion of your code to demo the construction of the URL. Notice when you get the URL from the Json object, it is formatted properly (see the line: System.out.println("the URL recovered from Json:...). The output from that line looks like:
the URL recovered from Json: https://127.0.1.1:443/authorizer/
public static void main(String... args) throws Exception {
InetAddress ip;
ip = InetAddress.getLocalHost();
ip.getHostAddress();
String url0 = "https:" + File.separatorChar + File.separatorChar + ip.getHostAddress() + ":443"
+ File.separatorChar + "authorizer" + File.separatorChar;
String url1 = "https:" + "//" + ip.getHostAddress() + ":443"
+ "/" + "authorizer" + "/";
JSONObject obj = new JSONObject();
obj.put("name", url0);
obj.put("debugging", "true");
System.out.println("the URL recovered from Json: " + obj.get("name"));
System.out.println("json: " + obj.toJSONString());
System.out.println("this url will be different than what you want on Windows:\n" + url0);
System.out.println("this is what you want, it will be the same on all OSs:\n" + url1);
}
It appears that Json allows / to be escaped, but does not require it. So escaping the / is not incorrect, just unnecessary in your case. See: JSON: why are forward slashes escaped?

Constant 401 error with OAuth1 (MCM API)

I've been trying to establish a connection with an API for more than a week now, to no avail. (Magic Card Market's, authentification documentation here and there). I'm supposed to receive a XML file.
I have what MCM call a "widget" access to their API, meaning that I don't have nor need a oauth_token (it's supposed to be an empty string) for the authorization header, and that I'm not supposed to receive nor use an access token/access secret.
The only things I do have are a consumer key (they call it app token sometimes) and a consumer secret.
Here is how I build my Authorization header :
private static String buildOAuthAuthorization(String method, String request)
throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
String mkmAppToken = APICredentials.appToken;
String mkmAppSecret = APICredentials.appSecret;
String realm = "https://www.mkmapi.eu/ws/v1.1/games";
String oauthVersion = "1.0";
String oauthConsumerKey = mkmAppToken;
String oauthToken = "";
String oauthSignatureMethod = "HMAC-SHA1";
String oauthTimestamp = Long.toString(System.currentTimeMillis() / 1000);
String oauthNonce = Long.toString(System.currentTimeMillis());
String paramString = "oauth_consumer_key=" + oauthConsumerKey
+ "oauth_nonce=" + oauthNonce
+ "oauth_signature_method=" + oauthSignatureMethod
+ "oauth_timestamp=" + oauthTimestamp
+ "oauth_token=" + oauthToken
+ "oauth_version=" + oauthVersion;
String baseString = method + "&" + rawUrlEncode(realm) + "&" + rawUrlEncode(paramString);
String signingKey = rawUrlEncode(mkmAppSecret) + "&";
Mac mac = Mac.getInstance("HMAC-SHA1");
SecretKeySpec secret = new SecretKeySpec(signingKey.getBytes(), mac.getAlgorithm());
mac.init(secret);
byte[] digest = mac.doFinal(baseString.getBytes());
byte[] oauthSignature = Base64.encode(digest, Base64.URL_SAFE);
String authorizationProperty = "OAuth "
+ "realm=\"" + realm + "\", "
+ "oauth_version=\"" + oauthVersion + "\", "
+ "oauth_timestamp=\"" + oauthTimestamp + "\", "
+ "oauth_nonce=\"" + oauthNonce + "\", "
+ "oauth_consumer_key=\"" + oauthConsumerKey + "\", "
+ "oauth_token=\""+ oauthToken + "\", "
+ "oauth_signature_method=\"" + oauthSignatureMethod + "\", "
+ "oauth_signature=\"" + oauthSignature + "\"";
System.out.println(authorizationProperty);
return authorizationProperty;
}
The actual request is in an AsyncTask :
public static class oAuthRequest extends AsyncTask<String, Integer, StringReader> {
private int lastCode;
#Override
protected StringReader doInBackground(String... requestURLs) {
String method = requestURLs[0];
String url = requestURLs[1];
StringReader result = null;
try {
String authProperty = buildOAuthAuthorization(method, url);
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.addRequestProperty("Authorization:", authProperty);
lastCode = connection.getResponseCode();
System.out.println("RESPONSE CODE 1 " + lastCode);
// Get content
BufferedReader rd = new BufferedReader(new InputStreamReader(lastCode == 200 ? connection.getInputStream() : connection.getErrorStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
result = new StringReader(sb.toString());
} catch (NoSuchAlgorithmException | InvalidKeyException | IOException e) {
e.printStackTrace();
}
return result;
}
}
It seems like no matter what I change, I'm always getting a 401.
Things I've tried :
oauthSignature as a String using Base64.encodeToString()
Nonce generation using SecureRandom
With and without the empty oauthToken
Another timestamp generation method (can't remember what though)
signing key with and without app token (theorically I need only the consumer secret, but you never know)
Using HttpsURLConnection instead of HttpURLConnection (the URI start in https, so I thought, hey. But no)
At least 2-3 other different implementations (one who was basically a copy/paste of the Java example in the documentation of course -- it still kind of is one now)
(Probably a lot of things I can't even remember)
At this point I'm wondering if maybe the issue comes from my keys, as I've tried to use the Postman app to test requests with the same results.

Java, URL output different in java output

I have a question about URI and URL
when i pass a url is work good but result is worst need help!!
as my code look like this.
import java.io.*;
import java.net.*;
import java.net.URL;
public class isms {
public static void main(String[] args) throws Exception {
try {
String user = new String ("boo");
String pass = new String ("boo");
String dstno = new String("60164038811"); //You are going compose a message to this destination number.
String msg = new String("你的哈达哈达!"); //Your message over here
int type = 2; //for unicode change to 2, normal will the 1.
String sendid = new String("isms"); //Malaysia does not support sender id yet.
// Send data
URI myUrl = new URI("http://www.isms.com.my/isms_send.php?un=" + user + "&pwd=" + pass
+ "&dstno=" + dstno + "&msg=" + msg + "&type=" + type + "&sendid=" + sendid);
URL url = new URL(myUrl.toASCIIString());
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
// Get the response
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
// Print the response output...
System.out.println(line);
}
rd.close();
System.out.println(url);
} catch (Exception e) {
e.printStackTrace();
}
}
}
the output in web is different..
on my java output is
你的哈达哈达!
but on my the site is
ÄãµÄ¹þ´ï¹þ´ï!
Help!!
String user = new String ("boo");
You don't need to (and shouldn't) do new String in Java—String user = "boo"; is fine.
String msg = new String("你的哈达哈达!");
Writing non-ASCII characters in your source means that you have to get the -encoding flag to javac to match the encoding you have saved your text files with. It is possible you have saved the .java file as UTF-8 but not configured your build environment to use UTF-8 at compile time.
If you are not sure that you've got this right, you can use ASCII-safe \u escapes in the meantime:
String msg = "\u4F60\u7684\u54C8\u8FBE\u54C8\u8FBE!"; // 你的哈达哈达!
Finally:
URI myUrl = new URI("http://www.isms.com.my/isms_send.php?un=" + user + "&pwd=" + pass
+ "&dstno=" + dstno + "&msg=" + msg + "&type=" + type + "&sendid=" + sendid);
When you're putting a URI together you should URL-escape each of the parameters you include in the string. Otherwise any & or other invalid character in the value will break the query. This also allows you to choose what charset is used to create the query string.
String enc = "UTF-8";
URI myUrl = new URI("http://www.isms.com.my/isms_send.php?" +
"un=" + URLEncoder.encode(user, enc) +
"&pwd=" + URLEncoder.encode(pass, enc) +
"&dstno=" + URLEncoder.encode(dstno, enc) +
"&msg=" + URLEncoder.encode(msg, enc) +
"&type=" + URLEncoder.encode(Integer.toString(type), enc) +
"&sendid=" + URLEncoder.encode(sendid, enc)
);
What the right value for enc is depends on the service you are connecting to, but UTF-8 is a good guess.

URL manipulation

I want to do a little manipulation with URLs.
It is required to add a sub domain in already created URL like shown below
Inputs
String inputURL = "http://www.myhost.com";
String subdomain = "newlocation";
output
String output = "http://www.newlocation.myhost.com";
I was thinking if there is any existing utility class that can do this for me. expert can have something to say.
Thanks for your help !
Note that "www" is also subdomain. So you are actually appending another subdomain.
String inputURL = "http://www.myhost.com";
String subdomain = "newlocation";
URL url = new URL(inputURL);
String[] domainParts = url.getHost().split("\\.");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < domainParts.length; i ++) {
if (i == 1) {
sb.append(subdomain + ".");
}
sb.append(domainParts[i] + ".");
}
String query = "";
String port = "";
if (url.getQuery() != null) {
query = "?" + url.getQuery();
}
if (url.getPort() != -1) {
port = url.getPort() + "";
}
String output = url.getProtocol() + ":" + port + "//" + sb.toString() + "/" + url.getPath() + query;
System.out.println(output);
It is sufficient to parse only the host part of the URL and use the URI to render.
URL url = new URL(inputURL);
String host = url.getHost().replaceAll("(([.][^.]+){2,2})$", "." + subdomain + "$1");
String newUrl = new URI(url.getProtocol(), host, url.getPath(), url.getQuery(), null).toString();
Perhaps:
String output = inputURL.replaceAll("(http://[^.]+\\.)(.*)", "$1" + subdomain + ".$2");
Look at StringBuffer (Link to the Java API doc) and then you will probably need to use one of the insert() methods

Categories