This file is indexed.

/usr/lib/python2.7/dist-packages/impacket/wps.py is in python-impacket 0.9.15-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
# Copyright (c) 2003-2016 CORE Security Technologies
#
# This software is provided under under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# Description:
#  WPS packets
#
# Author:
# Aureliano Calvo


import array
import struct

from impacket.helper import ProtocolPacket, Byte, Bit


class ArrayBuilder(object):

    def from_ary(self, ary):
        return ary

    def to_ary(self, value):
        return array.array("B", value)
    
class ByteBuilder(object):

    def from_ary(self, ary):
        return ary[0]
    
    def to_ary(self, value):
        return array.array('B', [value])
    
class StringBuilder(object):
    def from_ary(self, ary):
        return ary.tostring()
        
    def to_ary(self, value):
        return array.array('B', value)
    
class NumBuilder(object):
    """Converts back and forth between arrays and numbers in network byte-order"""
    
    def __init__(self, size):
        """size: number of bytes in the field"""
        self.size = size
    
    def from_ary(self, ary):
        if len(ary) != self.size:
            raise Exception("Expected %s size but got %s" % (self.size, len(ary)))
        return reduce( lambda ac, x: ac * 256 + x, ary, 0)
    
    def to_ary(self, value0):
        value = value0
        rv = array.array('B')
        for _ in xrange(self.size):
            value, mod = divmod(value, 256)
            rv.append(mod)
            
        if value != 0:
            raise Exception("%s is too big. Max size: %s" % (value0, self.size))
            
        rv.reverse()
        return rv
    
class TLVContainer(object):
    
    def builder(self, kind):
        return self.builders.get(kind, self.default_builder)
    
    def from_ary(self, ary):
        i = 0
        while i<len(ary):
            kind = self.ary2n(ary, i)
            length = self.ary2n(ary, i+2)
            i+=4
            value = ary[i:i+length]
            self.elems.append((kind, value))
            i += length
            
        return self
                
    def __init__(self, builders, default_builder = ArrayBuilder(), descs=None):
        self.builders = builders
        self.default_builder = default_builder
        self.elems = []
        self.descs = descs or {}
        
    def append(self, kind, value):
        self.elems.append((kind, self.builder(kind).to_ary(value)))
    
    def __iter__(self):
        return ((k, self.builder(k).from_ary(v)) for k,v in self.elems)
    
    def all(self, kind):
        return [e[1] for e in self if e[0] == kind]
    
    def __contains__(self, kind):
        return len(self.all(kind)) != 0
    
    def first(self, kind):
        return self.all(kind)[0]
    
    def to_ary(self):
        ary = array.array('B')
        for k,v in self.elems:
            ary.extend(self.n2ary(k))
            ary.extend(self.n2ary(len(v)))
            ary.extend(v)
            
        return ary

    
    def get_packet(self):
        return self.to_ary().tostring()
    
    def set_parent(self, my_parent):
        self.__parent = my_parent
        
    def parent(self):
        return self.__parent
    
    def n2ary(self, n):
        return array.array("B", struct.pack(">H",n))
    
    def ary2n(self, ary, i=0):
        return struct.unpack(">H", ary[i:i+2].tostring())[0]
    
    def __repr__(self):
        def desc(kind):
            return self.descs[kind] if kind in self.descs else kind
        
        return "<TLVContainer %s>" % repr([(desc(k), self.builder(k).from_ary(v)) for (k,v) in self.elems])
    
    def child(self):
        return None

