📄 sesecuritymanagerimpl.java
字号:
/*
* File : SECertificateHandlerImpl.java
* Created : 29-Dec-2003
* By : parg
*
* Azureus - a Java Bittorrent client
*
* 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.
*
* 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 ( see the LICENSE file ).
*
* 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
*/
package org.gudy.azureus2.core3.security.impl;
/**
* @author parg
*
*/
import java.util.*;
import java.net.*;
import java.io.*;
import javax.net.ssl.*;
import java.security.*;
import java.security.cert.*;
import java.security.cert.Certificate;
import org.gudy.azureus2.core3.config.COConfigurationManager;
import org.gudy.azureus2.core3.logging.*;
import org.gudy.azureus2.core3.security.*;
import org.gudy.azureus2.core3.util.*;
import com.aelitis.azureus.core.util.CopyOnWriteList;
public class
SESecurityManagerImpl
{
private static final LogIDs LOGID = LogIDs.NET;
protected static SESecurityManagerImpl singleton = new SESecurityManagerImpl();
protected static String KEYSTORE_TYPE;
static{
String[] types = { "JKS", "GKR" };
for (int i=0;i<types.length;i++){
try{
KeyStore.getInstance( types[i] );
KEYSTORE_TYPE = types[i];
break;
}catch( Throwable e ){
}
}
if ( KEYSTORE_TYPE == null ){
// it'll fail later but we need to use something here
KEYSTORE_TYPE = "JKS";
}
Logger.log( new LogEvent(LOGID, "Keystore type is " + KEYSTORE_TYPE ));
}
protected String keystore_name;
protected String truststore_name;
protected List certificate_listeners = new ArrayList();
protected CopyOnWriteList password_listeners = new CopyOnWriteList();
protected Map password_handlers = new HashMap();
protected boolean exit_vm_permitted = false;
protected AEMonitor this_mon = new AEMonitor( "SESecurityManager" );
public static SESecurityManagerImpl
getSingleton()
{
return( singleton );
}
public void
initialise()
{
// keytool -genkey -keystore %home%\.keystore -keypass changeit -storepass changeit -keyalg rsa -alias azureus
// keytool -export -keystore %home%\.keystore -keypass changeit -storepass changeit -alias azureus -file azureus.cer
// keytool -import -keystore %home%\.certs -alias azureus -file azureus.cer
// debug SSL with -Djavax.net.debug=ssl
keystore_name = FileUtil.getUserFile(SESecurityManager.SSL_KEYS).getAbsolutePath();
truststore_name = FileUtil.getUserFile(SESecurityManager.SSL_CERTS).getAbsolutePath();
System.setProperty( "javax.net.ssl.trustStore", truststore_name );
System.setProperty( "javax.net.ssl.trustStorePassword", SESecurityManager.SSL_PASSWORD );
installAuthenticator();
String[] providers = { "com.sun.net.ssl.internal.ssl.Provider", "org.metastatic.jessie.provider.Jessie" };
String provider = null;
for (int i=0;i<providers.length;i++){
try{
Class.forName(providers[i]).newInstance();
provider = providers[i];
break;
}catch( Throwable e ){
}
}
if ( provider == null ){
Debug.out( "No SSL provider available" );
}
try{
SESecurityManagerBC.initialise();
}catch( Throwable e ){
Logger.log(new LogEvent(LOGID, LogEvent.LT_ERROR,
"Bouncy Castle not available"));
}
installSecurityManager();
ensureStoreExists( keystore_name );
ensureStoreExists( truststore_name );
/*
try{
Certificate c = createSelfSignedCertificate( "Dummy", "CN=fred,OU=wap,O=wip,L=here,ST=there,C=GB", 512 );
addCertToTrustStore( "SomeAlias", c);
addCertToTrustStore( null, null );
}catch( Throwable e ){
Debug.printStackTrace(e);
}
/*
try{
Certificate c = createSelfSignedCertificate( "SomeAlias", "CN=fred,OU=wap,O=wip,L=here,ST=there,C=GB", 1000 );
addCertToTrustStore( "SomeAlias", c);
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
*/
}
public String
getKeystoreName()
{
return( keystore_name );
}
public String
getKeystorePassword()
{
return( SESecurityManager.SSL_PASSWORD );
}
protected void
installSecurityManager()
{
String prop = System.getProperty( "azureus.security.manager.install", "1" );
if ( prop.equals( "0" )){
Debug.outNoStack( "Not installing security manager - disabled by system property" );
return;
}
try{
final SecurityManager old_sec_man = System.getSecurityManager();
System.setSecurityManager(
new SecurityManager()
{
public void
checkExit(int status)
{
if ( old_sec_man != null ){
old_sec_man.checkExit( status );
}
if ( !exit_vm_permitted ){
throw( new SecurityException( "VM exit operation prohibited"));
}
}
public void
checkPermission(Permission perm)
{
if ( perm instanceof RuntimePermission && perm.getName().equals( "stopThread")){
throw( new SecurityException( "Thread.stop operation prohibited"));
}
if ( old_sec_man != null ){
old_sec_man.checkPermission( perm );
}
}
public void
checkPermission(
Permission perm,
Object context)
{
if ( perm instanceof RuntimePermission && perm.getName().equals( "stopThread")){
throw( new SecurityException( "Thread.stop operation prohibited"));
}
if ( old_sec_man != null ){
old_sec_man.checkPermission( perm, context );
}
}
});
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
public void
exitVM(
int status )
{
try{
exit_vm_permitted = true;
try{
System.exit( status );
}
catch( Throwable t ){}
}finally{
exit_vm_permitted = false;
}
}
public void
installAuthenticator()
{
Authenticator.setDefault(
new Authenticator()
{
protected AEMonitor auth_mon = new AEMonitor( "SESecurityManager:auth");
protected PasswordAuthentication
getPasswordAuthentication()
{
try{
auth_mon.enter();
PasswordAuthentication res =
getAuthentication(
getRequestingPrompt(),
getRequestingProtocol(),
getRequestingHost(),
getRequestingPort());
/*
System.out.println( "Authenticator:getPasswordAuth: res = " + res );
if ( res != null ){
System.out.println( " user = '" + res.getUserName() + "', pw = '" + new String(res.getPassword()) + "'" );
}
*/
return( res );
}finally{
auth_mon.exit();
}
}
});
}
public PasswordAuthentication
getAuthentication(
String realm,
String protocol,
String host,
int port )
{
// special case for socks auth when user is explicitly "<none>" as some servers seem to cause
// a password prompt when no auth defined and java doesn't cache a successful blank response
// thus causing repetitive prompts
if ( protocol.toLowerCase().startsWith( "socks" )){
String socks_user = COConfigurationManager.getStringParameter( "Proxy.Username" ).trim();
String socks_pw = COConfigurationManager.getStringParameter( "Proxy.Password" ).trim();
if ( socks_user.equalsIgnoreCase( "<none>" )){
return( new PasswordAuthentication( "", "".toCharArray()));
}
// actually getting all sorts of problems with Java not caching socks passwords
// properly so I've abandoned prompting for them and always use the defined
// password
if ( socks_user.length() == 0 ){
Logger.log(
new LogAlert(false, LogAlert.AT_WARNING, "Socks server is requesting authentication, please setup user and password in config" ));
}
return( new PasswordAuthentication( socks_user, socks_pw.toCharArray()));
}
try{
URL tracker_url = new URL( protocol + "://" + host + ":" + port + "/" );
return( getPasswordAuthentication( realm, tracker_url ));
}catch( MalformedURLException e ){
Debug.printStackTrace( e );
return( null );
}
}
protected boolean
checkKeyStoreHasEntry()
{
File f = new File(keystore_name);
if ( !f.exists()){
Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE,
LogAlert.AT_ERROR, "Security.keystore.empty"),
new String[] { keystore_name });
return( false );
}
try{
KeyStore key_store = loadKeyStore();
Enumeration enumx = key_store.aliases();
if ( !enumx.hasMoreElements()){
Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE,
LogAlert.AT_ERROR, "Security.keystore.empty"),
new String[] { keystore_name });
return( false );
}
}catch( Throwable e ){
Logger.logTextResource(new LogAlert(LogAlert.UNREPEATABLE,
LogAlert.AT_ERROR, "Security.keystore.corrupt"),
new String[] { keystore_name });
return( false );
}
return( true );
}
protected boolean
ensureStoreExists(
String name )
{
try{
this_mon.enter();
KeyStore keystore = KeyStore.getInstance( KEYSTORE_TYPE );
if ( !new File(name).exists()){
keystore.load(null,null);
FileOutputStream out = null;
try{
out = new FileOutputStream(name);
keystore.store(out, SESecurityManager.SSL_PASSWORD.toCharArray());
}finally{
if ( out != null ){
out.close();
}
}
return( true );
}else{
return( false );
}
}catch( Throwable e ){
Debug.printStackTrace(e);
return( false );
}finally{
this_mon.exit();
}
}
public KeyStore
getKeyStore()
throws Exception
{
return( loadKeyStore());
}
public KeyStore
getTrustStore()
throws Exception
{
KeyStore keystore = KeyStore.getInstance( KEYSTORE_TYPE );
if ( !new File(truststore_name).exists()){
keystore.load(null,null);
}else{
FileInputStream in = null;
try{
in = new FileInputStream(truststore_name);
keystore.load(in, SESecurityManager.SSL_PASSWORD.toCharArray());
}finally{
if ( in != null ){
in.close();
}
}
}
return( keystore );
}
protected KeyStore
loadKeyStore()
throws Exception
{
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
return( loadKeyStore( keyManagerFactory ));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -