This file is indexed.

/usr/share/pyshared/desktopcouch/application/platform/linux/keyring.py is in python-desktopcouch-application 1.0.8-0ubuntu3.

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
# Copyright 2009 Canonical Ltd.
#
# This file is part of desktopcouch.
#
#  desktopcouch is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# as published by the Free Software Foundation.
#
# desktopcouch is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with desktopcouch.  If not, see <http://www.gnu.org/licenses/>.
#
# Author: Manuel de la Pena <manuel.delapena@canonical.com>
"""Keyring used to store secrets."""
import logging

import gnomekeyring

from desktopcouch.application.util import make_random_string


class Keyring(object):
    """Represent the keyring storage used to store secrets"""

    def __init__(self, make_random_string_fn=make_random_string,
                 keyring=gnomekeyring):
        self.keyring = keyring
        self.make_random_string = make_random_string_fn

    def get_user_name_password(self):
        """Return the user name and passwd used to access desktopcouch."""
        admin_username = None
        admin_password = None
        try:
            data = self.keyring.find_items_sync(
                self.keyring.ITEM_GENERIC_SECRET,
                {'desktopcouch': 'basic'})
            admin_username, admin_password = data[0].secret.split(":", 1)
        except (gnomekeyring.IOError, gnomekeyring.NoMatchError):
            # generate the random strings to be used as username and psswd
            admin_username = self.make_random_string(10)
            admin_password = self.make_random_string(10)
            try:
                # save admin account details in keyring
                self.keyring.item_create_sync(
                    None,
                    gnomekeyring.ITEM_GENERIC_SECRET,
                    'Desktop Couch user authentication',
                    {'desktopcouch': 'basic'},
                    ":".join([admin_username, admin_password]), True)
            except gnomekeyring.NoKeyringDaemonError:
                logging.warn(
                    "There is no keyring to store our admin credentials.")
            except gnomekeyring.CancelledError:
                logging.warn(
                    "There is no keyring to store our admin credentials.")
            except gnomekeyring.IOError:
                logging.warn(
                    "There is no keyring to store our admin credentials.")
        return (admin_username, admin_password)

    def get_oauth_data(self):
        """Return the oauth data used to connect with couchdb."""
        consumer_key = self.make_random_string(10)
        consumer_secret = self.make_random_string(10)
        token = self.make_random_string(10)
        token_secret = self.make_random_string(10)
        # Save the new OAuth creds so that 3rd-party
        # apps can authenticate by accessing the keyring first.
        # This is one-way, we don't read from keyring.
        try:
            self.keyring.item_create_sync(
                None,
                gnomekeyring.ITEM_GENERIC_SECRET,
                'Desktop Couch user authentication', {'desktopcouch': 'oauth'},
                ":".join([consumer_key, consumer_secret, token, token_secret]),
                True)
        except gnomekeyring.IOError:
            # in this case we do not have a major issue, continue and return
            logging.warn("There is no keyring to store our admin credentials.")
        except gnomekeyring.NoKeyringDaemonError:
            # in this case we do not have a major issue, continue and return
            logging.warn("There is no keyring to store our oauth credentials.")
        except gnomekeyring.CancelledError:
            # in this case we do not have a major issue, continue and return
            logging.warn("There is no keyring to store our admin credentials.")
        return (consumer_key, consumer_secret, token, token_secret)


class TestSecret(object):
    """Test secret."""
    def __init__(self, secret):
        self.secret = secret


class TestKeyring(object):
    """A gnomekeyring replacement that isolates us from the users keyring."""

    def __init__(self, appear_absent=False):
        self.appear_absent = appear_absent
        self.items = {}

    def _get_key(self, attributes):     # pylint: disable=R0201
        """Get key."""
        return "".join([str(a) for a in sorted(attributes.items())])

    def find_items_sync(self, item_type, attributes):
        """Find items sync."""
        key = self._get_key(attributes)
        if item_type in self.items and key in self.items[item_type]:
            return [TestSecret(self.items[item_type][key])]
        raise gnomekeyring.NoMatchError

    # pylint: disable=W0613
    def item_create_sync(self, keyring, item_type, display_name, attributes,
                         secret, update_if_exists):
        """Item create sync."""
        assert keyring is None, "Mock not coded to have multiple keyrings"
        assert update_if_exists is True, "Mock not coded to create duplicates"
        if self.appear_absent:
            raise gnomekeyring.NoKeyringDaemonError
        self.items.setdefault(item_type, {})
        key = self._get_key(attributes)
        self.items[item_type][key] = secret
        return "Mock keyring doesn't have item ids"
    # pylint: enable=W0613

    def get_user_name_password(self):
        """Return the user name and passwd used to access desktopcouch."""
        admin_username = None
        admin_password = None
        try:
            data = self.find_items_sync(gnomekeyring.ITEM_GENERIC_SECRET,
                {'desktopcouch': 'basic'})
            admin_username, admin_password = data[0].secret.split(":", 1)
        except gnomekeyring.NoMatchError:
            # generate the random strings to be used as username and psswd
            admin_username = make_random_string(10)
            admin_password = make_random_string(10)
            try:
                # save admin account details in keyring
                self.item_create_sync(
                    None,
                    gnomekeyring.ITEM_GENERIC_SECRET,
                    'Desktop Couch user authentication',
                    {'desktopcouch': 'basic'},
                    ":".join([admin_username, admin_password]), True)
            except gnomekeyring.NoKeyringDaemonError:
                # in this case we do not have a major issue, continue & return
                pass
            except gnomekeyring.CancelledError:
                # in this case we do not have a major issue, continue & return
                pass
        return (admin_username, admin_password)

    def get_oauth_data(self):
        """Return the oauth data used to connect with couchdb."""
        consumer_key = make_random_string(10)
        consumer_secret = make_random_string(10)
        token = make_random_string(10)
        token_secret = make_random_string(10)

        try:
            self.item_create_sync(
                None,
                gnomekeyring.ITEM_GENERIC_SECRET,
                'Desktop Couch user authentication', {'desktopcouch': 'oauth'},
                ":".join([consumer_key, consumer_secret, token, token_secret]),
                True)
        except gnomekeyring.NoKeyringDaemonError:
            # in this case we do not have a major issue, continue and return
            pass
        except gnomekeyring.CancelledError:
            # in this case we do not have a major issue, continue and return
            pass
        return (consumer_key, consumer_secret, token, token_secret)