expect4r 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 46b8625696193f9bb771295b2241b1d883ad31c7
4
+ data.tar.gz: aea806dc760988161a7fe2dfaa31de9930e4af35
5
+ SHA512:
6
+ metadata.gz: 524998e2c125d35b21b53a5ca329b6bf74f4a293289469f0d9d8d99ae5bbcc7622b29d220cd9f6e7d4fff221ff4d51ba3bb524c9024503cfcbb2df6059a4067b
7
+ data.tar.gz: 421532f69db8e08bd329901d82080206ce1ce8c75181fa5012db558e047dc1aea29a0d4dc9c666db54083ef340935a79b6a7bc88cb14b6fcfe5fe10159fc8051
data/lib/expect/io.rb CHANGED
@@ -151,13 +151,21 @@ module Expect4r
151
151
  raise
152
152
  end
153
153
 
154
- def interact(k="C-z")
155
- k.upcase!
156
- raise unless k =~ /C\-[A-Z]/
154
+ def interact(k="C-t")
155
+ raise unless k =~ /C\-[A-Z]/i
156
+ unless STDOUT.tty? and STDIN.tty?
157
+ $stderr.puts "Cannot interact: not running from terminal!"
158
+ return
159
+ end
157
160
  login unless connected?
158
- STDOUT.puts "\n\#\n\# #{k.gsub(/C\-/,'^')} to terminate.\n\#\n"
159
- reader :start
160
- writer(eval "?\\#{k}")
161
+ @@interact_mutex ||= Mutex.new
162
+
163
+ @@interact_mutex.synchronize {
164
+ k.upcase!
165
+ STDOUT.puts "\n\#\n\# #{k.gsub(/C\-/,'^')} to terminate.\n\#\n"
166
+ reader :start
167
+ writer(eval "?\\#{k}")
168
+ }
161
169
  rescue
162
170
  ensure
163
171
  begin
@@ -239,6 +247,13 @@ module Expect4r
239
247
  ''
240
248
  end
241
249
 
250
+ def read_until(match,ti=0.2)
251
+ ret = expect(match, ti, [])
252
+ ret[0][0].chomp
253
+ rescue ExpTimeoutError => ex
254
+ ''
255
+ end
256
+
242
257
  def connected?
243
258
  @r && (not child_exited?)
244
259
  end
@@ -271,6 +286,19 @@ module Expect4r
271
286
  exp_internal "readbuf: _io_exit?"
272
287
  throw :done, [ :cnx_error, read_pipe._io_buf1]
273
288
  end
289
+
290
+ @pre_matches ||= []
291
+ @pre_matches.each do |match, _send|
292
+ if read_pipe._io_string =~ match
293
+ read_pipe._io_save no_echo, "match #{match}"
294
+ if _send.is_a?(Proc)
295
+ _send.call
296
+ else
297
+ exp_puts _send.to_s
298
+ end
299
+ end
300
+ end
301
+
274
302
  case read_pipe._io_string
275
303
  when spawnee_prompt
276
304
  read_pipe._io_save no_echo, "match PROMPT"
data/lib/misc/base.rb CHANGED
@@ -5,7 +5,7 @@ module Expect4r
5
5
  class << self
6
6
  attr_reader :routers
7
7
  def all
8
- @arr
8
+ @arr || []
9
9
  end
10
10
  def add(r)
11
11
  @arr ||=[]
@@ -49,41 +49,95 @@ module Expect4r
49
49
  # Adds a login to a Expect4r::BaseLoginObject"
50
50
  #
51
51
  # Constructor:
52
- # * <tt>new</tt> <method>, <username>, <password>, [port_number]
52
+ # * <tt>new</tt> <method>, <username>, <password>, <enable_password>, <port>
53
+ # * <tt>new</tt> <method>, <username>, <password>, <enable_password>
54
+ # * <tt>new</tt> <method>, <username>, <password>, <port>
55
+ # * <tt>new</tt> <method>, <username>, <password>
56
+ #
53
57
  # * <tt>new</tt> <method>, options={}
54
58
  #
55
59
  # Options are:
56
60
  # * <tt>:host</tt> or <tt>:hostname</tt>
57
61
  # * <tt>:user</tt> or <tt>:username</tt>
58
62
  # * <tt>:pwd</tt> or <tt>:password</tt>
63
+ # * <tt>:enable_password</tt>
64
+ # * <tt>:port</tt>
59
65
  #
