• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Paul Clapham
  • Devaka Cooray
  • Tim Cooke
Sheriffs:
  • Rob Spoor
  • Liutauras Vilda
  • paul wheaton
Saloon Keepers:
  • Tim Holloway
  • Tim Moores
  • Mikalai Zaikin
  • Carey Brown
  • Piet Souris
Bartenders:
  • Stephan van Hulst

Can you execute CGI From a Servlet?

 
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a commercial cgi program (read as blackbox) which, for security reasons, I cannot expose directly to web users.
What I want to do is receive the request for the program and reroute it to a servlet which would perform authorization checking on the user. If the user is authorized then the java servlet would execute the cgi program directly and return the output to the user.
A call to the cgi program using Runtime.exec(program) doesn't work because the cgi program needs to be running in the web server environment.
I can accomplish what I want by running a batch file (this on Windows2K) as a cgi and then running the cgi program from the batch file but this an inelegant solution.
Any ideas? Thanks a bunch!
[ December 06, 2002: Message edited by: Brian Podolny ]
 
Author and all-around good cowpoke
Posts: 13078
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
How much of the server environment does the CGI really need? You might be able to fake it using the form of exec that includes environment string values.
Bill
 
Ranch Hand
Posts: 672
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You can hide your CGI in a protected area and have a servlet to call it. I think in your servlet you need to use URL class to do this.
 
Brian Podolny
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
William,
Unfortunately, I can't just pass the environment variables to the commercial CGI program directly because the company that wrote it won't reveal what information it requires.
Bruce,
Could you elaborate a little more on what you mean by a protected area and what you would be using the URL class for?
Thanks to both of you for your help.
[ December 06, 2002: Message edited by: Brian Podolny ]
 
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You could try this:
I found some code on:
http://www.webdeveloper.com/java/java_jj_read_write.html .
Combining that with a servlet, I was able to call a script that prints out the junk from the CGI environment (local Apache httpd w/ Perl).
Your idea sparked my interest and I can use it.
Here is the doGet() from my servlet CGIHandler.
Hope this helps.
-Randy
*************************************
public void doGet(
javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws javax.servlet.ServletException, java.io.IOException
{
boolean isValid = false;
//get theCgiUrl from Request URL or just set it to a static dest.
String theCgiUrl = "http://localhost/cgi-bin/printenv.pl";
String errorUrl = "http://127.0.0.1/"; //probably a local JSP like cgiError.jsp or something

ServletContext ctx = getServletContext();

//do some authorization, I will just set to true
isValid = true;

URL myUrl = null;
if(isValid)
{
myUrl = new URL(theCgiUrl);
}
else // isValid == false <=> not authorized
{
myUrl = new URL(errorUrl);
}
//log which URK
ctx.log(this.getClass().getName() + " -> using URL: " + myUrl);
//capture the URL's ctxtent
URLConnection conn = myUrl.openConnection();
conn.connect();
ctx.log(this.getClass().getName() + " -> connected..." );
//now get the content into a buffer.
DataInputStream data = null;
String line;
String content = "";
StringBuffer buf = new StringBuffer();
data = new DataInputStream(new BufferedInputStream(conn.getInputStream()));
while ((line = data.readLine()) != null)
{
buf.append(line + "\n");
content += line;
}
data.close();
//print it out
PrintWriter out = response.getWriter();
out.print(content);
}//end doGet()
 
Bruce Jin
Ranch Hand
Posts: 672
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Because you don�t want your CGI to be accessed by browser directly you have to put it in a location that can�t be seen by browser. See <security-constraint> tag in web.xml file.
URL class can be used to retrieve resource from web. You can use it to get response from your CGI and resend that response to browser.
I have not done this myself. Just guess this might be one of the ways to do it.
Thanks.
 
Brian Podolny
Ranch Hand
Posts: 32
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sorry if this sounds a bit lame-brained but if the CGI has been placed in a directory that is not directly accessible via the webserver then how is a URL, even a local one, going to resolve to CGI program which, if I understand your suggestion correctly, is not accessible via direct URL.
 
Bruce Jin
Ranch Hand
Posts: 672
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Brian:
I tried hard and I could not find a way to implement what I proposed above. Sorry.
Another thing to try is to add a simple interface to the CGI so that it can be called from an application rather than browser and have it output to some other stream instead of the browser. For example I added the following code to a servlet (servlet is just a special CGI) then this servlet can be called from an application (even from command line) and output to a file.
public static void main(String[] str) {

ServeltA aa = new ServletA();

try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(�out.txt�)));
aa.start(out,sapplnp, satype);
out.close();
} catch(IOException e){
System.err.println( e);
}

}
}
 
Randy Motluck
Greenhorn
Posts: 10
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In my example, I called a Perl CGI script on my own computer. I think your answer is the setup in the machine. You could restrict access to the web server that hosts your CGI. If you restrict it such that the only requests it answers are the ones coming from your machine where the Java app server runs, you are done. You just need to make sure the Servlet has the security you desire.
This would work for a GET Method. The Servlet can pick up the form data from the URL and pass it along. I did not try this for any POST method forms, but I would imagine that you could just rip off the encoded arguments and shoot them over the socket to the CGI server.
-Randy
-Randy
 
Mo-om! You're embarassing me! Can you just read a tiny ad like a normal person?
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic