示例#1
0
 def sstpMsgCallConnectRequestReceived(self, protocolId):
     if self.state in (CALL_ABORT_TIMEOUT_PENDING, CALL_ABORT_PENDING,
             CALL_DISCONNECT_ACK_PENDING, CALL_DISCONNECT_TIMEOUT_PENDING):
         return
     if self.state != SERVER_CONNECT_REQUEST_PENDING:
         logging.warn('Not in the state.')
         self.transport.loseConnection()
         return
     if protocolId != SSTP_ENCAPSULATED_PROTOCOL_PPP:
         logging.warn('Unsupported encapsulated protocol.')
         nak = SSTPControlPacket(SSTP_MSG_CALL_CONNECT_NAK)
         nak.attributes = [(SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID,
                 ATTRIB_STATUS_VALUE_NOT_SUPPORTED)]
         self.addRetryCounterOrAbrot()
         return
     self.nonce = os.urandom(32)
     ack = SSTPControlPacket(SSTP_MSG_CALL_CONNECT_ACK)
     # 3 bytes reserved + 1 byte hash bitmap (SHA-1 only) + nonce.
     ack.attributes = [(SSTP_ATTRIB_CRYPTO_BINDING_REQ,
             '\x00\x00\x00' + '\x03' + self.nonce)]
     ack.writeTo(self.transport.write)
     self.pppd = PPPDProtocol()
     self.pppd.sstp = self
     self.pppd.remote = self.factory.remotePool.apply()
     if self.pppd.remote is None:
         logging.warn('IP address pool is full. '
                 'Cannot accpet new connection.')
         self.abort()
     addressArgument = '%s:%s' % (self.factory.local, self.pppd.remote)
     reactor.spawnProcess(self.pppd, self.factory.pppd,
             args=['local', 'file', self.factory.pppdConfigFile,
                 '115200', addressArgument], usePTY=True)
     self.transport.registerProducer(self.pppd, True)
     self.pppd.resumeProducing()
     self.state = SERVER_CALL_CONNECTED_PENDING
示例#2
0
 def sstpMsgEchoRequest(self):
     if self.state == SERVER_CALL_CONNECTED:
         response = SSTPControlPacket(SSTP_MSG_ECHO_RESPONSE)
         response.writeTo(self.transport.write)
     elif self.state in (CALL_ABORT_TIMEOUT_PENDING, CALL_ABORT_PENDING,
             CALL_DISCONNECT_ACK_PENDING, CALL_DISCONNECT_TIMEOUT_PENDING):
         return
     self.abort(ATTRIB_STATUS_UNACCEPTED_FRAME_RECEIVED)
示例#3
0
 def sstpMsgEchoRequest(self):
     if self.state == SERVER_CALL_CONNECTED:
         response = SSTPControlPacket(SSTP_MSG_ECHO_RESPONSE)
         response.writeTo(self.transport.write)
     elif self.state in (CALL_ABORT_TIMEOUT_PENDING, CALL_ABORT_PENDING,
             CALL_DISCONNECT_ACK_PENDING, CALL_DISCONNECT_TIMEOUT_PENDING):
         return
     self.abort(ATTRIB_STATUS_UNACCEPTED_FRAME_RECEIVED)
示例#4
0
 def sstpMsgCallDisconnect(self, status=None):
     if self.state in (CALL_ABORT_TIMEOUT_PENDING, CALL_ABORT_PENDING,
             CALL_DISCONNECT_TIMEOUT_PENDING):
         return
     logging.info('Received call disconnect request.')
     self.state = CALL_DISCONNECT_IN_PROGRESS_2
     ack = SSTPControlPacket(SSTP_MSG_CALL_DISCONNECT_ACK)
     ack.writeTo(self.transport.write)
     self.state = CALL_DISCONNECT_TIMEOUT_PENDING
     reactor.callLater(1, self.transport.loseConnection)
