capp 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.autotest +12 -0
- data/.gemtest +0 -0
- data/.hoerc +2 -0
- data/History.rdoc +4 -0
- data/Manifest.txt +24 -0
- data/README.rdoc +84 -0
- data/Rakefile +57 -0
- data/ext/capp/capp.c +1382 -0
- data/ext/capp/extconf.rb +34 -0
- data/ext/capp/structs.h +86 -0
- data/lib/capp.rb +168 -0
- data/lib/capp/packet.rb +402 -0
- data/lib/capp/test_case.rb +61 -0
- data/test/802.1X.pcap +0 -0
- data/test/arp.pcap +0 -0
- data/test/icmp4.pcap +0 -0
- data/test/icmp6.pcap +0 -0
- data/test/tcp4.pcap +0 -0
- data/test/tcp6.pcap +0 -0
- data/test/test_capp.rb +273 -0
- data/test/test_capp_packet.rb +160 -0
- data/test/test_capp_packet_tcp_header.rb +103 -0
- data/test/test_capp_root.rb +194 -0
- data/test/udp4.pcap +0 -0
- data/test/udp6.pcap +0 -0
- metadata +161 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'capp'
|
3
|
+
|
4
|
+
class TestCappPacketTCPHeader < MiniTest::Unit::TestCase
|
5
|
+
|
6
|
+
def test_ack_eh
|
7
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
8
|
+
nil, 0xff, nil, nil, nil)
|
9
|
+
|
10
|
+
assert header.ack?
|
11
|
+
|
12
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
13
|
+
nil, 0x00, nil, nil, nil)
|
14
|
+
|
15
|
+
refute header.ack?
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_cwr_eh
|
19
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
20
|
+
nil, 0xff, nil, nil, nil)
|
21
|
+
|
22
|
+
assert header.cwr?
|
23
|
+
|
24
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
25
|
+
nil, 0x00, nil, nil, nil)
|
26
|
+
|
27
|
+
refute header.cwr?
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_ece_eh
|
31
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
32
|
+
nil, 0xff, nil, nil, nil)
|
33
|
+
|
34
|
+
assert header.ece?
|
35
|
+
|
36
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
37
|
+
nil, 0x00, nil, nil, nil)
|
38
|
+
|
39
|
+
refute header.ece?
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_fin_eh
|
43
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
44
|
+
nil, 0xff, nil, nil, nil)
|
45
|
+
|
46
|
+
assert header.fin?
|
47
|
+
|
48
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
49
|
+
nil, 0x00, nil, nil, nil)
|
50
|
+
|
51
|
+
refute header.fin?
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_push_eh
|
55
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
56
|
+
nil, 0xff, nil, nil, nil)
|
57
|
+
|
58
|
+
assert header.push?
|
59
|
+
|
60
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
61
|
+
nil, 0x00, nil, nil, nil)
|
62
|
+
|
63
|
+
refute header.push?
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_rst_eh
|
67
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
68
|
+
nil, 0xff, nil, nil, nil)
|
69
|
+
|
70
|
+
assert header.rst?
|
71
|
+
|
72
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
73
|
+
nil, 0x00, nil, nil, nil)
|
74
|
+
|
75
|
+
refute header.rst?
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_syn_eh
|
79
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
80
|
+
nil, 0xff, nil, nil, nil)
|
81
|
+
|
82
|
+
assert header.syn?
|
83
|
+
|
84
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
85
|
+
nil, 0x00, nil, nil, nil)
|
86
|
+
|
87
|
+
refute header.syn?
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_urg_eh
|
91
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
92
|
+
nil, 0xff, nil, nil, nil)
|
93
|
+
|
94
|
+
assert header.urg?
|
95
|
+
|
96
|
+
header = Capp::Packet::TCPHeader.new(nil, nil, nil, nil,
|
97
|
+
nil, 0x00, nil, nil, nil)
|
98
|
+
|
99
|
+
refute header.urg?
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
@@ -0,0 +1,194 @@
|
|
1
|
+
require 'capp/test_case'
|
2
|
+
require 'etc'
|
3
|
+
require 'socket'
|
4
|
+
require 'thread'
|
5
|
+
require 'tmpdir'
|
6
|
+
|
7
|
+
class TestCappRoot < Capp::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@root = Etc.getpwuid
|
11
|
+
|
12
|
+
skip 'this test must run as root' unless @root.uid == 0
|
13
|
+
|
14
|
+
begin
|
15
|
+
@nobody = Etc.getpwnam 'nobody'
|
16
|
+
rescue ArgumentError
|
17
|
+
skip 'this test require a "nobody" user"'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_capp_devices
|
22
|
+
devices = Capp.devices
|
23
|
+
|
24
|
+
refute_empty devices
|
25
|
+
|
26
|
+
device = devices.first
|
27
|
+
|
28
|
+
assert_kind_of Capp::Device, device
|
29
|
+
|
30
|
+
refute_empty device.addresses
|
31
|
+
|
32
|
+
address = device.addresses.first
|
33
|
+
|
34
|
+
assert_kind_of Capp::Address, address
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_capp_drop_privileges_chroot
|
38
|
+
Dir.mktmpdir 'capp' do |dir|
|
39
|
+
fork_and_test do
|
40
|
+
Capp.drop_privileges 'nobody', dir
|
41
|
+
|
42
|
+
abort 'current directory unchanged' unless Dir.pwd == '/'
|
43
|
+
|
44
|
+
begin
|
45
|
+
File.stat dir
|
46
|
+
abort 'choot failed'
|
47
|
+
rescue Errno::ENOENT
|
48
|
+
end
|
49
|
+
|
50
|
+
exit! 0
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_capp_drop_privileges_chroot_no_user
|
56
|
+
Dir.mktmpdir 'capp' do |dir|
|
57
|
+
e = assert_raises Capp::Error do
|
58
|
+
Capp.drop_privileges nil, dir
|
59
|
+
end
|
60
|
+
|
61
|
+
assert_equal 'chroot without dropping root is insecure', e.message
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_capp_drop_privileges_chroot_nonexistent_dir
|
66
|
+
Dir.mktmpdir 'capp' do |dir|
|
67
|
+
nonexistent = File.join dir, 'nonexistent'
|
68
|
+
e = assert_raises Capp::Error do
|
69
|
+
Capp.drop_privileges 'nobody', nonexistent
|
70
|
+
end
|
71
|
+
|
72
|
+
assert_equal \
|
73
|
+
"could not chroot to #{nonexistent} or change to chroot directory",
|
74
|
+
e.message
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_capp_drop_privileges_name
|
79
|
+
dir = Dir.pwd
|
80
|
+
|
81
|
+
fork_and_test do
|
82
|
+
Capp.drop_privileges 'nobody'
|
83
|
+
|
84
|
+
user = Etc.getpwuid
|
85
|
+
|
86
|
+
abort 'user unchanged' if @root.uid == user.uid
|
87
|
+
abort 'group unchanged' if @root.gid == user.gid
|
88
|
+
|
89
|
+
begin
|
90
|
+
File.stat dir
|
91
|
+
rescue Errno::ENOENT
|
92
|
+
abort 'unexpected chroot!'
|
93
|
+
end
|
94
|
+
|
95
|
+
exit! 0
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_capp_drop_privileges_no_user
|
100
|
+
fork_and_test do
|
101
|
+
Capp.drop_privileges nil
|
102
|
+
|
103
|
+
user = Etc.getpwuid
|
104
|
+
|
105
|
+
abort 'user changed' unless @root.uid == user.uid
|
106
|
+
abort 'group changed' unless @root.gid == user.gid
|
107
|
+
|
108
|
+
exit! 0
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_capp_drop_privileges_nonexistent_user
|
113
|
+
e = assert_raises Capp::Error do
|
114
|
+
Capp.drop_privileges 'nonexistent'
|
115
|
+
end
|
116
|
+
|
117
|
+
assert_equal 'could not find user nonexistent', e.message
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_capp_drop_privileges_uid
|
121
|
+
dir = Dir.pwd
|
122
|
+
|
123
|
+
fork_and_test do
|
124
|
+
Capp.drop_privileges @nobody.uid
|
125
|
+
|
126
|
+
user = Etc.getpwuid
|
127
|
+
|
128
|
+
abort 'user unchanged' if @root.uid == user.uid
|
129
|
+
abort 'group unchanged' if @root.gid == user.gid
|
130
|
+
|
131
|
+
begin
|
132
|
+
File.stat dir
|
133
|
+
rescue Errno::ENOENT
|
134
|
+
abort 'unexpected chroot!'
|
135
|
+
end
|
136
|
+
|
137
|
+
exit! 0
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_capp_live
|
142
|
+
loopback = Capp.devices.find do |device|
|
143
|
+
device.addresses.any? do |address|
|
144
|
+
address.address == '127.0.0.1'
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
skip 'unable to find IPv4 loopback device' unless loopback
|
149
|
+
|
150
|
+
capp = Capp.open loopback.name
|
151
|
+
queue = Queue.new
|
152
|
+
|
153
|
+
Thread.new do
|
154
|
+
capp.loop do |packet|
|
155
|
+
queue << packet
|
156
|
+
break
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
socket = UDPSocket.new
|
161
|
+
socket.send 'hi', 0, '127.0.0.1', 54321
|
162
|
+
socket.close
|
163
|
+
|
164
|
+
packet = queue.pop
|
165
|
+
|
166
|
+
assert_equal 'hi', packet.payload
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_capp_device_open
|
170
|
+
loopback = Capp.devices.find do |device|
|
171
|
+
device.addresses.any? do |address|
|
172
|
+
address.address == '127.0.0.1'
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
skip 'unable to find IPv4 loopback device' unless loopback
|
177
|
+
|
178
|
+
capp = loopback.open
|
179
|
+
|
180
|
+
assert_equal loopback.name, capp.device
|
181
|
+
end
|
182
|
+
|
183
|
+
def fork_and_test
|
184
|
+
pid = fork do
|
185
|
+
yield
|
186
|
+
end
|
187
|
+
|
188
|
+
_, status = Process.wait2 pid
|
189
|
+
|
190
|
+
assert status.success?, status.inspect
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
data/test/udp4.pcap
ADDED
Binary file
|
data/test/udp6.pcap
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Hodel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBBMRAwDgYDVQQDDAdkcmJy
|
14
|
+
YWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZFgNu
|
15
|
+
ZXQwHhcNMTMwMjI4MDUyMjA4WhcNMTQwMjI4MDUyMjA4WjBBMRAwDgYDVQQDDAdk
|
16
|
+
cmJyYWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZ
|
17
|
+
FgNuZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbbgLrGLGIDE76
|
18
|
+
LV/cvxdEzCuYuS3oG9PrSZnuDweySUfdp/so0cDq+j8bqy6OzZSw07gdjwFMSd6J
|
19
|
+
U5ddZCVywn5nnAQ+Ui7jMW54CYt5/H6f2US6U0hQOjJR6cpfiymgxGdfyTiVcvTm
|
20
|
+
Gj/okWrQl0NjYOYBpDi+9PPmaH2RmLJu0dB/NylsDnW5j6yN1BEI8MfJRR+HRKZY
|
21
|
+
mUtgzBwF1V4KIZQ8EuL6I/nHVu07i6IkrpAgxpXUfdJQJi0oZAqXurAV3yTxkFwd
|
22
|
+
g62YrrW26mDe+pZBzR6bpLE+PmXCzz7UxUq3AE0gPHbiMXie3EFE0oxnsU3lIduh
|
23
|
+
sCANiQ8BAgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
|
24
|
+
BBS5k4Z75VSpdM0AclG2UvzFA/VW5DAfBgNVHREEGDAWgRRkcmJyYWluQHNlZ21l
|
25
|
+
bnQ3Lm5ldDAfBgNVHRIEGDAWgRRkcmJyYWluQHNlZ21lbnQ3Lm5ldDANBgkqhkiG
|
26
|
+
9w0BAQUFAAOCAQEAOflo4Md5aJF//EetzXIGZ2EI5PzKWX/mMpp7cxFyDcVPtTv0
|
27
|
+
js/6zWrWSbd60W9Kn4ch3nYiATFKhisgeYotDDz2/pb/x1ivJn4vEvs9kYKVvbF8
|
28
|
+
V7MV/O5HDW8Q0pA1SljI6GzcOgejtUMxZCyyyDdbUpyAMdt9UpqTZkZ5z1sicgQk
|
29
|
+
5o2XJ+OhceOIUVqVh1r6DNY5tLVaGJabtBmJAYFVznDcHiSFybGKBa5n25Egql1t
|
30
|
+
KDyY1VIazVgoC8XvR4h/95/iScPiuglzA+DBG1hip1xScAtw05BrXyUNrc9CEMYU
|
31
|
+
wgF94UVoHRp6ywo8I7NP3HcwFQDFNEZPNGXsng==
|
32
|
+
-----END CERTIFICATE-----
|
33
|
+
date: 2013-05-03 00:00:00.000000000 Z
|
34
|
+
dependencies:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: minitest
|
37
|
+
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '4.6'
|
42
|
+
type: :development
|
43
|
+
prerelease: false
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '4.6'
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rdoc
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '3.10'
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '3.10'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: rake-compiler
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0.8'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0.8'
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: hoe
|
79
|
+
requirement: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ~>
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '3.5'
|
84
|
+
type: :development
|
85
|
+
prerelease: false
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ~>
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '3.5'
|
91
|
+
description: |-
|
92
|
+
Capp is a packet capture library that wraps libpcap. Capp provides a simple
|
93
|
+
API for capturing packets and automatically unpacks common packets (including
|
94
|
+
Ethernet, IP, TCP, UDP and ICMP). Capp also cooperates with other threads
|
95
|
+
better than other pcap wrapper libraries for ruby.
|
96
|
+
email:
|
97
|
+
- drbrain@segment7.net
|
98
|
+
executables: []
|
99
|
+
extensions:
|
100
|
+
- ext/capp/extconf.rb
|
101
|
+
extra_rdoc_files:
|
102
|
+
- History.rdoc
|
103
|
+
- Manifest.txt
|
104
|
+
- README.rdoc
|
105
|
+
- ext/capp/capp.c
|
106
|
+
files:
|
107
|
+
- .autotest
|
108
|
+
- .hoerc
|
109
|
+
- History.rdoc
|
110
|
+
- Manifest.txt
|
111
|
+
- README.rdoc
|
112
|
+
- Rakefile
|
113
|
+
- ext/capp/capp.c
|
114
|
+
- ext/capp/extconf.rb
|
115
|
+
- ext/capp/structs.h
|
116
|
+
- lib/capp.rb
|
117
|
+
- lib/capp/packet.rb
|
118
|
+
- lib/capp/test_case.rb
|
119
|
+
- test/802.1X.pcap
|
120
|
+
- test/arp.pcap
|
121
|
+
- test/icmp4.pcap
|
122
|
+
- test/icmp6.pcap
|
123
|
+
- test/tcp4.pcap
|
124
|
+
- test/tcp6.pcap
|
125
|
+
- test/test_capp.rb
|
126
|
+
- test/test_capp_packet.rb
|
127
|
+
- test/test_capp_packet_tcp_header.rb
|
128
|
+
- test/test_capp_root.rb
|
129
|
+
- test/udp4.pcap
|
130
|
+
- test/udp6.pcap
|
131
|
+
- .gemtest
|
132
|
+
homepage: https://github.com/drbrain/capp
|
133
|
+
licenses: []
|
134
|
+
metadata: {}
|
135
|
+
post_install_message:
|
136
|
+
rdoc_options:
|
137
|
+
- --main
|
138
|
+
- README.rdoc
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - '>='
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
requirements: []
|
152
|
+
rubyforge_project: capp
|
153
|
+
rubygems_version: 2.0.3
|
154
|
+
signing_key:
|
155
|
+
specification_version: 4
|
156
|
+
summary: Capp is a packet capture library that wraps libpcap
|
157
|
+
test_files:
|
158
|
+
- test/test_capp.rb
|
159
|
+
- test/test_capp_packet.rb
|
160
|
+
- test/test_capp_packet_tcp_header.rb
|
161
|
+
- test/test_capp_root.rb
|