60
66
  # Examples:
61
- # new :telnet, :host=> '1.1.1.1', :user=> 'lab', :password=>'lab'
67
+ #
68
+ # new :telnet, :host=> '1.1.1.1',
69
+ # :user=> 'lab',
70
+ # :password=>'lab',
71
+ # :enable_password=>'secret',
72
+ # :port=>2001
73
+ #
62
74
  # new :ssh, :host=> '1.1.1.1', :user=> 'jme'
63
- # new :ssh, '1.1.1.1', 'me', 'secret'
75
+ # new :telnet, '1.1.1.1', 'jme', 'myPwd', 'myEnablePwd', 2001
64
76
  #
77
+ #
78
+
79
+ =begin rdoc
80
+
81
+ @method, host, @user, pwd, enable_pwd, port = args
82
+ @method, host, @user, pwd, enable_pwd = args
83
+ @method, host, @user, pwd, port = args
84
+ @method, host, @user, pwd = args
85
+
86
+ @method, host+port, @user, pwd, enable_pwd = args
87
+ @method, host+port, @user, pwd = args
88
+
89
+ =end
90
+
65
91
  def initialize(*args)
66
- ciphered_password=nil
92
+ host, _pwd, _enable_pwd, ciphered_password=[nil]*5
67
93
  if args.size>2 and args[1].is_a?(String)
68
- @method, host, @user, pwd = args
69
- @host, port = host.split
70
- @port = (port || 0).to_i
94
+ case args.size
95
+ when 6
96
+ @method, host, @user, _pwd, _enable_pwd, port = args
97
+ when 5
98
+ if args.last.is_a?(Fixnum)
99
+ @method, host, @user, _pwd, port = args
100
+ else
101
+ @method, host, @user, _pwd, _enable_pwd = args
102
+ end
103
+ else
104
+ @method, host, @user, _pwd, port = args
105
+ end
106
+
107
+ raise ArgumentError if host.split.size>1 and port
108
+
109
+ @host, _port = host.split
110
+ @port = port || (_port || 0).to_i
111
+
71
112
  elsif args.size == 2 and args[1].is_a?(Hash) and args[0].is_a?(Symbol)
72
113
  @method = args[0]
73
114
  @host = args[1][:host] || args[1][:hostname]
74
115
  port = args[1][:port]
75
116
  @port = (port || 0).to_i
76
117
  @user = args[1][:user]|| args[1][:username]
77
- pwd = args[1][:pwd] || args[1][:password]
118
+
119
+ _pwd = args[1][:pwd] || args[1][:password]
78
120
  ciphered_password = args[1][:ciphered_password]
121
+
122
+ _enable_pwd = args[1][:enable_password]
123
+ ciphered_enable_password = args[1][:ciphered_enable_password]
124
+
79
125
  else
80
126
  raise
81
127
  end
128
+
82
129
  @pwd = if ciphered_password
83
130
  ciphered_password
84
131
  else
85
- Expect4r.cipher(pwd) if pwd
132
+ Expect4r.cipher(_pwd) if _pwd
86
133
  end
