This file is indexed.

/usr/lib/python3/dist-packages/wormhole/_interfaces.py is in magic-wormhole 0.10.3-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
from zope.interface import Interface

# These interfaces are private: we use them as markers to detect
# swapped argument bugs in the various .wire() calls

class IWormhole(Interface):
    """Internal: this contains the methods invoked 'from below'."""
    def got_welcome(welcome):
        pass
    def got_code(code):
        pass
    def got_key(key):
        pass
    def got_verifier(verifier):
        pass
    def got_versions(versions):
        pass
    def received(plaintext):
        pass
    def closed(result):
        pass

class IBoss(Interface):
    pass
class INameplate(Interface):
    pass
class IMailbox(Interface):
    pass
class ISend(Interface):
    pass
class IOrder(Interface):
    pass
class IKey(Interface):
    pass
class IReceive(Interface):
    pass
class IRendezvousConnector(Interface):
    pass
class ILister(Interface):
    pass
class ICode(Interface):
    pass
class IInput(Interface):
    pass
class IAllocator(Interface):
    pass
class ITerminator(Interface):
    pass

class ITiming(Interface):
    pass
class ITorManager(Interface):
    pass
class IWordlist(Interface):
    def choose_words(length):
        """Randomly select LENGTH words, join them with hyphens, return the
        result."""
    def get_completions(prefix):
        """Return a list of all suffixes that could complete the given
        prefix."""

# These interfaces are public, and are re-exported by __init__.py

