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) ack.attributes = [(SSTP_ATTRIB_CRYPTO_BINDING_REQ, '\x00\x00\x00' + '\x03' + self.nonce)] self.transport.write(ack.dump()) 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', 'notty', 'file', self.factory.pppdConfigFile, '115200', addressArgument, 'sync'], usePTY=False, childFDs={0:'w', 1:'r', 2:'r'}) self.state = SERVER_CALL_CONNECTED_PENDING
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)] self.transport.write(msg.dump()) self.state = CALL_ABORT_PENDING reactor.callLater(3, self.transport.loseConnection)
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)
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)
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
def processEnded(self, reason): logging.info('pppd stopped.') if (self.sstp.state != SERVER_CONNECT_REQUEST_PENDING and self.sstp.state != SERVER_CALL_CONNECTED_PENDING and self.sstp.state != SERVER_CALL_CONNECTED): self.sstp.transport.loseConnection() return self.sstp.state = CALL_DISCONNECT_IN_PROGRESS_1 msg = SSTPControlPacket(SSTP_MSG_CALL_DISCONNECT) msg.attributes = [(SSTP_ATTRIB_NO_ERROR, ATTRIB_STATUS_NO_ERROR)] self.sstp.transport.write(msg.dump()) self.sstp.state = CALL_DISCONNECT_ACK_PENDING reactor.callLater(5, self.sstp.transport.loseConnection)