示例#5
0
 def sstpMsgCallDisconnect(self, status=None):
     if self.state in (CALL_ABORT_TIMEOUT_PENDING, CALL_ABORT_PENDING,
             CALL_DISCONNECT_TIMEOUT_PENDING):
         return
     logging.info('Received call disconnect request.')
     self.state = CALL_DISCONNECT_IN_PROGRESS_2
     ack = SSTPControlPacket(SSTP_MSG_CALL_DISCONNECT_ACK)
     ack.writeTo(self.transport.write)
     self.state = CALL_DISCONNECT_TIMEOUT_PENDING
     reactor.callLater(1, self.transport.loseConnection)
示例#6
0
 def helloTimerExpired(self, close=False):
     if self.state == SERVER_CALL_DISCONNECTED:
         self.transport.loseConnection()  # TODO: follow HTTP
     elif close:
         logging.warn('Ping time out.')
         self.abort(ATTRIB_STATUS_NEGOTIATION_TIMEOUT)
     else:
         logging.info('Send echo request.')
         echo = SSTPControlPacket(SSTP_MSG_ECHO_REQUEST)
         echo.writeTo(self.transport.write)
         self.helloTimer = reactor.callLater(60, self.helloTimerExpired, True)
示例#7
0
 def helloTimerExpired(self, close=False):
     if self.state == SERVER_CALL_DISCONNECTED:
         self.transport.loseConnection()  # TODO: follow HTTP
     elif close:
         logging.warn('Ping time out.')
         self.abort(ATTRIB_STATUS_NEGOTIATION_TIMEOUT)
     else:
         logging.info('Send echo request.')
         echo = SSTPControlPacket(SSTP_MSG_ECHO_REQUEST)
         echo.writeTo(self.transport.write)
         self.helloTimer = reactor.callLater(60, self.helloTimerExpired, True)
示例#8
0
 def pppStoped(self):
     if (self.state != SERVER_CONNECT_REQUEST_PENDING and
             self.state != SERVER_CALL_CONNECTED_PENDING and
             self.state != SERVER_CALL_CONNECTED):
         self.transport.loseConnection()
         return
     self.state = CALL_DISCONNECT_IN_PROGRESS_1
     msg = SSTPControlPacket(SSTP_MSG_CALL_DISCONNECT)
     msg.attributes = [(SSTP_ATTRIB_NO_ERROR, ATTRIB_STATUS_NO_ERROR)]
     msg.writeTo(self.transport.write)
     self.state = CALL_DISCONNECT_ACK_PENDING
     reactor.callLater(5, self.transport.loseConnection)
示例#9
0
 def abort(self, status=None):
     if status is None:
         logging.warn('Abort.')
     else:
         logging.warn('Abort (%s).' % ord(status[-1]))
     self.state = CALL_DISCONNECT_IN_PROGRESS_1
     msg = SSTPControlPacket(SSTP_MSG_CALL_ABORT)
     if status is not None:
         msg.attributes = [(SSTP_ATTRIB_STATUS_INFO, status)]
     msg.writeTo(self.transport.write)
     self.state = CALL_ABORT_PENDING
     reactor.callLater(3, self.transport.loseConnection)
示例#10
0
 def pppStoped(self):
     if (self.state != SERVER_CONNECT_REQUEST_PENDING and
             self.state != SERVER_CALL_CONNECTED_PENDING and
             self.state != SERVER_CALL_CONNECTED):
         self.transport.loseConnection()
         return
     self.state = CALL_DISCONNECT_IN_PROGRESS_1
     msg = SSTPControlPacket(SSTP_MSG_CALL_DISCONNECT)
     msg.attributes = [(SSTP_ATTRIB_NO_ERROR, ATTRIB_STATUS_NO_ERROR)]
     msg.writeTo(self.transport.write)
     self.state = CALL_DISCONNECT_ACK_PENDING
     reactor.callLater(5, self.transport.loseConnection)
