meshtastic 0.0.16 → 0.0.18
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 +4 -4
- data/README.md +11 -8
- data/lib/meshtastic/mqtt.rb +40 -95
- data/lib/meshtastic/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 95418c85d77e376647941a4ad72cb556f36917e3e08c38459e7d500ebc198fe8
|
4
|
+
data.tar.gz: c25683cfd633e2aceb1a21c12b25bdaaaff2df1cca710457786e9721c9107971
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07ad4d65c7734479d9f97c8f4af7ffa7496b1bca97adc108d1fa617b9f1836a793836d702171358cbbccc23151a2479975b4bd62a1a9e77024bd925fbb850870
|
7
|
+
data.tar.gz: 8a11bec783dd3b48dfc4c830b651771ec0f9aadb9d0fc4814fab478f20eaf1ff197ee79d91a2ea458f79a76c1a3a9815c848045fd6e93255606cc39041b83976
|
data/README.md
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
# Meshtastic
|
2
|
-
|
2
|
+
|
3
|
+
Ruby gem for interfacing with Meshtastic nodes / network.
|
3
4
|
|
4
5
|
# Setting Expectations
|
5
|
-
|
6
|
+
|
7
|
+
This gem was created to support alt-comm capabilities w/in a security research framework known as [PWN](https://github.com/0dayInc/pwn). Contributors of this effort cannot guarantee full functionality or support for all Meshtastic features.
|
6
8
|
|
7
9
|
# Objectives
|
8
|
-
|
9
|
-
-
|
10
|
-
-
|
10
|
+
|
11
|
+
- Consume the latest [Meshtastic Protobof Specs](https://github.com/meshtastic/protobufs) and [auto-generate Ruby protobuf modules for Meshtastic](https://github.com/0dayInc/meshtastic/blob/master/AUTOGEN_meshtastic_protobufs.sh) using the `protoc` command: `Complete`
|
12
|
+
- Integrate auto-generated Ruby protobuf modules into a working Ruby gem: `Complete`
|
13
|
+
- Scale out Meshtastic Ruby Modules for their respective protobufs within the meshtastic gem (e.g. Meshtastic::MQTTPB is auto-generated based on latest Meshtastic protobuf specs and extended via Meshtastic::MQTT for more MQTT interaction as desired): `Ongoing Effort`
|
11
14
|
|
12
15
|
## Installation
|
13
16
|
|
@@ -21,7 +24,7 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
21
24
|
|
22
25
|
## Usage
|
23
26
|
|
24
|
-
At the moment the only
|
27
|
+
At the moment the only module available is `Meshtastic::MQTT`. To view MQTT messages, run the following:
|
25
28
|
|
26
29
|
```ruby
|
27
30
|
require 'meshtastic'
|
@@ -32,8 +35,8 @@ Meshtastic::MQTT.subscribe(mqtt_obj: mqtt_obj)
|
|
32
35
|
|
33
36
|
## Contributing
|
34
37
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/0dayinc/meshtastic. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/
|
38
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/0dayinc/meshtastic. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/0dayinc/meshtastic/blob/master/CODE_OF_CONDUCT.md).
|
36
39
|
|
37
40
|
## Code of Conduct
|
38
41
|
|
39
|
-
Everyone interacting in the Meshtastic project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/
|
42
|
+
Everyone interacting in the Meshtastic project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/0dayinc/meshtastic/blob/master/CODE_OF_CONDUCT.md).
|
data/lib/meshtastic/mqtt.rb
CHANGED
@@ -49,7 +49,8 @@ module Meshtastic
|
|
49
49
|
# channel: 'optional - channel name (default: LongFast)',
|
50
50
|
# psk: 'optional - channel pre-shared key (default: AQ==)',
|
51
51
|
# qos: 'optional - quality of service (default: 0)',
|
52
|
-
# json: 'optional - JSON output (default: false)'
|
52
|
+
# json: 'optional - JSON output (default: false)',
|
53
|
+
# filter: 'optional - comma-delimited string(s) to search for in the payload (default: nil)'
|
53
54
|
# )
|
54
55
|
|
55
56
|
public_class_method def self.subscribe(opts = {})
|
@@ -59,6 +60,7 @@ module Meshtastic
|
|
59
60
|
psk = opts[:psk] ||= 'AQ=='
|
60
61
|
qos = opts[:qos] ||= 0
|
61
62
|
json = opts[:json] ||= false
|
63
|
+
filter = opts[:filter]
|
62
64
|
|
63
65
|
# TODO: Find JSON URI for this
|
64
66
|
root_topic = "msh/#{region}/2/json" if json
|
@@ -78,71 +80,34 @@ module Meshtastic
|
|
78
80
|
|
79
81
|
# cipher = OpenSSL::Cipher.new('AES-256-CTR')
|
80
82
|
cipher = OpenSSL::Cipher.new('AES-128-CTR')
|
83
|
+
filter_arr = filter.to_s.split(',').map(&:strip)
|
81
84
|
mqtt_obj.get_packet do |packet_bytes|
|
82
|
-
# puts "Packet Bytes: #{packet_bytes.public_methods}"
|
83
85
|
raw_packet = packet_bytes.to_s.b
|
84
86
|
raw_packet_len = raw_packet.to_s.b.length
|
85
87
|
raw_topic = packet_bytes.topic
|
86
88
|
raw_payload = packet_bytes.payload
|
87
|
-
raw_payload_len = raw_payload.length
|
88
89
|
|
89
90
|
begin
|
90
|
-
puts '-' * 80
|
91
|
-
|
92
91
|
payload = {}
|
93
92
|
if json
|
94
|
-
|
95
|
-
payload = Meshtastic::ServiceEnvelope.json_decode(json_payload)
|
96
|
-
map_report = Meshtastic::MapReport.json_decode(json_payload)
|
93
|
+
payload = JSON.parse(raw_payload, symbolize_names: true)
|
97
94
|
else
|
98
|
-
svc_envl= Meshtastic::ServiceEnvelope.decode(raw_payload)
|
95
|
+
svc_envl = Meshtastic::ServiceEnvelope.decode(raw_payload)
|
96
|
+
# map_report = Meshtastic::MapReport.decode(raw_payload)
|
99
97
|
payload = svc_envl.to_h[:packet]
|
100
|
-
# puts "STILL GOOD: #{payload.inspect}"
|
101
|
-
# puts "Public Methods: #{Meshtastic::MapReport.public_methods}"
|
102
|
-
# puts "Public Methods: #{Meshtastic::MapReport.class}"
|
103
|
-
# map_report_decode = Meshtastic::MapReport.decode(raw_payload)
|
104
|
-
# map_report = map_report_decode.to_h
|
105
|
-
# puts "STILL GOOD: #{map_report.inspect}"
|
106
|
-
end
|
107
|
-
|
108
|
-
puts "*** MESSAGE ***"
|
109
|
-
packet_from = payload[:from]
|
110
|
-
puts "Packet From: #{packet_from}"
|
111
|
-
packet_to = payload[:to]
|
112
|
-
puts "Packet To: #{packet_to}"
|
113
|
-
channel = payload[:channel]
|
114
|
-
puts "Channel: #{channel}"
|
115
|
-
packet_id = payload[:id]
|
116
|
-
puts "Packet ID: #{packet_id}"
|
117
|
-
puts "\nTopic: #{raw_topic}"
|
118
|
-
|
119
|
-
decoded_payload = payload[:decoded]
|
120
|
-
if decoded_payload
|
121
|
-
port_num = decoded_payload[:portnum]
|
122
|
-
puts "Port Number: #{port_num}"
|
123
|
-
decp = decoded_payload[:payload].b
|
124
|
-
puts "Decoded Payload: #{decp.inspect}"
|
125
|
-
want_response = decoded_payload[:want_response]
|
126
|
-
puts "Want Response: #{want_response}"
|
127
|
-
dest = decoded_payload[:dest]
|
128
|
-
puts "Destination: #{dest}"
|
129
|
-
source = decoded_payload[:source]
|
130
|
-
puts "Source: #{source}"
|
131
|
-
request_id = decoded_payload[:request_id]
|
132
|
-
puts "Request ID: #{request_id}"
|
133
|
-
reply_id = decoded_payload[:reply_id]
|
134
|
-
puts "Reply ID: #{reply_id}"
|
135
|
-
emoji = decoded_payload[:emoji]
|
136
|
-
puts "Emoji: #{emoji}"
|
137
98
|
end
|
99
|
+
payload[:topic] = raw_topic
|
100
|
+
payload[:node_id_from] = "!#{payload[:from].to_i.to_s(16)}"
|
101
|
+
payload[:node_id_to] = "!#{payload[:to].to_i.to_s(16)}"
|
138
102
|
|
139
103
|
encrypted_payload = payload[:encrypted]
|
140
104
|
# If encrypted_payload is not nil, then decrypt the message
|
141
105
|
if encrypted_payload.length.positive?
|
106
|
+
packet_id = payload[:id]
|
107
|
+
packet_from = payload[:from]
|
142
108
|
nonce_packet_id = [packet_id].pack('V').ljust(8, "\x00")
|
143
109
|
nonce_from_node = [packet_from].pack('V').ljust(8, "\x00")
|
144
110
|
nonce = "#{nonce_packet_id}#{nonce_from_node}".b
|
145
|
-
puts "Nonce: #{nonce.inspect} | Length: #{nonce.length}"
|
146
111
|
|
147
112
|
# Decrypt the message
|
148
113
|
# Key must be 32 bytes
|
@@ -150,62 +115,42 @@ module Meshtastic
|
|
150
115
|
cipher.decrypt
|
151
116
|
cipher.key = dec_psk
|
152
117
|
cipher.iv = nonce
|
153
|
-
puts "\nEncrypted Payload:\n#{encrypted_payload.inspect}"
|
154
|
-
puts "Length: #{encrypted_payload.length}" if encrypted_payload
|
155
118
|
|
156
119
|
decrypted = cipher.update(encrypted_payload) + cipher.final
|
157
|
-
|
158
|
-
puts "Length: #{decrypted.length}" if decrypted
|
120
|
+
payload[:decrypted] = decrypted
|
159
121
|
end
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
#
|
186
|
-
# puts "Position Precision: #{position_precision}"
|
187
|
-
# num_online_local_nodes = map_report[:num_online_local_nodes]
|
188
|
-
# puts "Number of Online Local Nodes: #{num_online_local_nodes}"
|
189
|
-
# puts '*' * 20
|
190
|
-
|
191
|
-
puts "\n*** PACKET DEBUGGING ***"
|
192
|
-
puts "Payload: #{payload.inspect}"
|
193
|
-
# puts "\nMap Report: #{map_report.inspect}"
|
194
|
-
puts "\nRaw Packet: #{raw_packet.inspect}"
|
195
|
-
puts "Length: #{raw_packet_len}"
|
196
|
-
puts '*' * 20
|
197
|
-
rescue Google::Protobuf::ParseError => e
|
198
|
-
puts "ERROR: #{e.inspect}"
|
199
|
-
puts "\n*** PACKET DEBUGGING ***"
|
200
|
-
puts "Payload: #{payload.inspect}"
|
122
|
+
|
123
|
+
filter_arr = [payload[:id].to_s] if filter.nil?
|
124
|
+
disp = false
|
125
|
+
flat_payload = payload.values.join(' ')
|
126
|
+
|
127
|
+
disp = true if filter_arr.first == payload[:id] ||
|
128
|
+
filter_arr.all? { |filter| flat_payload.include?(filter) }
|
129
|
+
|
130
|
+
if disp
|
131
|
+
puts "\n"
|
132
|
+
puts '-' * 80
|
133
|
+
puts "\n*** DEBUGGING ***"
|
134
|
+
puts "Payload:\n#{payload}"
|
135
|
+
# puts "\nMap Report: #{map_report.inspect}"
|
136
|
+
puts "\nRaw Packet: #{raw_packet.inspect}"
|
137
|
+
puts "Length: #{raw_packet_len}"
|
138
|
+
puts '-' * 80
|
139
|
+
puts "\n\n\n"
|
140
|
+
else
|
141
|
+
print '.'
|
142
|
+
end
|
143
|
+
rescue Google::Protobuf::ParseError
|
144
|
+
puts "\n"
|
145
|
+
puts '-' * 80
|
146
|
+
puts "\n*** DEBUGGING ***"
|
147
|
+
puts "Payload:\n#{payload}"
|
201
148
|
# puts "\nMap Report: #{map_report.inspect}"
|
202
149
|
puts "\nRaw Packet: #{raw_packet.inspect}"
|
203
150
|
puts "Length: #{raw_packet_len}"
|
204
|
-
puts '*' * 20
|
205
|
-
next
|
206
|
-
ensure
|
207
151
|
puts '-' * 80
|
208
152
|
puts "\n\n\n"
|
153
|
+
next
|
209
154
|
end
|
210
155
|
end
|
211
156
|
rescue Interrupt
|
data/lib/meshtastic/version.rb
CHANGED