Tuesday, April 22

How to avoid CSRF - Cross Side Request Forgery attack






How to prevent CSRF using.

CSRF attack can be prevented using Synchronized Token Pattern.

When an HTML form is rendered ,server assigns it a unique and random identifier in the form of hidden http parameter. Server

Also stored the unique identifier in user session profile

When This form is submitted server compares the identifier's value in hidden field with value stored in user session profile . If value matches only then request is further processed otherwise request is aborted.

Thus if any evil website tries to submit a form with forging the client request information in that , it is not able to generate the unique identifier As
It does not know How to get it , It's not there on client cookie , it's not guessable . So attacker can't make CSRF attack.





For example : If a form named businessForm is rendered is follow ,server creates random token and form store that in hidden field. Also it's value is sotred
in user session

businessForm
">


CSRF_identifier">123#rret_val</>



When user submit this form token value is validated. Evil site can't steal this random number So that request will be rejected and CSRF attack will be prevented







CSRF - Cross Side Request Forgery





When you are accessing your bank website ,Why should you not open any other tab in same window with some unknown /evil application?

You might become s CSRF prey.

How does that happen ?

LEt's understand this with an simple example.

Let's say you open the browser and login to you bank website www.mybank.com with your username/password.

When you Do this bank might persist your authentication token in cookie. For eample : You login to the website using your username/password and bank website
,after successful authentication , stores in client cookie "isUserALreadyLoggenzIn"="true"







After this you open an evil website in new tab , may be by clicking on some link on some other page in the same window . Now that evil website might contain

a form like this



name="amonut" value="50000"

Win Lottery

On on page opened with evil website link you click on Win Lottery button. This click submits a request of money tranfer and money is transferred to some
other account without your knowledge. Application identifies the logged in your using cookie data and there "isUserLoggedIn" is already set to true So no problem comes in authentication.



This example is Just to cover the CRSF i.e. cross side request forgery . These days bank application and browsers are much more intellient to

defend against these evils .


Thursday, March 20

Configuring apache mod security -Mod Security rules configuration








Below are the detailed around Mod Security configuration on apache server. Please let me know If you need any further details on that .

1.       Add  below configuration  in httpd.conf file

LoadModule security2_module modules/mod_security2.so
LoadModule unique_id_module modules/mod_unique_id.so
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin

Include /etc/httpd/modsecurity_crs/*.conf
SecAuditEngine On
#SecFilterScanPOST On
SecAuditLog logs/audit_log

2.       mod_security2.so and mod_unique_id.so are modules that needs to be placed in apache modules folder

/etc/httpd/modsecurity_crs is the place where rules files exist .

We have placed below rule file at this location





Mod_security_rules.conf
--------------------------------------------------------------------------------------------------------------
SecDefaultAction  "phase:1,phase:2,auditlog,logdata:'%{MATCHED_VAR_NAME}=%{MATCHED_VAR}',deny,redirect:/errorpage.html"

SecRule ARGS_NAMES "!^(post-name_)+$" "id:'1000010'"

SecRule ARGS:post-name "!^[a-zA-Z0-9_]{0,4096}$" "id:'1000237'"
 -----------------------------------------------------------------------------------------

This configuration will allow only post-name attribute with alphanumeric and _ characters allowed in the value . Every other request parameter will be rejected and user will be redirected to errorpage.html

Logs captured by mod security can be viewed in  logs/audit_log file. 


3.       I have created simple Form with GET and POST request on apache server

<html>
<body>
<h1>GET!! Test Apache Redirection</h1>
<form name='f1' method="GET" action="/getService">
Enter Your Name : <input type="text" name="name" value=""/>
<input type="submit" id="Go" value="GET Submit"/>
</form>
 
 
<h1>POST !! Test Apache Redirection</h1>
<form name='f2' method="POST" action="/postService">
Enter Your Name : <input type="text" name="post-name" value=""/>
<input type="submit" id="submit" value="Post Submit"/>
</form>
</body>
</html>

4.       So in above form through GET request we are submitting form with request attribute name and through post request attribute is post-name.


post-name will pass  and name will fail as name is not configured as allowed parameter in mod security rules configuration file.





Wednesday, March 19

Grizzly jax-ws file upload service and client






Server Side code : 


Below file start the Grizzly server and register the uploadService class as jax-ws web service 


package com.sap;

import com.sun.grizzly.http.embed.GrizzlyWebServer;

import java.io.IOException;

import javax.xml.ws.Endpoint;
import javax.xml.ws.spi.http.HttpContext;

import org.jvnet.jax_ws_commons.transport.grizzly_httpspi.GrizzlyHttpContextFactory;

public class JaxwsMain {

    /**
     * @param args
     */
    public static void main(String[] args) {
        
        String contextPath = "/ws";
        String path = "/test";
        int port = 8081;

        String address = "http://localhost:"+port+contextPath+path;

        GrizzlyWebServer server = new GrizzlyWebServer(port);
        HttpContext context = GrizzlyHttpContextFactory.createHttpContext(server, contextPath, path);

        Endpoint endpoint = Endpoint.create(new UploadService());
        //endpoint.create(new UploadService());
        endpoint.publish(context); 
     
        try {
            server.start();
            
            System.out.println(12121);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        
   
        
    }

}








