This file is indexed.

/usr/lib/python2.7/dist-packages/framework/subsystems/ogsmd/modems/abstract/pdp.py is in fso-frameworkd 0.10.1-3.

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
#!/usr/bin/env python
"""
The Open GSM Daemon - Python Implementation

(C) 2008 Michael 'Mickey' Lauer <mlauer@vanille-media.de>
(C) 2008 Openmoko, Inc.
GPLv2 or later

This module is based on pyneod/pypppd.py (C) 2008 M. Dietrich.

Package: ogsmd.modems.abstract
Module: pdp

"""

__version__ = "0.3.0"
MODULE_NAME = "ogsmd.modems.abstract.pdp"

from .mediator import AbstractMediator
from .overlay import OverlayFile

from framework.patterns.kobject import KObjectDispatcher
from framework.patterns.processguard import ProcessGuard

import gobject
import os, subprocess, signal, copy

import logging
logger = logging.getLogger( MODULE_NAME )

#=========================================================================#
class Pdp( AbstractMediator ):
#=========================================================================#
    """
    Encapsulates the state of (all) PDP connections on a modem
    """

    _instance = None

    @classmethod
    def getInstance( klass, dbus_object=None ):
        if klass._instance is None and dbus_object is not None:
            klass._instance = Pdp( dbus_object )
        return klass._instance

    def __init__( self, dbus_object, **kwargs ):
        AbstractMediator.__init__( self, dbus_object, None, None, **kwargs )
        self._callchannel = self._object.modem.communicationChannel( "PdpMediator" )
        self._netchannel = self._object.modem.communicationChannel( "NetworkMediator" )

        self.state = "release" # initial state
        self.ppp = None
        self.overlays = []

        # FIXME: add match only while running pppd
        KObjectDispatcher.addMatch( "addlink", "", self._onAddLinkEvent )

    def _onInterfaceChange( action, path, **kwargs ):
        logger.debug( "detected interface change", action, path )

    #
    # public
    #
    def setParameters( self, apn, user, password ):
        self.pds = copy.copy( self.__class__.PPP_DAEMON_SETUP )
        self.pds[self.__class__.PPP_CONNECT_CHAT_FILENAME] = self.__class__.PPP_DAEMON_SETUP[self.__class__.PPP_CONNECT_CHAT_FILENAME] % apn

        apn, user, password = str(apn), str(user), str(password)

        # check whether pppd needs to handle setup and teardown
        if self._object.modem.data( "pppd-does-setup-and-teardown" ):
            # merge with modem specific options
            self.ppp_options = self.__class__.PPP_OPTIONS_GENERAL + self._object.modem.data( "pppd-configuration" )
        else:
            self.ppp_options = self._object.modem.data( "pppd-configuration" )

        # merge with user and password settings
        if user:
            logger.info( "configuring ppp for user '%s' w/ password '%s'" % ( user, password ) )
            self.ppp_options += [ "user", user ]
            self.pds[self.__class__.PPP_PAP_SECRETS_FILENAME] = '%s * "%s" *\n' % ( user or '*', password )
            self.pds[self.__class__.PPP_CHAP_SECRETS_FILENAME] =  '%s * "%s" *\n'% ( user or '*', password )

        self.childwatch_source = None

    def isActive( self ):
        return self.state == "active"

    def activate( self ):
        self._activate()

    def deactivate( self ):
        self._deactivate()

    def status( self ):
        return self.state

    #
    # private
    #
    def _prepareFiles( self ):
        for filename, overlay in self.pds.iteritems():
            logger.debug( "preparing file %s" % filename )
            f = OverlayFile( filename, overlay=overlay )
            f.store()
            self.overlays.append( f )

    def _recoverFiles( self ):
        for f in self.overlays:
            logger.debug( "recovering file %s" % f.name )
            f.restore()
        self.overlays = []

    def _activate( self ):
        if self.ppp is not None and self.ppp.isRunning():
            raise Exception( "already active" )

        self.port = str( self._object.modem.dataPort() )
        if not self.port:
            raise Exception( "no device" )

        logger.debug( "activate got port %s" % self.port )
        ppp_commandline = [ self.__class__.PPP_BINARY, self.port ] + self.ppp_options
        logger.info( "launching ppp as commandline %s" % ppp_commandline )

        self._prepareFiles()
        self.ppp = ProcessGuard( ppp_commandline )
        self.ppp.execute( onExit=self._spawnedProcessDone, onError=self._onPppError, onOutput=self._onPppOutput )

        logger.info( "pppd launched. See syslog (e.g. logread -f) for output." )

        # FIXME that's somewhat premature. we might adopt the following states:
        # "setup", "active", "shutdown", "release"

        self._updateState( "outgoing" )

    def _updateState( self, newstate ):
        if newstate != self.state:
            self.state = newstate
            self._object.ContextStatus( 1, newstate, {} )

    def _deactivate( self ):
        logger.info( "shutting down pppd" )
        self.ppp.shutdown()

    def _spawnedProcessDone( self, pid, exitcode, exitsignal ):
        logger.info( "pppd exited with code %d, signal %d" % ( exitcode, exitsignal ) )

        # FIXME check whether this was a planned exit or not, if not, try to recover

        self._updateState( "release" )
        self._recoverFiles()

        # FIXME at this point, the default route might be wrong, if someone killed pppd

        # force releasing context and attachment to make sure that
        # the next ppp setup will find the data port in command mode
        self._netchannel.enqueue( "+CGACT=0;+CGATT=0", lambda a,b:None, lambda a,b:None )

    def _onAddLinkEvent( self, action, path, **properties ):
        """
        Called by KObjectDispatcher
        """
        try:
            device = properties["dev"]
            flags = properties["flags"]
        except KeyError:
            pass # not enough information
        else:
            if device == "ppp0" and "UP" in flags:
                self._updateState( "active" )

    def _onPppError( self, text ):
        print "ppp error:", repr(text)

    def _onPppOutput( self, text ):
        print "ppp output:", repr(text)

    # class wide constants constants

    PPP_CONNECT_CHAT_FILENAME = "/var/tmp/ogsmd/gprs-connect-chat"
    PPP_DISCONNECT_CHAT_FILENAME = "/var/tmp/ogsmd/gprs-disconnect-chat"

    PPP_PAP_SECRETS_FILENAME = "/etc/ppp/pap-secrets"
    PPP_CHAP_SECRETS_FILENAME = "/etc/ppp/chap-secrets"

    PPP_OPTIONS_GENERAL = [ "connect", PPP_CONNECT_CHAT_FILENAME, "disconnect", PPP_DISCONNECT_CHAT_FILENAME ]

    PPP_BINARY = "/usr/sbin/pppd"

    PPP_DAEMON_SETUP = {}

    PPP_DAEMON_SETUP[ PPP_CONNECT_CHAT_FILENAME ] = r"""#!/bin/sh -e
exec /usr/sbin/chat -v\
    'ABORT' 'BUSY'\
    'ABORT' 'DELAYED'\
    'ABORT' 'ERROR'\
    'ABORT' 'NO ANSWER'\
    'ABORT' 'NO CARRIER'\
    'ABORT' 'NO DIALTONE'\
    'ABORT' 'RINGING'\
    'ABORT' 'VOICE'\
    'TIMEOUT' '5'\
    '' '+++AT'\
    'OK-\k\k\k\d+++ATH-OK' 'ATE0Q0V1'\
    'OK' 'AT+CMEE=2'\
    'OK' 'AT+CGDCONT=1,"IP","%s"'\
    'TIMEOUT' '180'\
    'OK' 'ATD*99#'\
    'CONNECT' '\d\c'
"""

    PPP_DAEMON_SETUP[ PPP_DISCONNECT_CHAT_FILENAME ] = r"""#!/bin/sh -e
echo disconnect script running...
"""

    PPP_DAEMON_SETUP["/etc/ppp/ip-up.d/08setupdns"] = """#!/bin/sh -e
cp /var/run/ppp/resolv.conf /etc/resolv.conf
"""

    PPP_DAEMON_SETUP["/etc/ppp/ip-down.d/92removedns"] = """#!/bin/sh -e
echo nameserver 127.0.0.1 > /etc/resolv.conf
"""

    PPP_DAEMON_SETUP[PPP_PAP_SECRETS_FILENAME] = '* * "%s" *\n' % ''

    PPP_DAEMON_SETUP[PPP_CHAP_SECRETS_FILENAME] =  '* * "%s" *\n'% ''

#=========================================================================#
if __name__ == "__main__":
#=========================================================================#
    pass