示例#11
0
 def abort(self, status=None):
     if status is None:
         logging.warn('Abort.')
     else:
         logging.warn('Abort (%s).' % ord(status[-1]))
     self.state = CALL_DISCONNECT_IN_PROGRESS_1
     msg = SSTPControlPacket(SSTP_MSG_CALL_ABORT)
     if status is not None:
         msg.attributes = [(SSTP_ATTRIB_STATUS_INFO, status)]
     msg.writeTo(self.transport.write)
     self.state = CALL_ABORT_PENDING
     reactor.callLater(3, self.transport.loseConnection)
示例#12
0
 def sstpMsgCallAbort(self, status=None):
     if self.state in (CALL_ABORT_TIMEOUT_PENDING,
             CALL_DISCONNECT_TIMEOUT_PENDING):
         return
     logging.warn("Call abort.")
     if self.state == CALL_ABORT_PENDING:
         reactor.callLater(1, self.transport.loseConnection)
         return
     self.state = CALL_ABORT_IN_PROGRESS_2
     msg = SSTPControlPacket(SSTP_MSG_CALL_ABORT)
     msg.writeTo(self.transport.write)
     self.state = CALL_ABORT_PENDING
     reactor.callLater(1, self.transport.loseConnection)
示例#13
0
 def sstpMsgCallAbort(self, status=None):
     if self.state in (CALL_ABORT_TIMEOUT_PENDING,
             CALL_DISCONNECT_TIMEOUT_PENDING):
         return
     logging.warn("Call abort.")
     if self.state == CALL_ABORT_PENDING:
         reactor.callLater(1, self.transport.loseConnection)
         return
     self.state = CALL_ABORT_IN_PROGRESS_2
     msg = SSTPControlPacket(SSTP_MSG_CALL_ABORT)
     msg.writeTo(self.transport.write)
     self.state = CALL_ABORT_PENDING
     reactor.callLater(1, self.transport.loseConnection)
示例#14
0
    def sstpMsgCallConnectRequestReceived(self, protocolId):
        if self.state in (CALL_ABORT_TIMEOUT_PENDING, CALL_ABORT_PENDING,
                CALL_DISCONNECT_ACK_PENDING, CALL_DISCONNECT_TIMEOUT_PENDING):
            return
        if self.state != SERVER_CONNECT_REQUEST_PENDING:
            logging.warn('Not in the state.')
            self.transport.loseConnection()
            return
        if protocolId != SSTP_ENCAPSULATED_PROTOCOL_PPP:
            logging.warn('Unsupported encapsulated protocol.')
            nak = SSTPControlPacket(SSTP_MSG_CALL_CONNECT_NAK)
            nak.attributes = [(SSTP_ATTRIB_ENCAPSULATED_PROTOCOL_ID,
                    ATTRIB_STATUS_VALUE_NOT_SUPPORTED)]
            self.addRetryCounterOrAbrot()
            return
        self.nonce = os.urandom(32)
        ack = SSTPControlPacket(SSTP_MSG_CALL_CONNECT_ACK)
        # 3 bytes reserved + 1 byte hash bitmap (SHA-1 only) + nonce.
        ack.attributes = [(SSTP_ATTRIB_CRYPTO_BINDING_REQ,
                '\x00\x00\x00' + '\x03' + self.nonce)]
        ack.writeTo(self.transport.write)
        self.pppd = PPPDProtocol()
        self.pppd.sstp = self
        if self.factory.remotePool:
            self.pppd.remote = self.factory.remotePool.apply()
            if self.pppd.remote is None:
                logging.warn('IP address pool is full. '
                             'Cannot accpet new connection.')
                self.abort()
        else:
            self.pppd.remote = ''

        addressArgument = '%s:%s' % (self.factory.local, self.pppd.remote)
        reactor.spawnProcess(self.pppd, self.factory.pppd,
                args=['local', 'file', self.factory.pppdConfigFile,
                    '115200', addressArgument,
                    'remotenumber', str(self.transport.getPeer().host)], usePTY=True)
        self.transport.registerProducer(self.pppd, True)
        self.pppd.resumeProducing()
        self.state = SERVER_CALL_CONNECTED_PENDING