class SCElem(object):    
    #Data elements as defined in section 11 of the WPS 1.0h spec.
    
    AP_CHANNEL = 0x1001
    ASSOCIATION_STATE = 0x1002
    AUTHENTICATION_TYPE = 0x1003
    AUTHENTICATION_TYPE_FLAGS = 0x1004
    AUTHENTICATOR = 0x1005
    CONFIG_METHODS = 0x1008
    CONFIGURATION_ERROR = 0x1009
    CONFIRMATION_URL4 = 0x100A
    CONFIRMATION_URL6 = 0x100B
    CONNECTION_TYPE = 0X100C
    CONNECTION_TYPE_FLAGS = 0X100D
    CREDENTIAL = 0X100E 
    DEVICE_NAME = 0x1011
    DEVICE_PASSWORD_ID = 0x1012
    E_HASH1 = 0x1014
    E_HASH2 = 0x1015
    E_SNONCE1 = 0x1016
    E_SNONCE2 = 0x1017
    ENCRYPTED_SETTINGS = 0x1018 
    ENCRYPTION_TYPE = 0X100F
    ENCRYPTION_TYPE_FLAGS = 0x1010
    ENROLLEE_NONCE = 0x101A
    FEATURE_ID = 0x101B
    IDENTITY = 0X101C
    INDENTITY_PROOF = 0X101D 
    KEY_WRAP_AUTHENTICATOR = 0x101E
    KEY_IDENTIFIER = 0X101F
    MAC_ADDRESS = 0x1020
    MANUFACTURER = 0x1021
    MESSAGE_TYPE = 0x1022
    MODEL_NAME = 0x1023
    MODEL_NUMBER = 0x1024
    NETWORK_INDEX = 0x1026
    NETWORK_KEY = 0x1027
    NETWORK_KEY_INDEX = 0x1028
    NEW_DEVICE_NAME = 0x1029
    NEW_PASSWORD = 0x102A
    OOB_DEVICE_PASSWORD = 0X102C
    OS_VERSION= 0X102D
    POWER_LEVEL = 0X102F
    PSK_CURRENT = 0x1030
    PSK_MAX = 0x1031
    PUBLIC_KEY = 0x1032
    RADIO_ENABLED = 0x1033
    REBOOT = 0x1034
    REGISTRAR_CURRENT = 0x1035
    REGISTRAR_ESTABLISHED = 0x1036
    REGISTRAR_LIST = 0x1037
    REGISTRAR_MAX = 0x1038
    REGISTRAR_NONCE = 0x1039
    REQUEST_TYPE = 0x103A
    RESPONSE_TYPE = 0x103B
    RF_BANDS = 0X103C
    R_HASH1 = 0X103D
    R_HASH2 = 0X103E
    R_SNONCE1 = 0X103F
    R_SNONCE2 = 0x1040
    SELECTED_REGISTRAR = 0x1041
    SERIAL_NUMBER = 0x1042
    WPS_STATE = 0x1044
    SSID = 0x1045
    TOTAL_NETWORKS = 0x1046
    UUID_E = 0x1047
    UUID_R = 0x1048
    VENDOR_EXTENSION = 0x1049
    VERSION = 0x104A
    X_509_CERTIFICATE_REQUEST = 0x104B 
    X_509_CERTIFICATE = 0x104C
    EAP_IDENTITY = 0x104D
    MESSAGE_COUNTER = 0x104E
    PUBLIC_KEY_HASH = 0x104F
    REKEY_KEY = 0x1050
    KEY_LIFETIME = 0x1051
    PERMITTED_CONFIG_METHODS = 0x1052
    SELECTED_REGISTRAR_CONFIG_METHODS= 0x1053
    PRIMARY_DEVICE_TYPE = 0x1054
    SECONDARY_DEVICE_TYPE_LIST = 0x1055
    PORTABLE_DEVICE = 0x1056
    AP_SETUP_LOCKED = 0x1057
    APPLICATION_EXTENSION = 0x1058
    EAP_TYPE = 0x1059
    INITIALIZATION_VECTOR = 0x1060
    KEY_PROVIDED_AUTOMATICALLY = 0x1061
    _802_1X_ENABLED = 0x1062
    APP_SESSION_KEY = 0x1063
    WEP_TRANSMIT_KEY = 0x1064
    
class MessageType(object):
    """Message types according to WPS 1.0h spec, section 11"""
    
    BEACON = 0x01
    PROBE_REQUEST = 0x02
    PROBE_RESPONSE = 0x03
    M1 = 0x04
    M2 = 0x05
    M2D = 0x06
    M3 = 0x07
    M4 = 0x08
    M5 = 0x09
    M6 = 0x0A
    M7 = 0x0B
    M8 = 0x0C
    WSC_ACK = 0x0D
    WSC_NACK = 0x0E
    WSC_DONE = 0x0F
    
class AuthTypeFlag(object):
    OPEN = 0x0001
    WPAPSK = 0x0002
    SHARED = 0x0004
    WPA = 0x0008
    WPA2 = 0x0010
    WPA2PSK = 0x0020
    
AuthTypeFlag_ALL = AuthTypeFlag.OPEN | \
        AuthTypeFlag.WPAPSK | \
        AuthTypeFlag.SHARED | \
        AuthTypeFlag.WPA | \
        AuthTypeFlag.WPA2 | \
        AuthTypeFlag.WPA2PSK
        
class EncryptionTypeFlag(object):
    NONE = 0x0001
    WEP = 0x0002
    TKIP = 0x0004
    AES = 0x0008
    
EncryptionTypeFlag_ALL = EncryptionTypeFlag.NONE | EncryptionTypeFlag.WEP | EncryptionTypeFlag.TKIP | EncryptionTypeFlag.AES

class ConnectionTypeFlag(object):
    ESS = 0x01
    IBSS = 0x02
    
class ConfigMethod(object):
    USBA = 0x0001
    ETHERNET = 0x0002
    LABEL = 0x0004
    DISPLAY = 0x0008
    EXT_NFC_TOKEN = 0x0010
    INT_NFC_TOKEN = 0x0020
    NFC_INTERFACE = 0x0040
    PUSHBUTTON = 0x0080
    KEYPAD = 0x0100
    
    
class OpCode(object):
    WSC_START = 0x01
    WSC_ACK = 0x02
    WSC_NACK = 0x03
    WSC_MSG = 0x04
    WSC_DONE = 0x05
    WSC_FRAG_ACK = 0x06
    
class AssocState(object):
    NOT_ASSOC = 0
    CONN_SUCCESS = 1
    CFG_FAILURE = 2
    FAILURE = 3,
    IP_FAILURE = 4
    
