Generated from Manticore v1.1.6 • 388 packages. View on pkg.go.dev

keytab

import "github.com/TheManticoreProject/Manticore/network/kerberos/v5/credcache/keytab"

Package keytab reads and writes the MIT/Heimdal Kerberos keytab file (the “.keytab” / krb5.keytab format) in versioned format 2 (magic 0x05 0x02), the interchange format Unix Kerberos tooling (ktutil, kinit -kt, klist -k) uses to store a principal’s long-term keys on disk.

A keytab holds one or more entries, each binding a principal to a single long-term key (an enctype plus the raw key bytes) and a key version number (kvno). Unlike a credential cache (see the ccache package) it stores permanent keys, not tickets, so it lets a client authenticate non-interactively — the keytab-based analogue of pass-the-key.

Wire format (documented at https://web.mit.edu/kerberos/krb5-devel/doc/formats/keytab_file_format.html):

keytab {
    uint16                 file_format_version = 0x0502
    keytab_entry           entries[*]         (runs to EOF)
}
keytab_entry {
    int32                  size               // bytes that FOLLOW this field;
                                              // negative = a hole (deleted entry),
                                              // its magnitude is the hole length
    uint16                 num_components     // v2 does NOT count the realm
    counted_octet_string   realm
    counted_octet_string   components[num_components]
    uint32                 name_type          // v2 only
    uint32                 timestamp          // Unix seconds
    uint8                  vno8               // 8-bit key version number
    keyblock               key
    uint32                 vno                // OPTIONAL: present when >= 4 bytes
                                              // remain in size and it is non-zero;
                                              // supersedes vno8
}
keyblock             { uint16 enctype; counted_octet_string key }
counted_octet_string { uint16 length; uint8 data[length] }

Version 2 is big-endian throughout (version 1 used host byte order and folded the realm into num_components; only version 2 is emitted today and is what this package writes). This package implements the wire format and entry selection; wiring a selected key into a live client is done by the kerberos client layer.

Index

Constants

Version2 is the file_format_version this package reads and writes: the first byte is always 0x05, the second is the version (2).

const Version2 = 0x0502

type Entry

Entry is a single keytab record: one long-term key for one principal.

type Entry struct {
    Principal Principal
    // Timestamp is when the entry was written, in Unix seconds (0 if unknown).
    Timestamp uint32
    // KVNO8 is the 8-bit key version number always present on the wire.
    KVNO8 uint8
    // KVNO is the optional 32-bit key version number. When non-zero it is written
    // after the key and supersedes KVNO8 (kvnos above 255 need it). Zero means the
    // 32-bit field is absent and KVNO8 is authoritative.
    KVNO uint32
    // EType is the key's encryption type (see iana.EType*).
    EType uint16
    // Key is the raw long-term key bytes.
    Key []byte
}

func (Entry) Kvno

func (e Entry) Kvno() uint32

Kvno returns the effective key version number: the 32-bit KVNO when non-zero, otherwise the 8-bit KVNO8.

type Keytab

Keytab is a parsed keytab: an ordered list of key entries.

type Keytab struct {
    Entries []Entry
}

func Load

func Load(path string) (*Keytab, error)

Load reads and parses a keytab file.

func New

func New() *Keytab

New returns an empty keytab.

func Unmarshal

func Unmarshal(data []byte) (*Keytab, error)

Unmarshal parses a keytab. Only versioned format 2 (0x0502) is supported.

func (*Keytab) Add

func (kt *Keytab) Add(principal Principal, etype int, key []byte, kvno uint32)

Add appends an entry binding a key to a principal. The 8-bit KVNO8 is set from kvno (its low byte) and, when kvno exceeds 255, the 32-bit KVNO too. NameType defaults to NT-PRINCIPAL when zero. The key bytes are copied.

func (*Keytab) Find

func (kt *Keytab) Find(principal string, etype int, kvno int) []*Entry

Find returns pointers to every entry matching the filter, in file order. A principal of "" matches any principal; etype <= 0 matches any enctype; and kvno < 0 matches any key version.

func (*Keytab) Marshal

func (kt *Keytab) Marshal() ([]byte, error)

Marshal encodes the keytab in versioned format 2 (0x0502, big-endian).

func (*Keytab) Save

func (kt *Keytab) Save(path string) error

Save writes the keytab to path in versioned format 2, mode 0600.

func (*Keytab) Select

func (kt *Keytab) Select(principal string, etype int, kvno int) *Entry

Select returns the single best entry matching the filter, or nil when none match. “Best” is the highest key version number, breaking ties by enctype strength (AES256 > AES256-SHA2 > AES128 > AES128-SHA2 > RC4 > other). Pass principal "" for any principal, etype <= 0 for any enctype, and kvno < 0 to select the newest key rather than a specific version.

type Principal

Principal identifies the account a key belongs to: one or more name components, a realm, and the RFC 4120 name-type.

type Principal struct {
    NameType   uint32
    Realm      string
    Components []string
}

func (Principal) String

func (p Principal) String() string

String renders the principal in the conventional “comp1/comp2@REALM” form.