class IDeferredWormhole(Interface):
    def get_welcome():
        """
        Wait for the 'welcome message' dictionary, sent by the server upon
        first connection.

        :rtype: ``Deferred[dict]``
        :return: the welcome dictionary, when it arrives from the server
        """

    def allocate_code(code_length=2):
        """
        Ask the wormhole to allocate a nameplate and generate a random code.

        When the code is ready, any Deferreds returned by ``get_code()`` will
        be fired.  Only one of generate_code/set_code/input_code may be used.

        :param int code_length: the number of random words to use.  More
            words means the code is harder to guess.  Defaults to 2.

        :return: None

            ~mod.class
        """

    def set_code(code):
        """
        Tell the wormhole to use a specific code, either copied from a
        wormhole that used ``allocate_code``, or created out-of-band by
        humans (and given to ``set_code`` on both wormholes).

        Any Deferreds returned by ``get_code()`` will be fired as soon as
        this is called.  Only one of generate_code/set_code/input_code may be
        used.

        :return: None
        """

    def input_code():
        """
        Ask the wormhole to perform interactive entry of the code, with
        completion on the nameplate and/or words.

        This does not actually interact with the user, but instead returns a
        'code-entry helper' object.  The application is responsible for doing
        the IO: the helper is used to get completion lists and to submit the
        finished code.  See ``input_with_completion`` for a wrapper function
        that uses ``readline`` to do CLI-style input completion.

        Any Deferreds returned by ``get_code()`` will be fired when the final
        code is submitted to the helper.  Only one of
        generate_code/set_code/input_code may be used.

        :return: a code-entry helper instance
        :rtype: IHelper
        """

    def get_code():
        """
        Wait for the wormhole code to be established, then return the code.
        This is really only useful on the initiating side, which needs to
        deliver the code to the user (so the user can dictate it to the other
        user, who can deliver it to their application with ``set_code`` or
        ``input_code``).  On the receiving side, merely submitting the code
        is sufficient.

        The wormhole code is always unicode (so ``str`` on py3, ``unicode``
        on py2).

        For ``allocate_code``, this must wait for the server to allocate a
        nameplate.  For ``input_code``, it waits for the final code to be
        submitted to the helper.  For ``set_code``, it fires immediately.

        :return: the wormhole code
        :rtype: ``Deferred[str]``
        """

    def get_unverified_key():
        """
        Wait for key-exchange to occur, then return the raw unverified SPAKE2
        key.  When this fires, we have not seen any evidence that anyone else
        shares this key (nor have we seen evidence of a failed attack: e.g. a
        payload encrypted with a different key).

        This is only useful for testing, and for noticing a significant delay
        between the key-agreement message and the subsequent key-verification
        ("versions") message.

        :return: the raw unverified SPAKE2 key
        :rtype: ``Deferred[bytes]``
        """

    def get_verifier():
        """
        Wait for key verification to occur, then return the verifier string.
        When this fires, we have seen at least one validly-encrypted message
        from our peer, indicating that we have established a shared secret
        key with some party who knows (or correctly guessed) the wormhole
        code.

        The verifier string (bytes) can be displayed to the user (perhaps as
        hex), who can manually compare it with the peer's verifier, to obtain
        more confidence in the secrecy of the established key.

        If we receive an invalid encrypted message (such as what would happen
        if an attacker tried and failed to guess the wormhole code), this
        will instead errback with a ``WrongPasswordError``.

        :return: the verifier string, after a valid encrypted message has
                 arrived
        :rtype: ``Deferred[bytes]``
        """

    def get_versions():
        """
        Wait for a valid VERSION message to arrive, then return the peer's
        "versions" dictionary.  This dictionary comes from the ``versions=``
        argument to the peer's ``wormhole()`` constructor, and is meant to
        assist with capability-negotiation between the two peers.  In
        particular, the ``versions`` dictionary is delivered before either
        side has called ``send_message()``, so it can influence the first
        message sent to a peer that is too old to use that first message for
        negotiation purposes.

        If we receive any invalid encrypted message (such as what would
        happen if an attacker tried and failed to guess the wormhole code),
        this will instead errback with a ``WrongPasswordError``.

        :return: the verisions dictionary
        :rtype: ``Deferred[dict]``
        """

    def derive_key(purpose, length):
        """
        Derive a purpose-specific key.

        This combines the master SPAKE2 key with the given purpose string and
        deterministically derives a new key of the requested length.  Any two
        connected Wormhole objects which call ``derive_key`` with the same
        purpose and length will get the same key.  This can be used to
        encrypt or sign other messages, or exchanged for verification
        purposes.  The master key will remain secret even if you reveal a
        derivative key.

        This must be called after the key has been established, so after any
        of
        ``get_unverified_key()/get_verifier()/get_versions()/get_message()``
        have fired.  ``derive_key()`` returns immediately, rather than
        returning a ``Deferred``.

        :return: a derivative key, of the requested length
        :rtype: ``bytes``
        """

    def send_message(msg):
        """
        Send a message to the connected peer.

        This accepts a bytestring, and queues it for encryption and delivery
        to the other side, where it will eventually appear in
        ``get_message()``.  Messages are delivered in-order, and complete
        (the Wormhole is a record-pipe, not a byte-pipe).

        This can be called at any time, even before setting the wormhole
        code.  The message will be queued for delivery after the master key
        is established.

        :return: None
        """

    def get_message():
        """
        Wait for, and return, the next message.

        This returns a Deferred that will fire when the next (sequential)
        application message has been received and successfully decrypted.
        Messages will be delivered in-order and intact (the Wormhole is a
        record-pipe, not a byte-pipe).

        This can be called at any time, even before setting the wormhole
        code.  The Deferred will not fire until key-negotiation has completed
        and a validly-encrypted message has arrived.

        If we receive any invalid encrypted message (such as what would
        happen if an attacker tried and failed to guess the wormhole code),
        this will instead errback with a ``WrongPasswordError``.

        :return: the next decrypted message
        :rtype: ``Deferred[bytes]``
        """

    def close():
        """
        Close the wormhole.

        This frees all resources associated with the wormhole (including
        server-side queues and any established network connections).

        For operational purposes, it informs the server that the wormhole
        closed "happy".  Less-happy moods may be reported if the connection
        closed due to a ``WrongPasswordError`` or because of a timeout.

        ``close()`` returns a Deferred, which fires after the server has been
        informed and the sockets have been shut down.  One-shot applications
        should delay shutdown until this Deferred has fired, to increase the
        chances that server resources will be freed.  Long-running
        applications can probably ignore the Deferred, as they'll probably
        remain running long enough to allow the shutdown to complete.

        The Deferred will errback if the wormhole had problems, like a
        ``WrongPasswordError``.

        :return: a Deferred that fires when shutdown is complete
        :rtype: ``Deferred``
        """