class ConfigError(object):
    NO_ERROR = 0
    OOB_IFACE_READ_ERROR = 1
    DECRYPTION_CRC_FAILURE = 2
    _24_CHAN_NOT_SUPPORTED = 3
    _50_CHAN_NOT_SUPPORTED = 4
    SIGNAL_TOO_WEAK = 5
    NETWORK_AUTH_FAILURE = 6
    NETWORK_ASSOC_FAILURE = 7
    NO_DHCP_RESPONSE = 8
    FAILED_DHCP_CONFIG = 9
    IP_ADDR_CONFLICT = 10
    NO_CONN_TO_REGISTRAR = 11
    MULTIPLE_PBC_DETECTED = 12
    ROGUE_SUSPECTED = 13
    DEVICE_BUSY = 14
    SETUP_LOCKED = 15
    MSG_TIMEOUT = 16
    REG_SESS_TIMEOUT = 17
    DEV_PASSWORD_AUTH_FAILURE = 18
    
class DevicePasswordId(object):
    DEFAULT = 0x0000
    USER_SPECIFIED = 0x0001
    MACHINE_SPECIFIED = 0x0002
    REKEY = 0x0003
    PUSHBUTTON = 0x0004
    REGISTRAR_SPECIFIED = 0x0005
    
class WpsState(object):
    NOT_CONFIGURED = 0x01
    CONFIGURED = 0x02
    

class SimpleConfig(ProtocolPacket):
    "For now, it supports Simple configs with the bits more_fragments and length_field not set"
    
    header_size = 2
    tail_size = 0

    op_code = Byte(0)
    flags = Byte(1)
    more_fragments = Bit(1, 0)
    length_field = Bit(1,1)
    
    BUILDERS = {
        SCElem.CONNECTION_TYPE: ByteBuilder(),
        SCElem.CONNECTION_TYPE_FLAGS: ByteBuilder(),
        SCElem.VERSION: ByteBuilder(),
        SCElem.MESSAGE_TYPE: ByteBuilder(),
        SCElem.NETWORK_INDEX: ByteBuilder(),
        SCElem.NETWORK_KEY_INDEX: ByteBuilder(),
        SCElem.POWER_LEVEL: ByteBuilder(),
        SCElem.PSK_CURRENT: ByteBuilder(),
        SCElem.PSK_MAX: ByteBuilder(),
        SCElem.REGISTRAR_CURRENT: ByteBuilder(),
        SCElem.REGISTRAR_MAX: ByteBuilder(),
        SCElem.REQUEST_TYPE: ByteBuilder(),
        SCElem.RESPONSE_TYPE: ByteBuilder(),
        SCElem.RF_BANDS: ByteBuilder(),
        SCElem.WPS_STATE: ByteBuilder(),
        SCElem.TOTAL_NETWORKS: ByteBuilder(),
        SCElem.VERSION: ByteBuilder(),
        SCElem.WEP_TRANSMIT_KEY: ByteBuilder(),
        
        SCElem.CONFIRMATION_URL4: StringBuilder(),
        SCElem.CONFIRMATION_URL6: StringBuilder(),
        SCElem.DEVICE_NAME: StringBuilder(),
        SCElem.IDENTITY: StringBuilder(),
        SCElem.MANUFACTURER: StringBuilder(),
        SCElem.MODEL_NAME: StringBuilder(),
        SCElem.MODEL_NUMBER: StringBuilder(),
        SCElem.NEW_DEVICE_NAME: StringBuilder(),
        SCElem.NEW_PASSWORD: StringBuilder(),
        SCElem.SERIAL_NUMBER: StringBuilder(),
        SCElem.EAP_IDENTITY: StringBuilder(),
        SCElem.NETWORK_KEY: StringBuilder(),
            
        SCElem.AP_CHANNEL: NumBuilder(2),
        SCElem.ASSOCIATION_STATE: NumBuilder(2),
        SCElem.AUTHENTICATION_TYPE: NumBuilder(2),
        SCElem.AUTHENTICATION_TYPE_FLAGS: NumBuilder(2),
        SCElem.CONFIG_METHODS: NumBuilder(2),
        SCElem.CONFIGURATION_ERROR: NumBuilder(2),
        SCElem.DEVICE_PASSWORD_ID: NumBuilder(2),
        SCElem.ENCRYPTION_TYPE: NumBuilder(2),
        SCElem.ENCRYPTION_TYPE_FLAGS: NumBuilder(2),
        SCElem.MESSAGE_COUNTER: NumBuilder(8),       
        SCElem.KEY_LIFETIME: NumBuilder(4),
        SCElem.PERMITTED_CONFIG_METHODS: NumBuilder(2),
        SCElem.SELECTED_REGISTRAR_CONFIG_METHODS: NumBuilder(2),
        SCElem.PUBLIC_KEY: NumBuilder(192),

    }
    
    @classmethod
    def build_tlv_container(cls):
        return TLVContainer(
            builders=SimpleConfig.BUILDERS, 
            descs = dict( (v,k) for (k,v) in SCElem.__dict__.iteritems() )
        )