Exemple #1
0
import sys

from pyptlib.client import ClientTransportPlugin
from pyptlib.config import EnvError

if __name__ == '__main__':
    client = ClientTransportPlugin()
    try:
        client.init(["blackfish", "bluefish"])
    except EnvError as err:
        print("pyptlib could not bootstrap ('%s')." % str(err))
        sys.exit(1)

    for transport in client.getTransports():
        # Spawn all the transports in the list, and for each spawned
        # transport report back the port where it is listening, and
        # the SOCKS version it supports.

        try:
            socks_version, bind_addrport = your_function_that_launches_transports(
                transport)
        except YourFailException as err:
            reportFailure(transport, "Failed to launch ('%s')." % str(err))
            continue

        client.reportMethodSuccess(transport, socks_version, bind_addrport,
                                   None, None)

    # After spawning our transports, report that we are done.
    client.reportMethodsEnd()
Exemple #2
0
"""This is a client-side example of the pyptlib API."""

import sys

from pyptlib.client import ClientTransportPlugin
from pyptlib.config import EnvError

if __name__ == '__main__':
    client = ClientTransportPlugin()
    try:
        client.init(["blackfish", "bluefish"])
    except EnvError, err:
        print "pyptlib could not bootstrap ('%s')." % str(err)
        sys.exit(1)

    for transport in client.getTransports():
        # Spawn all the transports in the list, and for each spawned
        # transport report back the port where it is listening, and
        # the SOCKS version it supports.

        try:
            socks_version, bind_addrport = your_function_that_launches_transports(transport)
        except YourFailException, err:
            reportFailure(transport, "Failed to launch ('%s')." % str(err))
            continue

        client.reportMethodSuccess(transport, socks_version, bind_addrport, None, None)

    # After spawning our transports, report that we are done.
    client.reportMethodsEnd()
Exemple #3
0
def pysshproxy():
    # Parse the command line arguments
    #
    # Note: Once #9163 is fixed and 0.2.5.x Tor is used, all these
    # arguments should just go away.
    #
    # TODO: It would be nice to support more than one host worth of
    # parameters somehow, maybe just use a config file?
    parser = argparse.ArgumentParser(description="SSH network proxy")
    parser.add_argument("--no-ecdsa", action="store_true", default=False,
                        help="Disable ECDSA")
    parser.add_argument("--debug", action="store_true", default=False,
                        help="SSH Debug Logging")
    parser.add_argument("--user", help="Remote user")
    parser.add_argument("--privkey", help="RSA Private Key")  # XXX: File?
    parser.add_argument("--orport", type=int, help="Remote ORPort")
    parser.add_argument("--hostkey-rsa", help="Remote RSA Public Hostkey")
    parser.add_argument("--hostkey-dss", help="Remote DSA Public Hostkey")
    group = parser.add_mutually_exclusive_group()
    group.add_argument("--hostkey-nistp256",
                       help="Remote ECDSA SHA2 NIST 256 Public Hostkey")
    group.add_argument("--hostkey-nistp384",
                       help="Remote ECDSA SHA2 NIST 384 Public Hostkey")
    group.add_argument("--hostkey-nistp521",
                       help="Remote ECDSA SHA2 NIST 521 Public Hostkey")
    group.add_argument("--monitor", help=argparse.SUPPRESS)
    args = parser.parse_args()
    optional_args = ["debug", "no_ecdsa"]

    # Cleanup on Windows is stupid, so sshproxy.exe also needs to double
    # as a monitor.
    if args.monitor is not None:
        run_monitor(args.monitor)
        sys.exit(0)

    # Bootstrap the pluggable transport protocol
    ptclient = ClientTransportPlugin()
    try:
        ptclient.init(["ssh"])
    except EnvError:
        sys.exit(1)
    state_location = ptclient.config.getStateLocation()

    # Create the state directory if required
    if not os.path.isdir(state_location):
        try:
            os.makedirs(state_location)
        except OSError as exception:
            if exception.errno != errno.EEXIST:
                ptclient.reportMethodError("ssh", "Failed to create dir " +
                                           str(exception))
                sys.exit(1)

    log.startLogging(open(os.path.join(state_location, _LOG_FILE_NAME),
                          "w"), setStdout=False)

    # Create the instance state directory and register cleanup handlers
    #
    # Note:
    # This will leave the directory behind on SIGKILL.  Maybe I should just
    # use a consistent path, but that will break if multiple copies of this
    # are ran at the same time.  tempfile.NamedTemporaryFile doesn't support
    # opening the created temporary file on Windows, otherwise that would be
    # a better way to handle things.
    global _tmpdir
    _tmpdir = mkdtemp(prefix="sshproxy-", dir=state_location)
    atexit.register(cleanup)
    signal(SIGTERM, cleanup)
    log.msg("Temp dir: " + _tmpdir)

    if os.name == "nt":
        try:
            import win32api
            win32api.SetConsoleCtrlHandler(ctrl_handler, True)
        except:
            log.msg("Failed to install ConsoleCtrlHandler")
            ptclient.reportMethodError("ssh", "Failed to install CtrlHandler")
            sys.exit(1)

    # Initialize the ssh state manager, and handle command line arguments
    global _state
    _state = ssh_state.state(_tmpdir)

    if args.debug is True:
        log.msg("SSH: Verbose logging enabled")
        _state.debug = True

    if args.no_ecdsa is True:
        log.msg("SSH: ECDSA support disabled")
        _state.use_ecdsa = False

    have_args = False
    for k, v in args.__dict__.iteritems():
        if k not in optional_args and v is not None:
            have_args = True
            break

    if have_args is True:
        _state.default_args = build_default_args(ptclient, args)
        if _state.default_args is None:
            sys.exit(1)

    if _state.ssh_works is False:
        ptclient.reportMethodError("ssh", "SSH client appears non-functional")
        sys.exit(1)

    # Setup the SOCKSv4 proxy
    factory = socks.SOCKSv4Factory(_state)
    addrport = reactor.listenTCP(0, factory, interface="localhost")

    # XXX: Trap SIGINT (Note: obfsproxy doesn't do this either)

    # Report back to Tor
    start_twisted = False
    for transport in ptclient.getTransports():
        if transport == "ssh":
            # pyptlib is bugged(?) and doesn't handle ARGS/OPT-ARGS correctly
            # when it does, _state.get_args()/_state.get_optargs() will give
            # what is expected.
            ptclient.reportMethodSuccess("ssh", "socks4",
                (addrport.getHost().host, addrport.getHost().port))
            start_twisted = True
    ptclient.reportMethodsEnd()

    if start_twisted is True:
        reactor.run()
