@@ -61,9 +61,9 @@ def __init__(self, fields):
6161 2 Last time seen (2015-05-27 19:28:46)
6262 3 channel (6)
6363 4 Speed (54)
64- 5 Privacy (WPA2)
64+ 5 Privacy (WPA2 OWE )
6565 6 Cipher (CCMP TKIP)
66- 7 Authentication (PSK)
66+ 7 Authentication (PSK SAE )
6767 8 Power (-62)
6868 9 beacons (2)
6969 10 # IV (0)
@@ -76,20 +76,37 @@ def __init__(self, fields):
7676 self .wps = WPSState .NONE
7777 self .bssid = fields [0 ].strip ()
7878 self .channel = fields [3 ].strip ()
79- self .encryption = fields [5 ].strip ()
80- self .authentication = fields [7 ].strip ()
81-
82- # airodump sometimes does not report the encryption type for some reason
83- # In this case (len = 0), defaults to WPA (which is the most common)
84- if 'WPA' in self .encryption or len (self .encryption ) == 0 :
85- self .encryption = 'WPA'
79+ self .encryption = fields [5 ].strip () # Contains encryption type(s) like "WPA2 WPA3 OWE"
80+ self .authentication = fields [7 ].strip () # Contains auth type(s) like "PSK SAE MGT"
81+
82+ # Determine primary encryption and auth
83+ if 'WPA3' in self .encryption :
84+ self .primary_encryption = 'WPA3'
85+ elif 'WPA2' in self .encryption :
86+ self .primary_encryption = 'WPA2'
87+ elif 'WPA' in self .encryption : # Handles cases where only "WPA" is present or if no other WPAx is found
88+ self .primary_encryption = 'WPA'
8689 elif 'WEP' in self .encryption :
87- self .encryption = 'WEP'
88- elif 'WPS' in self .encryption :
89- self .encryption = 'WPS'
90+ self .primary_encryption = 'WEP'
91+ elif 'OWE' in self .encryption : # Opportunistic Wireless Encryption
92+ self .primary_encryption = 'OWE'
93+ elif len (self .encryption ) == 0 : # Default to WPA if not specified, as per old logic
94+ self .primary_encryption = 'WPA'
95+ else : # Fallback for unknown types
96+ self .primary_encryption = self .encryption .split (' ' )[0 ]
97+
98+
99+ if 'SAE' in self .authentication :
100+ self .primary_authentication = 'SAE'
101+ elif 'PSK' in self .authentication :
102+ self .primary_authentication = 'PSK'
103+ elif 'MGT' in self .authentication : # Enterprise
104+ self .primary_authentication = 'MGT'
105+ elif 'OWE' in self .authentication : # OWE uses its own auth mechanism
106+ self .primary_authentication = 'OWE'
107+ else :
108+ self .primary_authentication = self .authentication .split (' ' )[0 ]
90109
91- if len (self .encryption ) > 4 :
92- self .encryption = self .encryption [:4 ].strip ()
93110
94111 self .power = int (fields [8 ].strip ())
95112 if self .power < 0 :
@@ -119,6 +136,14 @@ def __init__(self, fields):
119136
120137 self .clients = []
121138
139+ # Store full encryption and authentication strings for detailed info if needed
140+ self .full_encryption_string = self .encryption
141+ self .full_authentication_string = self .authentication
142+ # For compatibility with existing logic that expects a single string:
143+ self .encryption = self .primary_encryption # Overwrite with primary for now
144+ self .authentication = self .primary_authentication # Overwrite with primary for now
145+
146+
122147 self .validate ()
123148
124149 def __eq__ (self , other ):
@@ -142,6 +167,15 @@ def transfer_info(self, other):
142167 other .essid_known = self .essid_known
143168 other .essid_len = self .essid_len
144169
170+ # Transfer new fields as well
171+ if hasattr (self , 'primary_encryption' ):
172+ other .primary_encryption = self .primary_encryption
173+ other .full_encryption_string = self .full_encryption_string
174+ if hasattr (self , 'primary_authentication' ):
175+ other .primary_authentication = self .primary_authentication
176+ other .full_authentication_string = self .full_authentication_string
177+
178+
145179 def validate (self ):
146180 """ Checks that the target is valid. """
147181 if self .channel == '-1' :
@@ -203,16 +237,35 @@ def to_str(self, show_bssid=False, show_manufacturer=False):
203237 channel_color = '{C}' if int (self .channel ) > 14 else '{G}'
204238 channel = Color .s (f'{ channel_color } { str (self .channel ).rjust (3 )} ' )
205239
206- encryption = self .encryption .rjust (3 )
207- if 'WEP' in encryption :
208- encryption = Color .s ('{G}%s' % encryption )
209- elif 'WPA' in encryption :
210- if 'PSK' in self .authentication :
211- encryption = Color .s ('{O}%s-P' % encryption )
212- elif 'MGT' in self .authentication :
213- encryption = Color .s ('{R}%s-E' % encryption )
214- else :
215- encryption = Color .s ('{O}%s ' % encryption )
240+ # Use primary_encryption and primary_authentication for display
241+ display_encryption = self .primary_encryption .rjust (4 ) # Adjusted rjust for WPA3
242+ auth_suffix = ''
243+ if self .primary_encryption == 'WPA3' :
244+ display_encryption = Color .s ('{P}%s' % display_encryption ) # Purple for WPA3
245+ if self .primary_authentication == 'SAE' :
246+ auth_suffix = Color .s ('{P}-S' ) # Purple for SAE
247+ elif self .primary_authentication == 'MGT' :
248+ auth_suffix = Color .s ('{R}-E' ) # Red for Enterprise
249+ elif self .primary_encryption == 'WPA2' :
250+ display_encryption = Color .s ('{O}%s' % display_encryption ) # Orange for WPA2
251+ if self .primary_authentication == 'PSK' :
252+ auth_suffix = Color .s ('{O}-P' )
253+ elif self .primary_authentication == 'MGT' :
254+ auth_suffix = Color .s ('{R}-E' )
255+ elif self .primary_encryption == 'WPA' :
256+ display_encryption = Color .s ('{O}%s' % display_encryption ) # Orange for WPA
257+ if self .primary_authentication == 'PSK' :
258+ auth_suffix = Color .s ('{O}-P' )
259+ elif self .primary_authentication == 'MGT' :
260+ auth_suffix = Color .s ('{R}-E' )
261+ elif self .primary_encryption == 'WEP' :
262+ display_encryption = Color .s ('{G}%s' % display_encryption ) # Green for WEP
263+ elif self .primary_encryption == 'OWE' :
264+ display_encryption = Color .s ('{B}%s' % display_encryption ) # Blue for OWE
265+ else :
266+ display_encryption = Color .s ('{W}%s' % display_encryption ) # White for others
267+
268+ encryption_display_string = f"{ display_encryption } { auth_suffix } " .ljust (7 ) # Ensure consistent length
216269
217270 power = f'{ str (self .power ).rjust (3 )} db'
218271 if self .power > 50 :
@@ -238,7 +291,7 @@ def to_str(self, show_bssid=False, show_manufacturer=False):
238291 if len (self .clients ) > 0 :
239292 clients = Color .s ('{G} ' + str (len (self .clients )))
240293
241- result = f'{ essid } { bssid } { manufacturer } { channel } { encryption } { power } { wps } { clients } '
294+ result = f'{ essid } { bssid } { manufacturer } { channel } { encryption_display_string } { power } { wps } { clients } '
242295
243296 result += Color .s ('{W}' )
244297 return result
0 commit comments