-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathtacacs_socket.rb
111 lines (98 loc) · 3.19 KB
/
tacacs_socket.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
module TacacsPlus
module TacacsSocket #:nodoc: all
# PRIVATE INSTANCE METHODS
private
#==============================================================================#
# get_packet()
#==============================================================================#
#===Synopsis
#Receive and decode an inbound TACACS+ packet from a TCPSocket.
#
#===Usage
# packet = get_packet(socket)
#
#===Arguments:
#* TCP Socket
#
#===Returns:
#* PacketStruct
#
def get_packet(socket,key=nil)
decoded = nil
begin
# this check exists for offline testing with TestIO
if ( socket.kind_of?(IO) )
# read from socket. decode only if we actually read something.
if ( IO::select( [socket], nil, nil, @sock_timeout ) )
header = TacacsPlus::TacacsHeader.new( socket.readpartial(12) )
body = ''
remaining = header.length
while(remaining > 0)
body << socket.readpartial(remaining)
remaining = header.length - body.length
end
decoded = TacacsPlus.decode_packet(header,body,key)
if (@dump_file)
@dump_file.print("# Received\n" + decoded.to_yaml + "\n")
@dump_file.flush
end
else
raise TimeoutError
end
else # assume offline testing with TestIO
pkt = socket.read()
raise(EOFError) if (pkt.nil?)
header = TacacsPlus::TacacsHeader.new( pkt.slice!(0..11) )
body = pkt
decoded = TacacsPlus.decode_packet(header,body,key)
end
rescue TimeoutError
raise "Peer connection timed out."
rescue EOFError
raise "Peer sent EOF."
rescue DecodeError => error
raise "Error decoding data received from peer: #{error}"
rescue Exception => error
raise "Undefined error: #{error}."
end
return(decoded)
end
#==============================================================================#
# send_packet()
#==============================================================================#
#===Synopsis
#Send TACACS+ packet to a TCPSocket.
#
#===Usage
# send_packet(socket,header,body)
#
#===Arguments:
#* TCP Socket
#* TacacsHeader
#* TacacsBody
#
#===Returns:
#* True
#
def send_packet(socket,packet,key=nil)
# set correct type
if (packet.body.kind_of?(Authentication))
packet.header.type_authentication!
elsif (packet.body.kind_of?(Authorization))
packet.header.type_authorization!
else
packet.header.type_accounting!
end
# set body & header length fields
packet.body.set_len!
packet.header.length = packet.body.packed.length
if (@dump_file)
@dump_file.print("# Sent\n" + packet.to_yaml + "\n")
@dump_file.flush
end
pkt = TacacsPlus.encode_packet(packet,key)
socket.write(pkt)
return(true)
end
end # module TacacsSocket
end # module TacacsPlus