class IInputHelper(Interface):
    def refresh_nameplates():
        """
        Refresh the nameplates list.

        This asks the server for the set of currently-active nameplates
        (either from calls to ``allocate_code()`` or referenced by active
        wormhole clients).  It updates the set available to
        ``get_nameplate_completions()``.

        :return: None
        """

    def get_nameplate_completions(prefix):
        """
        Return a list of nameplate completions for the given prefix.

        This takes the most-recently-received set of active nameplates from
        the rendezvous server, finds the subset that start with the given
        prefix, and returns the result.  The result strings include the
        prefix and the terminating hyphen, in random order.

        This returns synchronously: it does not wait for a server response.
        If called before getting any response from the server, it will return
        an empty set.  If user input causes completion, it may be a good idea
        to kick off a new ``refresh_nameplates()`` too, in case the user is
        bouncing on the TAB key in the hopes of seeing their expected
        nameplate appear in the list eventually.

        :param str prefix: the nameplate as typed so far

        :return: a set of potential completions
        :rtype: set[str]
        """

    def choose_nameplate(nameplate):
        """
        Commit to a nameplate, allowing the word-completion phase to begin.

        This may only be called once.  Calling it a second time will raise
        ``AlreadyChoseNameplateError``.

        :param str nameplate: the complete nameplate, without a trailing
            hyphen

        :return: None
        """

    def when_wordlist_is_available():
        """
        Wait for the wordlist to be available.

        This fires when the wordlist is available, which means
        ``get_word_completions()`` is able to return a non-empty set.  This
        requires the nameplate be submitted, and may also require some server
        interaction (to claim the channel and learn a channel-specific
        wordlist, e.g. for i18n language selection).

        :return: a ``Deferred`` that fires when the wordlist is available
        :rtype: Deferred[None]
        """

    def get_word_completions(prefix):
        """
        Return a list of word completions for the given prefix.

        This takes the claimed channel's wordlist, finds the subset that
        start with the given prefix, and returns the result.  The result
        strings include the prefix and the terminating hyphen, in random
        order.

        The prefix should not include the nameplate, but should include
        whatever words have been selected so far (the default uses separate
        odd/even wordlists, which means the completion for a single string
        depends upon how many words have been entered so far).

        This returns synchronously: it does not wait for a server response.
        If called before getting the wordlist, it will return an empty set.

        If called before ``choose_nameplate()``, this will raise
        ``MustChooseNameplateFirstError``.  If called after
        ``choose_words()``, this will raise ``AlreadyChoseWordsError``.

        :param str prefix: the words typed so far

        :return: a set of potential completions
        :rtype: set[str]
        """

    def choose_words(words):
        """
        Submit the final words.

        This should be called when the user is finished typing in the code,
        and terminates the code-entry process.  It does not return anything,
        but will cause the Wormhole's ``w.get_code()`` to fire, and initiates
        the wormhole connection process.

        It accepts a string like "purple-sausages", without the leading
        nameplate (which must have been submitted to ``choose_nameplate()``
        earlier) or its hyphen.  If ``choose_nameplate()`` was not called
        first, this will raise ``MustChooseNameplateFirstError``.

        This may only be called once, otherwise ``AlreadyChoseWordsError``
        will be raised.

        :param str words: the 'words' portion of the wormhole code

        :return: None
        """


class IJournal(Interface): # TODO: this needs to be public
    pass