below is uploadService class that basically upload the file 


package com.sap;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.xml.ws.WebServiceException;

@WebService
public class UploadService {
  /*  @WebMethod
    public int up(@WebParam(name="value1") int value1, @WebParam(name="value2") int value2) {
        return value1 + value2;
    }
  */  
    @WebMethod
public void upload(String fileName, byte[] imageBytes) {
     
    String filePath = "D:/desktops/12march2014/uploads/" + fileName;
     
    try {
        FileOutputStream fos = new FileOutputStream(filePath);
        BufferedOutputStream outputStream = new BufferedOutputStream(fos);
        outputStream.write(imageBytes);
        outputStream.close();
         
        System.out.println("Received file: " + filePath);
         
    } catch (IOException ex) {
        System.err.println(ex);
        throw new WebServiceException(ex);
    }
}


    
}



run JaxwsMain Java class as java application . That will register the uploadService on Grizzly server\



use wsimport jax-ws utility from command line to generate the Client artifacts in Client project 

This will create below files 



  • ObjectFactory.java
  • package-info.java
  • Upload.java
  • UploadResponse.java
  • UploadService.java
  • UploadServiceService.java 






below the Client code file that will invoke the upload service


Execute this File and pass the file to be uploaded


package com.sa;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
import java.util.logging.FileHandler;

import javax.xml.ws.WebServiceRef;
import javax.xml.ws.soap.MTOMFeature;

public class JaxwsClient {

   

    /**
     * @param args
     */
    public static void main(String[] args) {
        JaxwsClient client =new JaxwsClient();
        client.doTest(args);

    }
    
    public void doTest(String[] args) {
        
        UploadServiceService service = new UploadServiceService();
    UploadService port = service.getPort(UploadService.class, new MTOMFeature(10240));

    String fileName = "tpd-alert-1.2.0.zip";
    String filePath = "D:/desktops/12march2014/" + fileName;
    File file = new File(filePath);
    
    if (args.length >0 && null != args[0]) {
        file = new File(args[0]);
    } else {
        
        System.out.println("Enter full path of file..");

        String path;

        Scanner scanIn = new Scanner(System.in);
        path = scanIn.nextLine();

        file = new File(path);

    }

    try {
        filePath=file.getPath();
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream inputStream = new BufferedInputStream(fis);
        byte[] imageBytes = new byte[(int) file.length()];
        inputStream.read(imageBytes);

        port.upload(file.getName(), imageBytes);
        inputStream.close();
        System.out.println("File uploaded: " + filePath);
    } catch (IOException ex) {
        System.err.println(ex);
    }}

}


Done!!!

Composition versus aggregation Java Code example



Aggregation


Read comments in Test class to understand the scenario / Code flow


package com.sam;

 class Car {
    Engine engine;

    public Car() {

        engine = Engine.getEngineInstance();

    }

    Engine getEngine() {
        return this.engine;
    }

}

class Engine {

    private Engine() {

    }

    public static Engine getEngineInstance() {

        return new Engine();
    }

    public void performAction(String str ) {

        System.out.println("Performed.."+str);
    }
}

public class Test {

    public static void main(String args[]) {

        Engine engine = Engine.getEngineInstance(); // can ncreate Engine instance ,
        // Engine can exist on its own ,
        // It can exist even without car instance
       
        engine.performAction("With Out Car Instance");

        Car car = new Car(); // Car class has dependency on ENgine class to perform Action
                             // But Engine Class instance can be created and used even without
                             // creating Car class instance

        car.getEngine().performAction("With Car Instance");

    }
}








composition


Read comments in Test class to understand the scenario / Code flow


package com.sam;
class Car {
    Engine engine;

    public Car() {

        engine = new Engine();

    }

    Engine getEngine() {
        return this.engine;
    }

    class Engine {

        private Engine() {

        }

        public Engine getEngineInstance() {

            return new Engine();
        }

        public void performAction(String str) {

            System.out.println("Performed.." + str);
        }
    }

}

public class Test {

    public static void main(String args[]) {

        Engine engine = Engine.getEngineInstance(); // compilation error / can not create Engine instance ,
        // Engine can not exist on its own ,
        // It can exist only with car instance

        engine.performAction("With Out Car Instance");

        Car car = new Car(); // Car class has dependency on ENgine class to perform Action
                             // SO Engine Class instance can be created only with
                             //  Car class instance

        car.getEngine().performAction("With Car Instance");

    }
}






Monday, March 17

File upload Jersey Grizzly example




1. Below class is required to startup the grizzly embedded container

package com.example;

import org.glassfish.grizzly.http.server.HttpServer;
importorg.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

import java.io.IOException;
import java.net.URI;

/**
 * Main class.
 *
 */
public class Main {
    // Base URI the Grizzly HTTP server will listen on
    public static final String BASE_URI = "http://localhost:8080/myapp/";

    /**
     * Starts Grizzly HTTP server exposing JAX-RS resources defined in this application.
     * @return Grizzly HTTP server.
     */
    public static HttpServer startServer() {
        // create a resource config that scans for JAX-RS resources and providers
        // in com.example package
        final ResourceConfig rc = new ResourceConfig().packages("com.example");

        // create and start a new instance of grizzly http server
        // exposing the Jersey application at BASE_URI
        return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
    }