134
+
135
+ @enable_pwd = if ciphered_enable_password
136
+ ciphered_enable_password
137
+ else
138
+ Expect4r.cipher(_enable_pwd || _pwd) if _enable_pwd || _pwd
139
+ end
140
+
87
141
  @ps1 = /(.*)(>|#|\$)\s*$/
88
142
  @more = / --More-- /
89
143
  @matches=Set.new
@@ -92,6 +146,7 @@ module Expect4r
92
146
  end
93
147
 
94
148
  attr_writer :host, :username, :port
149
+ alias :hostname= :host=
95
150
 
96
151
  def method=(arg)
97
152
  case arg
@@ -102,7 +157,6 @@ module Expect4r
102
157
  end
103
158
  end
104
159
 
105
-
106
160
  def spawnee
107
161
  case method
108
162
  when :telnet ; "telnet #{host} #{port if port>0}"
@@ -128,51 +182,41 @@ module Expect4r
128
182
  end
129
183
  end
130
184
 
185
+ def password
186
+ @pwd
187
+ end
188
+
189
+ def enable_password
190
+ @enable_pwd
191
+ end
192
+
193
+ def cmp(o)
194
+ o.spawnee == spawnee and o.password == password and o.enable_password == enable_password
195
+ end
196
+
131
197
  private
132
198
 
133
199
  def spawnee_password
134
- if @pwd.nil?
135
- @pwd = Expect4r.cipher( ask("(#{self}) Enter your password: ") { |q| q.echo = "X" } )
136
- @asked4pwd=true
137
- end
138
- Expect4r.decipher(@pwd)
200
+ @pwd ||= Expect4r.cipher( ask("(#{self}) Enter your password: ") { |q| q.echo = "X" } )
201
+ Expect4r.decipher(password)
202
+ end
203
+
204
+ def spawnee_enable_password
205
+ @enable_pwd ||= Expect4r.cipher( ask("(#{self}) Enter your enable password: ") { |q| q.echo = "X" } )
206
+ Expect4r.decipher(enable_password)
139
207
  end
140
208
 
141
209
  def spawnee_reset
142
- @pwd=nil if @asked4pwd
210
+ @pwd=nil
211
+ @enable_pwd=nil
143
212
  end
144
213
 
145
214
  end
146
215
  end
147
216
 
148
- if __FILE__ != $0
149
-
150
- at_exit {
151
- if Expect4r::Base.all
152
- Expect4r::Base.all.each { |o| o.logout if o.respond_to? :logout }
153
- end
154
- }
155
-
156
- else
157
-
158
- require "test/unit"
159
-
160
- class Expect4r::Base
161
- def initialize
162
- Expect4r::Base.add(self)
163
- end
217
+ at_exit {
218
+ if Expect4r::Base.all
219
+ Expect4r::Base.all.each { |o| o.logout if o.respond_to? :logout }
164
220
  end
221
+ }
165
222
 
166
- class Base < Test::Unit::TestCase
167
- include Expect4r
168
-
169
- def test_add
170
- assert [], Base.all
171
- Base.new
172
- assert 1, Base.all.size
173
- Base.new
174
- assert_equal 2, Base.all.size
175
- end
176
- end
177
-
178
- end
@@ -42,6 +42,43 @@ module CiscoCommon
42
42
  super
43
43
  end
44
44
  end
45
+
46
+ def enable
47
+ proc = Proc.new {
48
+ puts "FOUND WE HAVE A BAD PASSWORD SITUATION"
49
+ }
50
+ @pre_matches ||= []
51
+ @pre_matches << [/Bad Password/i, proc]
52
+
53
+ enable_pwd = [/^Password: $/, spawnee_enable_password]
54
+ @matches << enable_pwd
55
+ exp_send 'enable'
56
+ @matches =[]
57
+ @pre_matches=[]
58
+ exec "term len 0\nterm width 0"
59
+ rescue
60
+ raise
61
+ ensure
62
+ @matches.delete enable_pwd
63
+ end
64
+
65
+ def login(arg={})
66
+ # Skip the default banner.
67
+ proc = Proc.new {
68
+ read_until /QUICK START GUIDE/, 2
69
+ }
70
+ @pre_matches = []
71
+ @pre_matches << [/Cisco Configuration Professional/, proc]
72
+
73
+ super(spawnee,arg)
74
+ enable unless arg[:no_enable]
75
+
76
+ self
77
+ end
78
+ # FIXME: 1.9.2 bug:
79
+ # It calls LoginBaseOject#login() instead of calling J#login()
80
+ # modified login_by_proxy to call _login_ seems to work.
81
+ alias :_login_ :login
45
82
 
46
83
  end
47
84
  end
@@ -16,39 +16,11 @@ class Expect4r::Ios < ::Expect4r::BaseLoginObject
16
16
  @ps1 = /(.*)(>|#|\$)\s*$/
17
17
  @more = / --More-- /
18
18
  end
19
-
20
- def enable
21
- @enable_password ||= @pwd
22
- enable_pwd = [/^Password: $/, enable_password]
23
- @matches << enable_pwd
24
- exp_send 'enable'
25
- rescue
26
- raise
27
- ensure
28
- @matches.delete enable_pwd
29
- end
30
-
31
- def enable_password
32
- return unless @pwd || @enable_password
33
- @enable_password ||= @pwd # FIXME
34
- Expect4r.decipher(@pwd) # password is ciphered ...
35
- end
36
-
37
- def login(arg={})
38
- super(spawnee,arg)
39
- enable
40
- exec "term len 0\nterm width 0"
41
- self
42
- end
43
- # FIXME: 1.9.2 bug:
44
- # It calls LoginBaseOject#login() instead of calling J#login()
45
- # modified login_by_proxy to call _login_ seems to work.
46
- alias :_login_ :login
47
-
48
-
19
+
49
20
  def putline(line,*args)
50
21
  output, rc = super
51
22
  return output unless error?(output)
23
+ raise BadPasswordError.new(self.class.to_s,line) if output =~ /Bad password/
52
24
  raise SyntaxError.new(self.class.to_s,line)
53
25
  end
54
26
 
@@ -70,5 +42,32 @@ class Expect4r::Ios < ::Expect4r::BaseLoginObject
70
42
  string_start_with_pct_char?(output[-2]) ||
71
43
  string_start_with_pct_char?(output[-3])
72
44
  end
45
+
46
+ def method_missing(name, *args, &block)
47
+ if name.to_s =~ /^show_/
48
+ filters=[]
49
+ if args.last.is_a?(Hash)
50
+ _begin = args.last.delete(:begin)
51
+ _section = args.last.delete(:section)
52
+ _count = args.last.delete(:count)
53
+ _exclude = args.last.delete(:exclude)
54
+ _include = args.last.delete(:include)
55
+ filters << "| begin #{_begin}" if _begin
56
+ filters << "| count #{_count}" if _count
57
+ filters << "| section #{_section}" if _section
58
+ filters << "| exclude #{_exclude}" if _exclude
59
+ filters << "| include #{_include}" if _include
60
+ end
61
+ cmd = name.to_s.split('_').join(' ')
62
+ cmd += " " + filters.join(' ') if filters
63
+ cmd.gsub!(/running config/, 'running-config')
64
+ output = __send__ :exec, cmd, *args
65
+ elsif name.to_s =~ /^shell_/
66
+ cmd = name.to_s.split('_')[1..-1].join(' ') + args.join(' ')
67
+ output = __send__ :shell, cmd, *args
68
+ else
69
+ super
70
+ end
71
+ end
73
72
 
74
73
  end
data/lib/router/error.rb CHANGED
@@ -16,6 +16,12 @@ module Error
16
16
  end
17
17
  end
18
18
 
19
+ class BadPasswordError < RouterError
20
+ def err_msg
21
+ "#{@rname} [BadPassword] : #{@msg}"
22
+ end
23
+ end
24
+
19
25
  class SemanticError < RouterError
20
26
  def err_msg
21
27
  "#{@rname} [SemanticError] : #{@msg}"
@@ -0,0 +1,87 @@
1
+ require "test/unit"
2
+ require "misc/base"
3
+
4
+
5
+ require "test/unit"
6
+
7
+ class Base < Test::Unit::TestCase
8
+ include Expect4r
9
+
10
+ def test_add
11
+ assert_equal( [], Base.all)
12
+ Base.new
13
+ assert_equal( 1, Base.all.size)
14
+ Base.new
15
+ assert_equal( 2, Base.all.size)
16
+ end
17
+
18
+ end
19
+
20
+ require 'misc/passwd'
21
+ require 'set'
22
+
23
+ class TestBaseLoginObject < Test::Unit::TestCase
24
+ include Expect4r
25
+
26
+ def setup
27
+ @pwd = "MySecretPassword"
28
+ @cpwd = Expect4r.cipher(@pwd)
29
+ end
30
+
31
+ def test_we_are_not_caching_password_in_the_clear
32
+ o = BaseLoginObject.new :telnet, :host=> '1.1.1.1', :user=> 'lab', :password=>'lab'
33
+ assert_not_equal "lab", o.instance_eval { @pwd }
34
+ o = BaseLoginObject.new :telnet, :host=> '1.1.1.1', :user=> 'lab', :password=>'lab'
35
+ assert_not_equal "lab", o.instance_eval { @pwd }
36
+ assert ! o.respond_to?(:spawnee_enable_password), "certain things are better kept private!"
37
+ assert ! o.respond_to?(:spawnee_password), "certain things are better kept private!"
38
+ end
39
+
40
+ def test_that_default_enable_password_is_set_to_password
41
+ o = BaseLoginObject.new :telnet, :host=> '1.1.1.1', :user=> 'lab', :password=>'lab'
42
+ assert_equal(o.password, o.enable_password)
43
+ end
44
+
45
+ def test_dedicated_enable_password
46
+ o = BaseLoginObject.new :telnet, :host=> '1.1.1.1', :user=> 'lab', :password=>'lab', :enable_password=>'LAB'
47
+ assert_not_equal(o.password, o.enable_password)
48
+ end
49
+
50
+ def test_new_4_args
51
+ o1 = BaseLoginObject.new :telnet, '1.1.1.1', 'lab', 'lab'
52
+ o2 = BaseLoginObject.new :telnet, :host=> '1.1.1.1', :user=> 'lab', :password=>'lab'
53
+ assert o1.cmp(o2)
54
+ end
55
+
56
+ def test_new_5th_arg_is_port_number
57
+ o1 = BaseLoginObject.new :telnet, '1.1.1.1', 'lab', 'lab', 2001
58
+ o2 = BaseLoginObject.new :telnet, :host=> '1.1.1.1', :user=> 'lab', :password=>'lab'
59
+ assert ! o1.cmp(o2)
60
+ o2.port=2001
61
+ assert o1.cmp(o2)
62
+ end
63
+
64
+ def test_new_5th_arg_is_enable_password
65
+ o1 = BaseLoginObject.new :telnet, '1.1.1.1', 'lab', 'lab', 'secret'
66
+ o2 = BaseLoginObject.new :telnet, :host=> '1.1.1.1', :user=> 'lab', :password=>'lab', :enable_password=>'secret'
67
+ assert o1.cmp(o2)
68
+ end
69
+
70
+ def test_new_6_args
71
+ o1 = BaseLoginObject.new :telnet, '1.1.1.1', 'user', 'pwd', 'enable', 2001
72
+ o2 = BaseLoginObject.new :telnet, :host=> '1.1.1.1', :user=> 'user', :password=>'pwd', :enable_password=>'enable', :port=>2001
73
+ assert o1.cmp(o2)
74
+ end
75
+
76
+ def test_verify_private_spawnee_passord
77
+ o1 = BaseLoginObject.new :telnet, '1.1.1.1', 'user', 'pwd', 'enable', 2001
78
+ assert_equal("pwd", o1.instance_eval { spawnee_password})
79
+ end
80
+
81
+ def test_verify_private_spawnee_enable_passord
82
+ o1 = BaseLoginObject.new :telnet, '1.1.1.1', 'user', 'pwd', 'enable', 2001
83
+ assert_equal("enable", o1.instance_eval { spawnee_enable_password})
84
+ end
85
+
86
+ end
87
+
metadata CHANGED
@@ -1,30 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expect4r
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
5
- prerelease:
4
+ version: 0.0.10
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jean-Michel Esnault
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-09 00:00:00.000000000 Z
11
+ date: 2013-08-07 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: highline
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 1.5.0
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: 1.5.0
30
27
  description: A Ruby Library for interacting with IOS, IOS-XR, and JUNOS CLI.
@@ -66,11 +63,13 @@ files:
66
63
  - lib/router/vyatta/show.rb
67
64
  - lib/router/vyatta/vyatta.rb
68
65
  - test/expect4r_test.rb
66
+ - test/misc/base_test.rb
69
67
  - test/misc/passwd_test.rb
70
68
  - test/misc/rspec.rb
71
69
  - test/router/cisco/iox/iox_test.rb
72
70
  homepage: http://github.com/jesnault/expect4r
73
71
  licenses: []
72
+ metadata: {}
74
73
  post_install_message:
75
74
  rdoc_options:
76
75
  - --quiet
@@ -80,25 +79,24 @@ rdoc_options:
80
79
  require_paths:
81
80
  - lib
82
81
  required_ruby_version: !ruby/object:Gem::Requirement
83
- none: false
84
82
  requirements:
85
- - - ! '>='
83
+ - - '>='
86
84
  - !ruby/object:Gem::Version
87
85
  version: 1.8.6
88
86
  required_rubygems_version: !ruby/object:Gem::Requirement
89
- none: false
90
87
  requirements:
91
- - - ! '>='
88
+ - - '>='
92
89
  - !ruby/object:Gem::Version
93
90
  version: '0'
94
91
  requirements: []
95
92
  rubyforge_project:
96
- rubygems_version: 1.8.24
93
+ rubygems_version: 2.0.0.rc.2
97
94
  signing_key:
98
- specification_version: 3
95
+ specification_version: 4
99
96
  summary: Expect4r
100
97
  test_files:
101
98
  - test/expect4r_test.rb
99
+ - test/misc/base_test.rb
102
100
  - test/misc/passwd_test.rb
103
101
  - test/misc/rspec.rb
104
102
  - test/router/cisco/iox/iox_test.rb