rdpclient

package
v1.2.3-fred.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2022 License: Apache-2.0 Imports: 7 Imported by: 0

README

RDP client library

This library consists of 2 parts: the actual Rust library and the Go wrapper around it. Go wrappers calls into Rust code using CGO. Rust library is compiled as a static C library.

High-level

You should read the RFDs 34 and 35 first.

The gist of it is: between Teleport and the Windows host we use classic RDP. In order to authenticate with X.509 certificates instead of passwords, we emulate a smartcard device over the RDP connection. This emulated smartcard uses Teleport-issued X.509 certificates for Windows to verify. The Active Directory Windows environment should be configured with Teleport CA in its trust store.

Go

All the wrapper code is in client.go. This wrapper calls into Rust to establish an RDP connection and provides it with credentials (key/cert). The wrapper then proxies input/output data, translating between Teleport Desktop Protocol (TDP) and RDP.

Rust

Rust code is under src. It uses several libraries (see Cargo.toml), but the main one is rdp-rs. rdp-rs is a pure Rust (partial) implementation of the RDP protocol. We forked that library at https://github.com/gravitational/rdp-rs/. Our fork implements several changes necessary to support smartcard emulation.

Notes on specific Rust modules:

lib.rs

Entrypoint of the library. This implements the CGO API surface and basic RDP connection establishment. During RDP connection, it negotiates the "rdpdr" static virtual channel, which is used for smartcard device "redirection" (read more below).

Most of the protocol is implemented in the rdp-rs crate and the spec is https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-RDPBCGR/%5bMS-RDPBCGR%5d.pdf

rdpdr.rs

The device redirection layer. This lives inside of the RDP connection, under the MCS layer. Device redirection can mirror any disk, serial, smartcard or printer from the RDP client to the server. In our case, we redirect a hardcoded fake smartcard.

The spec is at: https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-RDPEFS/%5bMS-RDPEFS%5d.pdf

scard.rs

The smartcard reader emulation layer. This is redirected over RDPDR. Smartcards typically connect to a computer via a reader, e.g. a USB card reader. The code in scard.rs emulates a single hardcoded reader called "Teleport" with a single smartcard inserted.

The spec is at: https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-RDPESC/%5bMS-RDPESC%5d.pdf

piv.rs

The smartcard emulation and authn layer. This is the fake smartcard "inserted" into the "Teleport" reader above. This smartcard has a PIV applet "installed" and implements the protocol at: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf

It basically has file storage for some user-identifying info and an X.509 certificate. It also has an RSA private key that it does challenge/response authentication with, to prove the ownership of that X.509 certificate.

Memory management

Note that all memory allocated on the Go side must be freed on the Go side. Same goes for Rust. These languages have different memory management systems and can't free each others' memory. This is why you'll see the weird free_* hops from one side to the other.

Documentation

Overview

Package rdpclient implements an RDP client.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
}

Client is the dummy RDP client.

func New

func New(cfg Config) (*Client, error)

New creates and connects a new Client based on opts.

func (*Client) GetClientLastActive

func (c *Client) GetClientLastActive() time.Time

GetClientLastActive returns the time of the last recorded activity.

func (*Client) Run

func (c *Client) Run(ctx context.Context) error

Run starts the rdp client and blocks until the client disconnects, then runs the cleanup.

func (*Client) UpdateClientActivity

func (c *Client) UpdateClientActivity()

UpdateClientActivity updates the client activity timestamp.

type Config

type Config struct {
	// Addr is the network address of the RDP server, in the form host:port.
	Addr string
	// UserCertGenerator generates user certificates for RDP authentication.
	GenerateUserCert GenerateUserCertFn
	CertTTL          time.Duration

	// AuthorizeFn is called to authorize a user connecting to a Windows desktop.
	AuthorizeFn func(login string) error

	// Conn handles TDP messages between Windows Desktop Service
	// and a Teleport Proxy.
	Conn *tdp.Conn

	// Encoder is an optional override for PNG encoding.
	Encoder *png.Encoder

	// AllowClipboard indicates whether the RDP connection should enable
	// clipboard sharing.
	AllowClipboard bool

	// AllowDirectorySharing indicates whether the RDP connection should enable
	// directory sharing.
	AllowDirectorySharing bool

	// Log is the logger for status messages.
	Log logrus.FieldLogger
}

Config for creating a new Client.

type GenerateUserCertFn

type GenerateUserCertFn func(ctx context.Context, username string, ttl time.Duration) (certDER, keyDER []byte, err error)

GenerateUserCertFn generates user certificates for RDP authentication.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL