1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
//! Kerberos 5 structures
//!
//! - [RFC1510](https://tools.ietf.org/html/rfc1510) The Kerberos Network Authentication Service (V5)
//! - [RFC3961](https://tools.ietf.org/html/rfc3961) Encryption and Checksum Specifications for Kerberos 5
//! - [RFC3962](https://tools.ietf.org/html/rfc3962) Advanced Encryption Standard (AES) Encryption for Kerberos 5
//! - [RFC4120](https://tools.ietf.org/html/rfc4120) The Kerberos Network Authentication Service (V5)
//! - [RFC6803](https://tools.ietf.org/html/rfc6803) Camellia Encryption for Kerberos 5
//! - [RFC8009](https://tools.ietf.org/html/rfc8009) AES Encryption with HMAC-SHA2 for Kerberos 5

use std::fmt;
use der_parser::DerObject;

pub use krb5_constants::*;
pub use krb5_errors::*;

/// Kerberos Realm
///
/// A Kerberos realm is a set of managed nodes that share the same Kerberos database.
#[derive(Debug, PartialEq)]
pub struct Realm(pub String);

/// Kerberos PrincipalName
///
/// A Kerberos principal is a service or user that is known to the Kerberos system. Each Kerberos
/// principal is identified by its principal name. Principal names consist of three parts: a
/// service or user name, an instance name, and a realm name in the following form:
///
/// <pre>
/// principal-name.instance-name@realm-name
/// </pre>
#[derive(Debug, PartialEq)]
pub struct PrincipalName {
    pub name_type: NameType,
    pub name_string: Vec<String>,
}

impl fmt::Display for PrincipalName {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(&self.name_string.join("/"))
    }
}

/// Kerberos Ticket
///
/// A record that helps a client authenticate itself to a server; it
/// contains the client's identity, a session key, a timestamp, and
/// other information, all sealed using the server's secret key.  It
/// only serves to authenticate a client when presented along with a
/// fresh Authenticator.
#[derive(Debug, PartialEq)]
pub struct Ticket<'a> {
    /// Version number for the ticket format (5)
    pub tkt_vno: u32,
    /// Realm that issued a ticket
    pub realm: Realm,
    /// Components of the name part of the server's identity
    pub sname: PrincipalName,
    /// Encrypted encoding of the EncTicketPart sequence
    pub enc_part: &'a [u8],
}

/// Kerberos EncryptedData
#[derive(Debug, PartialEq)]
pub struct EncryptedData<'a> {
    /// EncryptionType
    pub etype: EncryptionType,
    /// Version number of the key under which data is encrypted
    pub kvno: Option<u32>,
    /// Ciphertext
    pub cipher: &'a [u8],
}

/// Key Distribution Center (KDC) Request Message
#[derive(Debug, PartialEq)]
pub struct KdcReq<'a> {
    pub pvno: u32,
    pub msg_type: MessageType,
    pub padata: Vec<PAData<'a>>,
    pub req_body: KdcReqBody<'a>,
}

/// Key Distribution Center (KDC) Request Message Body
#[derive(Debug, PartialEq)]
pub struct KdcReqBody<'a> {
    /// Options requested by the client
    pub kdc_options: DerObject<'a>,
    /// Client name (only for AS-REQ)
    pub cname: Option<PrincipalName>,
    /// Server's realm
    pub realm: Realm,
    /// Server name
    pub sname: Option<PrincipalName>,
    /// Desired starttime for the requested ticket
    pub from: Option<DerObject<'a>>,
    /// Expiration date requested by the client
    pub till: DerObject<'a>,
    /// Requested renew-till time
    pub rtime: Option<DerObject<'a>>,
    /// Random number generated by the client
    pub nonce: u32,
    /// Desired encryption algorithm to be used in the response
    pub etype: Vec<EncryptionType>,
    /// Addresses from which the requested ticket is to be valid
    pub addresses: Vec<HostAddress<'a>>,
    /// Encoding of the desired authorization-data encrypted under the sub-session key if present
    /// in the Authenticator, or alternatively from the session key in the TGT
    pub enc_authorization_data: Option<EncryptedData<'a>>,
    /// Additional tickets MAY be optionally included in a request to the ticket-granting server
    pub additional_tickets: Vec<Ticket<'a>>,
}

/// Kerberos HostAddress
#[derive(Debug, PartialEq)]
pub struct HostAddress<'a> {
    pub addr_type: AddressType,
    pub address: &'a[u8],
}

/// Key Distribution Center (KDC) Reply Message
#[derive(Debug, PartialEq)]
pub struct KdcRep<'a> {
    pub pvno: u32,
    pub msg_type: MessageType,
    pub padata: Vec<PAData<'a>>,
    pub crealm: Realm,
    pub cname: PrincipalName,
    pub ticket: Ticket<'a>,
    pub enc_part: EncryptedData<'a>,
}

/// Kerberos Error message
#[derive(Debug, PartialEq)]
pub struct KrbError<'a> {
    pub pvno: u32,
    pub msg_type: MessageType,
    pub ctime: Option<DerObject<'a>>,
    pub cusec: Option<u32>,
    pub stime: DerObject<'a>,
    pub susec: u32,
    pub error_code: ErrorCode,
    pub crealm: Option<Realm>,
    pub cname: Option<PrincipalName>,
    pub realm: Realm,
    pub sname: PrincipalName,
    pub etext: Option<String>,
    pub edata: Option<DerObject<'a>>,
}

/// Kerberos PA-Data
#[derive(Debug, PartialEq)]
pub struct PAData<'a> {
    pub padata_type:  PAType,
    pub padata_value: &'a[u8],
}

/// Kerberos AP Request
#[derive(Debug, PartialEq)]
pub struct ApReq<'a> {
    pub pvno          : u32,
    pub msg_type      : MessageType,
    pub ap_options    : DerObject<'a>, // KerberosFlags
    pub ticket        : Ticket<'a>,
    pub authenticator : EncryptedData<'a>,
}

/// Kerberos AP Reply
#[derive(Debug, PartialEq)]
pub struct ApRep<'a> {
    pub pvno     : u32,
    pub msg_type : MessageType,
    pub enc_part : EncryptedData<'a>,
}