Реализация стандартного шлюза Cisco на BeanShell c управлением по telnet
Материал из BiTel WiKi
Стандартный шлюз cisco, в котором управление по ssh подменено управлением по telnet
package bitel.billing.test.ipn;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import bitel.billing.common.module.ipn.CiscoRuleOptions; import bitel.billing.common.module.ipn.IPNContractStatus; import bitel.billing.server.ipn.GateWorker; import bitel.billing.server.ipn.UserStatus; import bitel.billing.server.ipn.bean.AclOptions; import bitel.billing.server.ipn.bean.ManadUtils; import bitel.billing.server.util.DefaultServerSetup; import bitel.billing.server.util.Utils; import bitel.billing.server.util.telnet.TelnetSession;
doSync()
{
host = gate.getHost();
port = gate.getPort();
gid = gate.getId();
gateSetup = new DefaultServerSetup( gate.getConfig(), "\r\n" );
login = gateSetup.getStringValue( "login", "root" );
pswd = gate.getKeyword();
if( log.isDebugEnabled() )
{
log.debug( gid + " gate: " + host + ":" + port + " login: " + login + " pswd: " + pswd );
}
//SSHSession session = null;
session = null;
try
{
session = new TelnetSession( host, port );
session.setLoginPromptSequence( ":" );
System.out.println( "before connect" );
session.connect();
System.out.println( "after connect" );
System.out.println( session.doCommand( login ) );
session.setLoginPromptSequence( "#" );
session.doCommand( pswd );
session.doCommand( "terminal length 0" );
result = new StringBuffer();
list = ( session.doCommand( "show access-list" ) );
result.append( list );
if( log.isDebugEnabled() )
{
log.debug( gid +" AccessList taking.." );
log.debug( result );
}
// код ACL - стуктура с описанием
aclMap = AclOptions.getAclMapById( gateSetup );
// имя ACL - стуктура с описанием
aclByNameMap = new HashMap();
for( AclOptions option : aclMap.values() )
{
aclByNameMap.put( option.name, option );
}
result.append( session.doCommand( "configure terminal" ) );
// проход по ACL списку с отметкой какие договора открыты
markOpenFromRules( list, aclByNameMap );
// подготовка списка корректирующих команд
buildCommandsLists( aclMap );
for( AclOptions options : aclMap.values() )
{
if( options.commands.size() > 0 )
{
// TODO: extended или нет - надо смотреть в конфиге
result.append( session.doCommand( "ip access-list extended " + options.name ) );
if( log.isDebugEnabled() )
{
log.debug( gid + " ACL " + options.name );
}
for( String command : options.commands )
{
if( log.isDebugEnabled() )
{
log.debug( gid + " " + command );
}
result.append( session.doCommand( command ) );
}
}
}
//выход из configure
result.append( session.doCommand( "exit" ) );
session.doCommandAsync( "exit" );
if (log.isDebugEnabled())
{
log.debug( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
log.debug( result.toString() );
log.debug( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
}
// пауза пока считает команду exit
Thread.sleep( 100 );
}
catch ( Exception e )
{
throw new RuntimeException ( e );
}
finally
{
if( session != null )
{
session.disconnect();
}
}
}
buildCommandsLists( aclMap )
{
for( status : statusList )
{
ruleOptions = CiscoRuleOptions.extractParams( status.rule.getRuleText() );
options = aclMap.get( ruleOptions.aclId );
// флаг того то правило есть на шлюзе
flag = false;
// правило для этого договора есть на шлюзе
if ( options.openRulesFrom.containsKey( ruleOptions.fromPos ) )
{
// если правило есть а юзер заблокирован - удаляем правило
if ( status.status > 0 )
{
if( options != null )
{
rules = options.openRulesFrom.get( ruleOptions.fromPos );
if( rules != null )
{
for( int rule : rules )
{
options.commands.add( "no " + rule );
}
}
}
}
flag = true;
options.openRulesFrom.remove( ruleOptions.fromPos );
}
// правила нет, а юзер открыт - добавляем правило
if ( !flag &&
status.status == IPNContractStatus.STATUS_OPEN )
{
rule = CiscoRuleOptions.clearFromParams( status.rule.getRuleText() );
acl = aclMap.get( ruleOptions.aclId );
if( acl != null )
{
// типизированное правило
if( status.ruleType != null )
{
String ruleText = ManadUtils.getRule( status.gateType, status.ruleType );
rule = ManadUtils.generateRule( ruleText, rule, null, status.ruleType );
//ipPattern = Pattern.compile( "access list\\s+([\\w\\-]+)" );
}
int rulePos = ruleOptions.fromPos;
StringTokenizer st = new StringTokenizer( rule, "\r\n" );
while( st.hasMoreTokens() )
{
String line = st.nextToken().trim();
acl.commands.add( (rulePos++) + " " + line );
}
}
}
}
}
markOpenFromRules( String result, aclByNameMap )
{
gid = gate.getId();
line = null;
currentAclOptions = null;
st = new StringTokenizer( result, "\r\n" );
accessPattern = Pattern.compile( "access list\\s+([\\w\\-]+)" );
rulePattern = Pattern.compile( "^(\\d+)\\s+((permit)|(deny))" );
while( st.hasMoreTokens() )
{
line = st.nextToken().trim();
m = accessPattern.matcher( line );
if( m.find() )
{
currentAcl = m.group( 1 );
currentAclOptions = aclByNameMap.get( currentAcl );
if( log.isDebugEnabled() )
{
log.debug( gid + " ACL " + currentAcl + " not in billing control.." );
}
continue;
}
if( currentAclOptions == null )
{
continue;
}
m = rulePattern.matcher( line );
if( m.find() )
{
rule = Utils.parseIntString( m.group( 1 ) );
if( rule < currentAclOptions.fromPos ||
rule > currentAclOptions.toPos )
{
if( log.isDebugEnabled() )
{
log.debug( gid + " Skip rule " + line );
}
}
else
{
ruleFrom =
((rule - currentAclOptions.fromPos) / currentAclOptions.onContact) * currentAclOptions.onContact
+ currentAclOptions.fromPos;
rules = currentAclOptions.openRulesFrom.get( ruleFrom );
if( rules == null )
{
rules = new HashSet();
currentAclOptions.openRulesFrom.put( ruleFrom, rules );
}
rules.add( rule );
if( log.isDebugEnabled() )
{
log.debug( gid + " Contact open from rule: " + ruleFrom );
}
}
}
}
}
