/* * Created on 04-Oct-2004 * Created by Paul Gardner * Copyright (C) 2004, 2005, 2006 Aelitis, All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * AELITIS, SAS au capital de 46,603.30 euros * 8 Allee Lenotre, La Grille Royale, 78600 Le Mesnil le Roi, France. * */ package org.gudy.azureus2.core3.util.jar; import java.net.*; import java.io.*; import org.gudy.azureus2.core3.util.*; import org.gudy.azureus2.core3.config.COConfigurationManager; import org.gudy.azureus2.core3.logging.*; /** * @author parg * */ public class AEJarSigner2 { protected static Class JarSigner_class; protected String keystore_name; protected String keystore_password; protected String alias; public AEJarSigner2( String _alias, String _keystore_name, String _keystore_password ) { alias = _alias; keystore_name = _keystore_name; keystore_password = _keystore_password; } protected void loadJarSigner() throws IOException { File tools_dir; String manual_tools_dir = COConfigurationManager.getStringParameter( "Security.JAR.tools.dir" ); if ( manual_tools_dir.length() == 0 ){ String java_home = System.getProperty( "java.home" ); // if it ends in "jre" then go up one dir // then look for lib/tools.jar File jh = new File( java_home ); if ( jh.getName().equalsIgnoreCase("jre")){ jh = jh.getParentFile(); }else{ // otherwise, for 1.5, see if the JDK is also installed in default position String dir_name = jh.getName(); if ( dir_name.startsWith( "jre" )){ dir_name = "jdk" + dir_name.substring(3); jh = new File( jh.getParentFile(), dir_name ); } } tools_dir = new File( jh, "lib" ); }else{ tools_dir = new File( manual_tools_dir ); } File tools_jar = new File( tools_dir, "tools.jar" ); // System.out.println( "tools_jar = " + tools_jar.toString() + ", exists = " + tools_jar.exists()); if ( tools_jar.exists()){ try{ ClassLoader cl = new URLClassLoader(new URL[]{tools_jar.toURL()},AEJarSigner2.class.getClassLoader()); JarSigner_class = cl.loadClass( "sun.security.tools.JarSigner" ); }catch( Throwable e ){ Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Security.jar.signfail"), new String[] { e .getMessage() }); Debug.printStackTrace(e); throw( new IOException( "JAR signing fails: " + e.getMessage())); } }else{ Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Security.jar.tools_not_found"), new String[] { tools_dir.toString() }); throw( new IOException( "JAR signing fails: tools.jar not found" )); } } protected void signJarFile( File input_file ) throws IOException { if ( JarSigner_class == null ){ loadJarSigner(); } PrintStream old_err = null; PrintStream old_out = null; String failure_msg = null; try{ Object jar_signer = JarSigner_class.newInstance(); String[] args = { "-keystore", keystore_name, "-storepass", keystore_password, input_file.toString(), alias }; old_err = System.err; old_out = System.out; ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); System.setErr( ps ); System.setOut( ps ); try{ JarSigner_class.getMethod( "run", new Class[]{ String[].class }).invoke( jar_signer, new Object[]{ args }); }catch( Throwable e ){ ps.close(); String err_msg = baos.toString(); if ( err_msg.length() > 0 ){ failure_msg = err_msg; }else{ Debug.printStackTrace(e); failure_msg = e.getMessage(); } } }catch( Throwable e ){ Debug.printStackTrace(e); failure_msg = e.getMessage(); }finally{ if ( old_err != null ){ System.setErr( old_err ); System.setOut( old_out ); } } if ( failure_msg != null ){ Debug.out( "JAR signing fails '" + failure_msg + "'" ); Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_ERROR, "Security.jar.signfail"), new String[] { failure_msg }); throw( new IOException( "JAR signing fails: " + failure_msg )); } } public void signJarFile( File file, OutputStream os ) throws IOException { signJarFile( file ); FileInputStream fis = null; try{ fis = new FileInputStream( file ); FileUtil.copyFile( file, os, false ); }finally{ try{ if (fis != null) {fis.close();} }catch( Throwable e ){ Debug.printStackTrace(e); } } } public void signJarStream( InputStream is, OutputStream os ) throws IOException { File temp_file = AETemporaryFileHandler.createTempFile(); FileOutputStream fos = null; try{ byte[] buffer = new byte[8192]; fos = new FileOutputStream( temp_file ); while(true){ int len = is.read( buffer ); if ( len <= 0 ){ break; } fos.write( buffer, 0, len ); } fos.close(); fos = null; signJarFile( temp_file, os ); }finally{ try{ is.close(); }catch( Throwable e ){ Debug.printStackTrace( e ); } if ( fos != null ){ try{ fos.close(); }catch( Throwable e ){ Debug.printStackTrace( e ); } } temp_file.delete(); } } }