Реализация стандартного шлюза Cisco на BeanShell c управлением по telnet
Материал из BiTel WiKi
Стандартный шлюз cisco, в котором управление по ssh подменено управлением по telnet
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 ); } } } } }