Exemple #4
0
def do_managed_client():
    """Start the managed-proxy protocol as a client."""

    should_start_event_loop = False

    ptclient = ClientTransportPlugin()
    try:
        ptclient.init(transports.transports.keys())
    except EnvError as err:
        log.warning("Client managed-proxy protocol failed (%s)." % err)
        return

    log.debug("pyptlib gave us the following data:\n'%s'", pprint.pformat(ptclient.getDebugData()))

    # Apply the proxy settings if any
    proxy = ptclient.config.getProxy()
    if proxy:
        # Make sure that we have all the necessary dependencies
        try:
            network.ensure_outgoing_proxy_dependencies()
        except network.OutgoingProxyDepsFailure as err:
            ptclient.reportProxyError(str(err))
            return

        ptclient.reportProxySuccess()

    for transport in ptclient.getTransports():

        # Will hold configuration parameters for the pluggable transport module.
        pt_config = transport_config.TransportConfig()
        pt_config.setStateLocation(ptclient.config.getStateLocation())
        pt_config.setListenerMode("socks")
        pt_config.setObfsproxyMode("managed")
        pt_config.setProxy(proxy)

        # Call setup() method for this transport.
        transport_class = transports.get_transport_class(transport, 'socks')
        try:
            transport_class.setup(pt_config)
        except base.TransportSetupFailed as err:
            log.warning("Transport '%s' failed during setup()." % transport)
            ptclient.reportMethodError(transport, "setup() failed: %s." % (err))
            continue

        try:
            addrport = launch_transport.launch_transport_listener(transport, None, 'socks', None, pt_config)
        except transports.TransportNotFound:
            log.warning("Could not find transport '%s'" % transport)
            ptclient.reportMethodError(transport, "Could not find transport.")
            continue
        except error.CannotListenError as e:
            error_msg = "Could not set up listener (%s:%s) for '%s' (%s)." % \
                        (e.interface, e.port, transport, e.socketError[1])
            log.warning(error_msg)
            ptclient.reportMethodError(transport, error_msg)
            continue

        should_start_event_loop = True
        log.debug("Successfully launched '%s' at '%s'" % (transport, log.safe_addr_str(str(addrport))))
        ptclient.reportMethodSuccess(transport, "socks5", addrport, None, None)

    ptclient.reportMethodsEnd()

    if should_start_event_loop:
        log.info("Starting up the event loop.")
        reactor.run()
    else:
        log.info("No transports launched. Nothing to do.")