    /**
     * Main method.
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        final HttpServer server = startServer();
        System.out.println(String.format("Jersey app started with WADL available at "
                + "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
        System.in.read();
        server.stop();
    }
}


As highlighted in above code this Main class will register all the web service classes lying under com.example package . SO Let us create our upload service in example package 


 import com.sun.jersey.multipart.FormDataParam;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
    
    @Path("/files")
    public class JerseyFileUpload {
    
        @POST
        @Path("/upload/{filename}")
        @Consumes(MediaType.MULTIPART_FORM_DATA)
        @Produces(MediaType.TEXT_PLAIN)
        public Response uploadFile(
            @FormDataParam("file") InputStream uploadedInputStream ,@PathParam("filename") String fileName)
{
    
            System.out.println("fileName"+fileName);
           // String uploadedFileLocation = "c://uploadedFiles/" + "fileDetail.getFileName()";
            String uploadedFileLocation = "D:/desktops/12march2014/uploads/"+fileName;
            // save it
            saveToFile(uploadedInputStream, uploadedFileLocation);
    
            String output = "File uploaded via Jersey based RESTFul Webservice to: " + uploadedFileLocation;
    
            return Response.status(200).entity(output).build();
    
        }
    
        // save uploaded file to new location
        private void saveToFile(InputStream uploadedInputStream,
            String uploadedFileLocation) {

    
            try {
                OutputStream out = null;
                int read = 0;
                byte[] bytes = new byte[1024];
    
                out = new FileOutputStream(new File(uploadedFileLocation));
                while ((read = uploadedInputStream.read(bytes)) != -1) {
                    out.write(bytes, 0, read);
                }
                out.flush();
                out.close();
            } catch (IOException e) {
    
                e.printStackTrace();
            }
    
        }
    
    }


That was server side Code. Execute the Main.java class as java application. It will start up the Grizzly server and JerseyUpload service will be up and running.


-->



Now Lets write Client Code to call this service :

package com.sapient;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Scanner;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;

public class JerseyClient {

    /**
     * @param args
     */
    public static void main(String[] args) {
        File file = new File("C:/Users/mkum63/Downloads/spring-framework-2.5-with-dependencies.zip");

        if (args.length >0 && null != args[0]) {
            file = new File(args[0]);
        } else {
           
            System.out.println("Enter full path of file..");

            String path;

            Scanner scanIn = new Scanner(System.in);
            path = scanIn.nextLine();

            file = new File(path);

        }
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost =
                new HttpPost("http://localhost:8080/myapp/files/upload/" + file.getName());
        FileBody fileContent = new FileBody(file);
        try {
            StringBody comment = new StringBody("Filename: " + file.getName());
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        MultipartEntity reqEntity = new MultipartEntity();
        reqEntity.addPart("file", fileContent);
        httppost.setEntity(reqEntity);
        HttpResponse response = null;
        try {
            response = httpclient.execute(httppost);
            System.out.println(response.getStatusLine().getStatusCode() == 200 ? "successful" : "Failed");
            // System.out.println(response.getStatusLine().getStatusCode());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        HttpEntity resEntity = response.getEntity();

    }

}


This is the client .Execute this class as java application and supply the full path of the file to be uploaded. 

You can keep your server files and client files on different machines. 









Monday, March 3

Reading Content from a PDF file






How to extract content from a PDF file in java

Here I am extreacting last 200 characters of a PDF file.



import java.io.File;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.util.PDFTextStripper;

public class PDFReader {

    /**
     * @param args
     */
    public static void main(String[] args) {

        {
            try
            {
            PDDocument pddDocument=PDDocument.load(new File("C:/Users/mkum63/Desktop/vit-strategic-growth-inst-sp.pdf"));
           System.out.println(pddDocument.getNumberOfPages());
           PDFTextStripper textStripper=new PDFTextStripper();
          String text=textStripper.getText(pddDocument);
          //System.out.println(textStripper.getEndPage());
           System.out.println(text.subSequence(text.length()-200, text.length()));
            pddDocument.close();
            }
            catch(Exception ex)
            {
            ex.printStackTrace();
            }
            }
    }

}

Jar files required :

commons-logging-api-1.1.1
fontbox-1.2.1
pdfbox-1.3.1









JCR SQL2 Query to exclude a path

JCR Query to select data from one parent path and at the same time exculding a child path




For example

I want to select all nt:unstructured PDF nodes under en folder except nodes falling under investor-resource folder









     select * from [nt:unstructured] as p
            where
               (isdescendantnode (p, [/content/dam/gsam/pdfs/us/en/])
               AND NOT isdescendantnode (p, [/content/dam/gsam/pdfs/us/en/investor-resources]))
                         and contains(p.*, 'application/pdf')



Sunday, March 2

Jersey web service + File Upload + Maven + Tomcat +Java + Rest Web service









------------------------------------------------------------------------------------------

package com.gs.gsam.lo.du;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;

// Plain old Java Object it does not extend as class or implements
// an interface

// The class registers its methods for the HTTP GET request using the @GET annotation.
// Using the @Produces annotation, it defines that it can deliver several MIME types,
// text, XML and HTML.

// The browser requests per default the HTML MIME type.

//Sets the path to base URL + /hello
@Path("/upload")
public class DocumentUploader {

    /*
     * // @Produces(MediaType.TEXT_HTML)
     *
     * @GET public String sayHtmlHello() { return " " + " " + "Hello Jerse y  " + "" + "

"
     * + "Hello Jersey" + "

" + " "; }
     */
    @POST
    @Path("/pdf")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response uploadFile(@FormDataParam("file") File file) {
        InputStream IS = null;;
        String uploadedFileLocation = "d://" + "Test.zip";

        try {
            IS = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {

        }

        // save it
        writeToFile(IS, uploadedFileLocation);

        String output = "The PDF File uploaded to : " + uploadedFileLocation;

        return Response.status(200).entity(output).build();

    }

    // save uploaded file to new location
    private void writeToFile(InputStream uploadedInputStream, String uploadedFileLocation) {
        OutputStream out = null;
        try {
            out = new FileOutputStream(new File(uploadedFileLocation));
            int read = 0;
            byte[] bytes = new byte[1024];

            out = new FileOutputStream(new File(uploadedFileLocation));
            while ((read = uploadedInputStream.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }
            out.flush();
            out.close();
            uploadedInputStream.close();
        } catch (IOException e) {

            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();

                }
                if (uploadedInputStream != null) {
                    uploadedInputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

}

-------------------------------------------------------------------------

package com.gs.gsam.lo.client;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.ws.rs.core.MediaType;

public class ClientJ {

  public static void main(String[] args) throws IOException {

      InputStream is=null;
  try {

    Client client = Client.create();

    WebResource webResource = client
       .resource("http://localhost:8080/FileUpload-0.0.1-SNAPSHOT/rest/upload/pdf");

    InputStream IS = null;;

    File file =new File("D:/file/file.zip");
   
    String uploadedFileLocation = "d://" + "Test.zip";

    try {
        IS = new FileInputStream(file);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {

    }

    // save it
    writeToFile(IS, uploadedFileLocation);

    String output = "The PDF File uploaded to : " + uploadedFileLocation;
   
    // is=new FileInputStream(file);
   /* ClientResponse response = webResource.type(MediaType.MULTIPART_FORM_DATA)
       .post(ClientResponse.class,file );

    if (response.getStatus() != 200) {
      throw new RuntimeException("Failed : HTTP error code : "
           + response.getStatus());
    }

    System.out.println("Output from Server .... \n");
    String output = response.getEntity(String.class);
    System.out.println(output);

 */   System.exit(0);
    } catch (Exception e) {

    e.printStackTrace();

    }finally{
        if(null!=is){
            is.close();
        }
    }

  }
 
//save uploaded file to new location
  private static  void writeToFile(InputStream uploadedInputStream, String uploadedFileLocation) {
      OutputStream out = null;
      try {
          out = new FileOutputStream(new File(uploadedFileLocation));
          int read = 0;
          byte[] bytes = new byte[1024];

          out = new FileOutputStream(new File(uploadedFileLocation));
          while ((read = uploadedInputStream.read(bytes)) != -1) {
              out.write(bytes, 0, read);
          }
          out.flush();
          out.close();
          uploadedInputStream.close();
      } catch (IOException e) {

          e.printStackTrace();
      } finally {
          try {
              if (out != null) {
                  out.close();

              }
              if (uploadedInputStream != null) {
                  uploadedInputStream.close();
              }
          } catch (IOException e) {
              e.printStackTrace();
          }
      }

  }

}

Friday, February 21

Heuristic exceptions






Heuristic exceptions are inconsistent exceptions . These exceptions does not come all the time and May occur suddenly due to some unavoidable condition 







For example You are calling a service to do some transaction on database and data-source configuration is missing . This happened because last time server got restarted Data-source configuration is removed . So this can be restored by setting the configuration right. 

For example in distributed system multiple parties taking part in a two phase commit transaction are waiting for transaction manager to get information If all of them should commit their individual transaction or not. Transaction manager took lot of time to response and Participant committed their individual transaction even before that . There could come a situation where some participants commit their transaction while others don't and they rollback it if transaction manager sends information to rollback. Thus in distributed system data becomes highly inconsistent .
You put some message in JMS queue But all of a sudden Queue connection breaks and you fail you get any proper response .

Such kind of strange and inconsistent exception falls under heuristic exceptions.


-->

Thursday, February 20

Creating a zip file in java

Creating a zip file in java 




Converting a String into a test file and putting that in zip file 


  1. Here I am creating File.zip file at location D:/file.zip
  2. Here two text files are using by reading an existing txt file
  3. One Pdf file is created by reading an existing file
  4. One txt file is created from a String 
  5. All are zipped together and are put in zip file 




import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


public class Zipper {
    
    public static void main( String[] args )
    {
      byte[] buffer = new byte[1024];

      try{

        FileOutputStream fos = new FileOutputStream("D:\\File.zip");
        ZipOutputStream zos = new ZipOutputStream(fos);
        ZipEntry ze= new ZipEntry("spy.txt");
        zos.putNextEntry(ze);
        FileInputStream in = new FileInputStream("D:\\spy.txt");

        int len;
        while ((len = in.read(buffer)) > 0) {
          zos.write(buffer, 0, len);
        }

        in.close();
        
        ZipEntry ze1= new ZipEntry("spy1.txt");
        zos.putNextEntry(ze1);
        FileInputStream in1 = new FileInputStream("D:\\spy.txt");

        int len1;
        while ((len1 = in1.read(buffer)) > 0) {
          zos.write(buffer, 0, len1);
        }

        in1.close();
        
        ZipEntry ze2= new ZipEntry("Promote PDF.pdf");
        zos.putNextEntry(ze2);
        FileInputStream in2 = new FileInputStream("C:/Users/mkum63/Desktop/Promote PDF.pdf");

        int len2;
        while ((len2 = in2.read(buffer)) > 0) {
          zos.write(buffer, 0, len2);
        }

        in.close();
        
        
        ZipEntry ze4= new ZipEntry("spy4.txt");
        zos.putNextEntry(ze4);
        StringBuilder sb=new StringBuilder();
        sb.append("dfdgfdgf");
        sb.append("\n");
        sb.append("dsfsdfs");
        sb.append("/n");
        sb.append("dsfsfsdfdffdf");

        InputStream  in4 = new ByteArrayInputStream(sb.toString().getBytes());
                
        int len4;
        while ((len4 = in4.read(buffer))>0) {
          zos.write(buffer, 0, len4);
        }
          
        in4.close();
        
        zos.closeEntry();

        zos.close();

        System.out.println("Done");

      }catch(IOException ex){
         ex.printStackTrace();
      }
    }
}