Done basic part on guacamole to allow a transport to be created on UDS

Now, it:
  * Allow register credentials from "trusted" sources (those knowing the secret ID of the server)
  * Access to remote desktop based on parameters registered with credentials
  * Return to the specified page on disconnection, if indicated.
  * Use of credentials just once, and forget them
  
With uds transport part, when done, people will have full desktop access using just html5 client over a browser.
This commit is contained in:
Adolfo Gómez 2013-03-04 01:51:15 +00:00
parent ec0e3c6dee
commit 12af8907a8
8 changed files with 191 additions and 58 deletions

View File

@ -0,0 +1,5 @@
In order to increase the security of the server, there will be a key, stored at /etc/uniqueid.cfg, that will be required in order to store
valid credentials for users.
The credentials for the user are 1 time used, so if connection is lost, there will be needed a full register-cred, connect to acces again to session.

View File

@ -0,0 +1,67 @@
package org.openuds.guacamole;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import org.openuds.guacamole.creds.Credentials;
public class CredentialsServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 8321644141165009209L;
private static final String UUID_ERROR = "ERROR: Invalid UUID";
private static final String PARAMS_ERROR = "ERROR: Invalid Credentials Parameters";
private static final String OK = "OK";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
processCredentials(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
processCredentials(req, resp);
}
private void processCredentials(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
String uuid = req.getParameter("uuid");
String cred = req.getParameter("credential");
String data = req.getParameter("data");
if( req.getParameter("test") != null && uuid != null ) {
if( Credentials.test(uuid) == false )
out.println(UUID_ERROR);
else
out.println(OK);
return;
}
if( uuid == null || cred == null || data == null ) {
out.println(PARAMS_ERROR);
return;
}
// Test url:
// /creds?uuid=f070f721-15ea-44a9-8df1-b9480991989c&credential=12345&data=protocol%09rdp%0ahostname%09w7adolfo%0ausername%09admin%0apassword%09temporal
if( Credentials.put(uuid, cred, data) == false )
out.println(UUID_ERROR);
else
out.println(OK);
}
}

View File

@ -34,24 +34,12 @@ public class TunnelServlet
if( data == null || width == null || height == null)
throw new GuacamoleException("Can't read required parameters");
HttpSession rSession = request.getSession();
Hashtable<String,String> params = Util.readParameters(data);
@SuppressWarnings("unchecked")
Hashtable<String,String> params = (Hashtable<String,String>)rSession.getAttribute(data);
// Parameters not owned by user session, get them from remote server
// (one time shot at other side, so they can't be retrieved again)
if( params == null ) {
try {
params = Util.readParameters(data);
rSession.setAttribute(data, params);
} catch(Exception e) {
throw new GuacamoleException("Getting broker data", e);
}
}
else
System.out.println("Params got from session");
if( params == null ) {
System.out.println("Invalid credentials");
throw new GuacamoleException("Can't access required user credentials");
}
GuacamoleClientInformation info = new GuacamoleClientInformation();
info.setOptimalScreenWidth(Integer.parseInt(width));

View File

@ -1,16 +1,19 @@
package org.openuds.guacamole;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Hashtable;
import org.openuds.guacamole.creds.Credentials;
public class Util {
//
public static Hashtable<String,String> readParameters(String data) {
//String url = unscramble(data);
//String params = getUrl(url);
//return parseParams(params);
return parseParams("protocol\trdp\nhostname\tw7adolfo\nusername\tadmin\npassword\ttemporal");
String params = Credentials.getAndRemove(data);
if( params == null )
return null;
return parseParams(params);
}
public static Hashtable<String,String> parseParams(String params)
@ -27,41 +30,4 @@ public class Util {
return res;
}
public static String unscramble(String in)
{
int len = in.length();
StringBuilder res = new StringBuilder(len/2);
int val = 0x32;
for( int i = 0; i < len; i += 2) {
String b = in.substring(i, i+2);
int c = Integer.parseInt(b, 16)^val;
val = (val + c) & 0xFF;
res.append((char)c);
}
return res.reverse().toString();
}
public static String getUrl(String url) {
try {
java.net.URL u = new java.net.URL(url);
BufferedReader in = new BufferedReader(new InputStreamReader(u.openStream()));
StringBuilder data = new StringBuilder();
String inputLine;
while ((inputLine = in.readLine()) != null) {
data.append(inputLine);
data.append("\n");
}
in.close();
return data.toString();
} catch(Exception e) {
System.out.println("Unable to get url. Network error? " + e.getMessage());
return null;
}
}
}

View File

@ -0,0 +1,45 @@
package org.openuds.guacamole.creds;
import java.util.LinkedHashMap;
public class Credentials {
private static CredentialsMap creds = new CredentialsMap();
public static boolean put(String uuid, String credential, String value) {
synchronized (creds) {
if( uuid.equals(creds.uniqueId) ) {
creds.put(credential, value);
return true;
}
return false;
}
}
public static String get(String credential) {
synchronized (creds) {
return creds.get(credential);
}
}
public static String getAndRemove(String credential) {
synchronized (creds) {
String cred = creds.get(credential);
creds.put(credential, null);
return cred;
}
}
public static boolean test(String uuid) {
synchronized (creds) {
if( uuid.equals(creds.uniqueId) )
return true;
return false;
}
}
}

View File

@ -0,0 +1,32 @@
package org.openuds.guacamole.creds;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.LinkedHashMap;
public class CredentialsMap extends LinkedHashMap<String, String> {
private static final int MAX_CREDENTIALS = 1024;
public String uniqueId;
public CredentialsMap() {
super(MAX_CREDENTIALS);
try {
FileInputStream fi = new FileInputStream("/etc/uniqueid.cfg");
DataInputStream in = new DataInputStream(fi);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
uniqueId = br.readLine();
in.close();
} catch(Exception e) {
uniqueId = null;
}
}
@Override
protected boolean removeEldestEntry(
java.util.Map.Entry<String, String> eldest) {
return size() >= MAX_CREDENTIALS;
}
}

View File

@ -20,9 +20,22 @@
</servlet-class>
</servlet>
<servlet>
<description>Credentials Servlet</description>
<servlet-name>Credentials</servlet-name>
<servlet-class>
org.openuds.guacamole.CredentialsServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Tunnel</servlet-name>
<url-pattern>/tunnel</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Credentials</servlet-name>
<url-pattern>/creds</url-pattern>
</servlet-mapping>
</web-app>

View File

@ -58,7 +58,18 @@
window.onload = function() {
window.setTimeout(function() {
// Get parameter information, so we can retrieve connecton data
var data = window.location.search.substr(1);
var params = window.location.search.substr(1);
var data = "";
var exitUrl = "";
var ioa = params.indexOf('&');
// URL is in the format ?XXXXXXXX&URL, where XXX is the id of the credential stored, and URL is the output URL
if( ioa != -1 ) {
data = params.substr(0,ioa);
exiturl = params.substr(ioa+1);
}
else {
data = params;
}
// Get display div from document
var display = document.getElementById("display");
@ -76,6 +87,12 @@
// Error handler
guac.onerror = function(error) {
alert(error);
window.location.assign(exiturl);
};
guac.onstatechange = function(state) {
if( state == 0 || state == 4 || state == 5 )
window.location.assign(exiturl);
};
var optimal_width = window.innerWidth;