summaryrefslogtreecommitdiffstats
path: root/rust/vendor/kerberos-parser
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:39:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 17:39:49 +0000
commita0aa2307322cd47bbf416810ac0292925e03be87 (patch)
tree37076262a026c4b48c8a0e84f44ff9187556ca35 /rust/vendor/kerberos-parser
parentInitial commit. (diff)
downloadsuricata-a0aa2307322cd47bbf416810ac0292925e03be87.tar.xz
suricata-a0aa2307322cd47bbf416810ac0292925e03be87.zip
Adding upstream version 1:7.0.3.upstream/1%7.0.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'rust/vendor/kerberos-parser')
-rw-r--r--rust/vendor/kerberos-parser/.cargo-checksum.json1
-rw-r--r--rust/vendor/kerberos-parser/.travis.yml25
-rw-r--r--rust/vendor/kerberos-parser/Cargo.toml34
-rw-r--r--rust/vendor/kerberos-parser/LICENSE-APACHE201
-rw-r--r--rust/vendor/kerberos-parser/LICENSE-MIT25
-rw-r--r--rust/vendor/kerberos-parser/README.md71
-rw-r--r--rust/vendor/kerberos-parser/assets/ap-req.binbin0 -> 1052 bytes
-rw-r--r--rust/vendor/kerberos-parser/assets/as-rep.binbin0 -> 1256 bytes
-rw-r--r--rust/vendor/kerberos-parser/assets/as-req.binbin0 -> 291 bytes
-rw-r--r--rust/vendor/kerberos-parser/assets/krb-error.bin1
-rw-r--r--rust/vendor/kerberos-parser/assets/krb5-ticket.binbin0 -> 1164 bytes
-rw-r--r--rust/vendor/kerberos-parser/assets/tgs-rep-no-padata.binbin0 -> 1189 bytes
-rw-r--r--rust/vendor/kerberos-parser/benches/b_krb5_parser.rs25
-rw-r--r--rust/vendor/kerberos-parser/src/krb5.rs172
-rw-r--r--rust/vendor/kerberos-parser/src/krb5_constants.rs258
-rw-r--r--rust/vendor/kerberos-parser/src/krb5_errors.rs153
-rw-r--r--rust/vendor/kerberos-parser/src/krb5_parser.rs587
-rw-r--r--rust/vendor/kerberos-parser/src/lib.rs45
-rw-r--r--rust/vendor/kerberos-parser/tests/krb5_parser.rs253
19 files changed, 1851 insertions, 0 deletions
diff --git a/rust/vendor/kerberos-parser/.cargo-checksum.json b/rust/vendor/kerberos-parser/.cargo-checksum.json
new file mode 100644
index 0000000..50073e6
--- /dev/null
+++ b/rust/vendor/kerberos-parser/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{".travis.yml":"6707873f357a13c413711ca71d73f55ace176cfc9f508e633f4f63560c6d37b0","Cargo.toml":"780ee5ec8f7bffb4be90586fa871e1fd32f66df13ebdce2c46b4746e26b0ad50","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"a5c61b93b6ee1d104af9920cf020ff3c7efe818e31fe562c72261847a728f513","README.md":"af4d42f26c82971b246d04dd99ad0398f5ce7a90af0156fb221d7a8396e8b51d","assets/ap-req.bin":"67e9c04a5fb580ca72b4da19ad554af43c127ce56ca4ce309c8afb2dc8cbe790","assets/as-rep.bin":"0a1af2b2204721e22aca58861410f56b271a48f960a4f12872e3b6f86e5ddc9c","assets/as-req.bin":"4256f675abf77424ad2c0eb17504e2602f0b702ba5ea2f0e61643755a9ef33a5","assets/krb-error.bin":"3a2cecf108a82e6048342b18954afd126a90bcc1362c528a45e4bb36ca461db6","assets/krb5-ticket.bin":"5ece64076dd0aac8fc1b4d4c93e4fb625119400584df598cbf26516dec2688c9","assets/tgs-rep-no-padata.bin":"76e8fe3b7cea6d5140433f9668cf798edce5a0b5e594f06a1638b0ae07d9793f","benches/b_krb5_parser.rs":"5669b5d8f2cb9c18a5b65c163530bb5d49a66328d2ee7f2646e9318b8848782c","src/krb5.rs":"dbbda40dbeb106b3bac5b0cee60ce0de9812a8b111af78458f50cca2c3e4038b","src/krb5_constants.rs":"981f0937dcbf4ec3b8d7b45430c1d1916a6eb582bf656cef59742ca76259fdfd","src/krb5_errors.rs":"8d88e1e123649f74a24c55950e725da18dd287fc197400161a447b928f2707ee","src/krb5_parser.rs":"647c39b34c7bda01c422c788d32b97d81a63852335471e2c7e42881920ad7778","src/lib.rs":"47ef411516eb15edf6136a4f8d158d2b3c54675abf5a8f4ce89b3854a4299611","tests/krb5_parser.rs":"667afa9083193757ffe8e8dd4e3e00642e793a650003870bdf401d42552e0863"},"package":"c10e7cfd4759cbce37ea65e2f48caebd695c246196a38e97ba4f731da48996da"} \ No newline at end of file
diff --git a/rust/vendor/kerberos-parser/.travis.yml b/rust/vendor/kerberos-parser/.travis.yml
new file mode 100644
index 0000000..62bc4f2
--- /dev/null
+++ b/rust/vendor/kerberos-parser/.travis.yml
@@ -0,0 +1,25 @@
+language: rust
+sudo: false
+matrix:
+ include:
+ - rust: stable
+ env:
+ - NAME="stable"
+ - FEATURES=''
+ - rust: stable
+ env:
+ - NAME="stable,fmt"
+ - FEATURES=''
+ - RUSTFMT=yes
+ - rust: nightly
+ env:
+ - NAME="nightly"
+ - FEATURES=''
+before_script:
+ - ([ "$RUSTFMT" != yes ] || rustup component add rustfmt)
+script:
+ - ([ "$RUSTFMT" != yes ] || cargo fmt --all -- --check)
+ - |
+ cargo build --verbose --features "$FEATURES" &&
+ cargo test --verbose --features "$FEATURES" &&
+ ([ "$BENCH" != 1 ] || cargo bench --verbose --features "$FEATURES")
diff --git a/rust/vendor/kerberos-parser/Cargo.toml b/rust/vendor/kerberos-parser/Cargo.toml
new file mode 100644
index 0000000..023a8be
--- /dev/null
+++ b/rust/vendor/kerberos-parser/Cargo.toml
@@ -0,0 +1,34 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "kerberos-parser"
+version = "0.7.1"
+authors = ["Pierre Chifflier <chifflier@wzdftpd.net>"]
+include = ["LICENSE-*", "README.md", ".gitignore", ".travis.yml", "Cargo.toml", "assets/*.bin", "benches/*.rs", "src/*.rs", "tests/*.rs"]
+description = "Parser for the Kerberos protocol"
+homepage = "https://github.com/rusticata/kerberos-parser"
+readme = "README.md"
+keywords = ["Kerberos", "parser", "nom"]
+categories = ["parser-implementations"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/rusticata/kerberos-parser.git"
+[dependencies.der-parser]
+version = "6.0.0"
+
+[dependencies.nom]
+version = "7.0"
+
+[dependencies.rusticata-macros]
+version = "4.0"
+[badges.travis-ci]
+repository = "rusticata/kerberos-parser"
diff --git a/rust/vendor/kerberos-parser/LICENSE-APACHE b/rust/vendor/kerberos-parser/LICENSE-APACHE
new file mode 100644
index 0000000..16fe87b
--- /dev/null
+++ b/rust/vendor/kerberos-parser/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/rust/vendor/kerberos-parser/LICENSE-MIT b/rust/vendor/kerberos-parser/LICENSE-MIT
new file mode 100644
index 0000000..290e7b9
--- /dev/null
+++ b/rust/vendor/kerberos-parser/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2017 Pierre Chifflier
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/rust/vendor/kerberos-parser/README.md b/rust/vendor/kerberos-parser/README.md
new file mode 100644
index 0000000..9205644
--- /dev/null
+++ b/rust/vendor/kerberos-parser/README.md
@@ -0,0 +1,71 @@
+# Kerberos parser
+
+[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE-MIT)
+[![Apache License 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](./LICENSE-APACHE)
+[![Build Status](https://travis-ci.org/rusticata/kerberos-parser.svg?branch=master)](https://travis-ci.org/rusticata/kerberos-parser)
+[![Crates.io Version](https://img.shields.io/crates/v/kerberos-parser.svg)](https://crates.io/crates/kerberos-parser)
+
+<!-- cargo-sync-readme start -->
+
+# Kerberos Parser
+
+A Kerberos v5 ([RFC4120]) parser, implemented with the [nom](https://github.com/Geal/nom)
+parser combinator framework.
+
+The code is available on [Github](https://github.com/rusticata/kerberos-parser).
+
+Specific parsing functions are provided for Kerberos message types. For ex. to parse a
+KRB_AS_REQ message, use [`parse_as_req`](krb5_parser/fn.parse_as_req.html).
+
+# Examples
+
+Parsing a KRB_AS_REQ message:
+
+```rust,no_run
+use kerberos_parser::krb5::MessageType;
+use kerberos_parser::krb5_parser::parse_as_req;
+
+static AS_REQ: &'static [u8] = include_bytes!("../assets/as-req.bin");
+
+let res = parse_as_req(AS_REQ);
+match res {
+ Ok((rem, kdc_req)) => {
+ assert!(rem.is_empty());
+ //
+ assert_eq!(kdc_req.msg_type, MessageType::KRB_AS_REQ);
+ },
+ _ => panic!("KRB_AS_REQ parsing failed: {:?}", res),
+}
+```
+
+[RFC4120]: https://tools.ietf.org/html/rfc4120
+
+<!-- cargo-sync-readme end -->
+
+## Rusticata
+
+This parser is part of the [rusticata](https://github.com/rusticata) project.
+The goal of this project is to provide **safe** parsers, that can be used in other projects.
+
+Testing of the parser is done manually, and also using unit tests and
+[cargo-fuzz](https://github.com/rust-fuzz/cargo-fuzz). Please fill a bugreport if you find any issue.
+
+Feel free to contribute: tests, feedback, doc, suggestions (or code) of new parsers etc. are welcome.
+
+## License
+
+Licensed under either of
+
+ * Apache License, Version 2.0
+ ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license
+ ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+
+at your option.
+
+## Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
+
diff --git a/rust/vendor/kerberos-parser/assets/ap-req.bin b/rust/vendor/kerberos-parser/assets/ap-req.bin
new file mode 100644
index 0000000..39386ec
--- /dev/null
+++ b/rust/vendor/kerberos-parser/assets/ap-req.bin
Binary files differ
diff --git a/rust/vendor/kerberos-parser/assets/as-rep.bin b/rust/vendor/kerberos-parser/assets/as-rep.bin
new file mode 100644
index 0000000..43d0560
--- /dev/null
+++ b/rust/vendor/kerberos-parser/assets/as-rep.bin
Binary files differ
diff --git a/rust/vendor/kerberos-parser/assets/as-req.bin b/rust/vendor/kerberos-parser/assets/as-req.bin
new file mode 100644
index 0000000..6d503b3
--- /dev/null
+++ b/rust/vendor/kerberos-parser/assets/as-req.bin
Binary files differ
diff --git a/rust/vendor/kerberos-parser/assets/krb-error.bin b/rust/vendor/kerberos-parser/assets/krb-error.bin
new file mode 100644
index 0000000..b9c7645
--- /dev/null
+++ b/rust/vendor/kerberos-parser/assets/krb-error.bin
@@ -0,0 +1 @@
+~–0“ ¡¤20050816094029Z¥(|¦©DENYDCª0 ¡0krbtgtDENYDC¬A?0=0;¡ ¢42000 ¡ DENYDC.COMdes0 ¡ DENYDC.COMdes \ No newline at end of file
diff --git a/rust/vendor/kerberos-parser/assets/krb5-ticket.bin b/rust/vendor/kerberos-parser/assets/krb5-ticket.bin
new file mode 100644
index 0000000..8536896
--- /dev/null
+++ b/rust/vendor/kerberos-parser/assets/krb5-ticket.bin
Binary files differ
diff --git a/rust/vendor/kerberos-parser/assets/tgs-rep-no-padata.bin b/rust/vendor/kerberos-parser/assets/tgs-rep-no-padata.bin
new file mode 100644
index 0000000..25d6270
--- /dev/null
+++ b/rust/vendor/kerberos-parser/assets/tgs-rep-no-padata.bin
Binary files differ
diff --git a/rust/vendor/kerberos-parser/benches/b_krb5_parser.rs b/rust/vendor/kerberos-parser/benches/b_krb5_parser.rs
new file mode 100644
index 0000000..d9becf9
--- /dev/null
+++ b/rust/vendor/kerberos-parser/benches/b_krb5_parser.rs
@@ -0,0 +1,25 @@
+#![feature(test)]
+
+extern crate test;
+use test::Bencher;
+
+extern crate kerberos_parser;
+extern crate nom;
+
+use kerberos_parser::krb5_parser::*;
+
+static KRB5_TICKET: &[u8] = include_bytes!("../assets/krb5-ticket.bin");
+
+#[bench]
+fn bench_parse_ticket(b: &mut Bencher) {
+ b.iter(|| {
+ let res = parse_krb5_ticket(KRB5_TICKET);
+ match res {
+ Ok((rem, tkt)) => {
+ assert!(rem.is_empty());
+ assert_eq!(tkt.tkt_vno, 5);
+ }
+ _ => assert!(false),
+ }
+ });
+}
diff --git a/rust/vendor/kerberos-parser/src/krb5.rs b/rust/vendor/kerberos-parser/src/krb5.rs
new file mode 100644
index 0000000..378c5d1
--- /dev/null
+++ b/rust/vendor/kerberos-parser/src/krb5.rs
@@ -0,0 +1,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 der_parser::der::DerObject;
+use std::fmt;
+
+pub use crate::krb5_constants::*;
+pub use crate::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: EncryptedData<'a>,
+}
+
+/// 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>,
+}
diff --git a/rust/vendor/kerberos-parser/src/krb5_constants.rs b/rust/vendor/kerberos-parser/src/krb5_constants.rs
new file mode 100644
index 0000000..c95b438
--- /dev/null
+++ b/rust/vendor/kerberos-parser/src/krb5_constants.rs
@@ -0,0 +1,258 @@
+// See https://www.iana.org/assignments/kerberos-parameters/kerberos-parameters.xhtml
+
+use std::fmt;
+
+/// Address type
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub struct AddressType(pub i32);
+
+#[rustfmt::skip]
+impl AddressType {
+ pub const IPV4 : AddressType = AddressType(2);
+ pub const DIRECTIONAL : AddressType = AddressType(3);
+ pub const CHAOSNET : AddressType = AddressType(5);
+ pub const XNS : AddressType = AddressType(6);
+ pub const ISO : AddressType = AddressType(7);
+ pub const DECNET_P4 : AddressType = AddressType(12);
+ pub const APPLETALK_DDP : AddressType = AddressType(16);
+ pub const NETBIOS : AddressType = AddressType(20);
+ pub const IPV6 : AddressType = AddressType(24);
+}
+
+impl fmt::Debug for AddressType {
+ #[rustfmt::skip]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self.0 {
+ 2 => f.write_str("IPv4"),
+ 3 => f.write_str("Directional"),
+ 5 => f.write_str("ChaosNet"),
+ 6 => f.write_str("XNS"),
+ 7 => f.write_str("ISO"),
+ 12 => f.write_str("DECNET Phase IV"),
+ 16 => f.write_str("Appletalk DDP"),
+ 20 => f.write_str("Netbios"),
+ 24 => f.write_str("IPv6"),
+ n => f.debug_tuple("AddressType").field(&n).finish(),
+ }
+ }
+}
+
+/// Encryption type
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub struct EncryptionType(pub i32);
+
+#[rustfmt::skip]
+impl EncryptionType {
+ pub const DES_CBC_CRC : EncryptionType = EncryptionType(1);
+ pub const DES_CBC_MD4 : EncryptionType = EncryptionType(2);
+ pub const DES_CBC_MD5 : EncryptionType = EncryptionType(3);
+ pub const DES3_CBC_MD5 : EncryptionType = EncryptionType(5);
+ pub const DES3_CBC_SHA1 : EncryptionType = EncryptionType(7);
+ pub const DSAWITHSHA1_CMSOID : EncryptionType = EncryptionType(9);
+ pub const MD5WITHRSAENCRYPTION_CMSOID : EncryptionType = EncryptionType(10);
+ pub const SHA1WITHRSAENCRYPTION_CMSOID : EncryptionType = EncryptionType(11);
+ pub const RC2CBC_ENVOID : EncryptionType = EncryptionType(12);
+ pub const RSAENCRYPTION_ENVOID : EncryptionType = EncryptionType(13);
+ pub const RSAES_OAEP_ENV_OID : EncryptionType = EncryptionType(14);
+ pub const DES_EDE3_CBC_ENV_OID : EncryptionType = EncryptionType(15);
+ pub const DES3_CBC_SHA1_KD : EncryptionType = EncryptionType(16);
+ pub const AES128_CTS_HMAC_SHA1_96 : EncryptionType = EncryptionType(17);
+ pub const AES256_CTS_HMAC_SHA1_96 : EncryptionType = EncryptionType(18);
+ pub const AES128_CTS_HMAC_SHA256_128 : EncryptionType = EncryptionType(19);
+ pub const AES256_CTS_HMAC_SHA384_192 : EncryptionType = EncryptionType(20);
+ pub const RC4_HMAC : EncryptionType = EncryptionType(23);
+ pub const RC4_HMAC_EXP : EncryptionType = EncryptionType(24);
+ pub const CAMELLIA128_CTS_CMAC : EncryptionType = EncryptionType(25);
+ pub const CAMELLIA256_CTS_CMAC : EncryptionType = EncryptionType(26);
+ pub const SUBKEY_KEYMATERIAL : EncryptionType = EncryptionType(65);
+ // negative values
+ pub const RC4_MD4 : EncryptionType = EncryptionType(-128);
+ pub const RC4_PLAIN2 : EncryptionType = EncryptionType(-129);
+ pub const RC4_LM : EncryptionType = EncryptionType(-130);
+ pub const RC4_SHA : EncryptionType = EncryptionType(-131);
+ pub const DES_PLAIN : EncryptionType = EncryptionType(-132);
+ pub const RC4_HMAC_OLD : EncryptionType = EncryptionType(-133);
+ pub const RC4_PLAIN_OLD : EncryptionType = EncryptionType(-134);
+ pub const RC4_HMAC_OLD_EXP : EncryptionType = EncryptionType(-135);
+ pub const RC4_PLAIN_OLD_EXP : EncryptionType = EncryptionType(-136);
+ pub const RC4_PLAIN : EncryptionType = EncryptionType(-140);
+ pub const RC4_PLAIN_EXP : EncryptionType = EncryptionType(-141);
+}
+
+impl fmt::Debug for EncryptionType {
+ #[rustfmt::skip]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self.0 {
+ 1 => f.write_str("des-cbc-crc"),
+ 2 => f.write_str("des-cbc-md4"),
+ 3 => f.write_str("des-cbc-md5"),
+ 5 => f.write_str("des3-cbc-md5"),
+ 7 => f.write_str("des3-cbc-sha1"),
+ 9 => f.write_str("dsaWithSHA1-CmsOID"),
+ 10 => f.write_str("md5WithRSAEncryption-CmsOID"),
+ 11 => f.write_str("sha1WithRSAEncryption-CmsOID"),
+ 12 => f.write_str("rc2CBC-EnvOID"),
+ 13 => f.write_str("rsaEncryption-EnvOID"),
+ 14 => f.write_str("rsaES-OAEP-ENV-OID"),
+ 15 => f.write_str("des-ede3-cbc-Env-OID"),
+ 16 => f.write_str("des3-cbc-sha1-kd"),
+ 17 => f.write_str("aes128-cts-hmac-sha1-96"),
+ 18 => f.write_str("aes256-cts-hmac-sha1-96"),
+ 19 => f.write_str("aes128-cts-hmac-sha256-128"),
+ 20 => f.write_str("aes256-cts-hmac-sha384-192"),
+ 23 => f.write_str("rc4-hmac"),
+ 24 => f.write_str("rc4-hmac-exp"),
+ 25 => f.write_str("camellia128-cts-cmac"),
+ 26 => f.write_str("camellia256-cts-cmac"),
+ 65 => f.write_str("subkey-keymaterial"),
+ // negative values
+ -128 => f.write_str("rc4-md4"),
+ -129 => f.write_str("rc4-plain2"),
+ -130 => f.write_str("rc4-lm"),
+ -131 => f.write_str("rc4-sha"),
+ -132 => f.write_str("des-plain"),
+ -133 => f.write_str("rc4-hmac-OLD"),
+ -134 => f.write_str("rc4-plain-OLD"),
+ -135 => f.write_str("rc4-hmac-OLD-exp"),
+ -136 => f.write_str("rc4-plain-OLD-exp"),
+ -140 => f.write_str("rc4-plain"),
+ -141 => f.write_str("rc4-plain-exp"),
+ n => f.debug_tuple("EncryptionType").field(&n).finish(),
+ }
+ }
+}
+
+/// Message type
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub struct MessageType(pub u32);
+
+#[rustfmt::skip]
+impl MessageType {
+ /// Request for initial authentication
+ pub const KRB_AS_REQ : MessageType = MessageType(10);
+ /// Response to KRB_AS_REQ request
+ pub const KRB_AS_REP : MessageType = MessageType(11);
+ /// Request for authentication based on TGT
+ pub const KRB_TGS_REQ : MessageType = MessageType(12);
+ /// Response to KRB_TGS_REQ request
+ pub const KRB_TGS_REP : MessageType = MessageType(13);
+ /// Application request to server
+ pub const KRB_AP_REQ : MessageType = MessageType(14);
+ /// Response to KRB_AP_REQ_MUTUAL
+ pub const KRB_AP_REP : MessageType = MessageType(15);
+ /// Reserved for user-to-user krb_tgt_request
+ pub const KRB_RESERVED16 : MessageType = MessageType(16);
+ /// Reserved for user-to-user krb_tgt_reply
+ pub const KRB_RESERVED17 : MessageType = MessageType(17);
+ /// Safe (checksummed) application message
+ pub const KRB_SAFE : MessageType = MessageType(20);
+ /// Private (encrypted) application message
+ pub const KRB_PRIV : MessageType = MessageType(21);
+ /// Private (encrypted) message to forward credentials
+ pub const KRB_CRED : MessageType = MessageType(22);
+ /// Error response
+ pub const KRB_ERROR : MessageType = MessageType(30);
+}
+
+impl fmt::Debug for MessageType {
+ #[rustfmt::skip]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self.0 {
+ 10 => f.write_str("KRB_AS_REQ"),
+ 11 => f.write_str("KRB_AS_REP"),
+ 12 => f.write_str("KRB_TGS_REQ"),
+ 13 => f.write_str("KRB_TGS_REP"),
+ 14 => f.write_str("KRB_AP_REQ"),
+ 15 => f.write_str("KRB_AP_REP"),
+ 16 => f.write_str("KRB_RESERVED16"),
+ 17 => f.write_str("KRB_RESERVED17"),
+ 20 => f.write_str("KRB_SAFE"),
+ 21 => f.write_str("KRB_PRIV"),
+ 22 => f.write_str("KRB_CRED"),
+ 30 => f.write_str("KRB_ERROR"),
+ n => f.debug_tuple("MessageType").field(&n).finish(),
+ }
+ }
+}
+
+/// Name type
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub struct NameType(pub i32);
+
+#[rustfmt::skip]
+impl NameType {
+ /// Name type not known
+ pub const KRB_NT_UNKNOWN : NameType = NameType(0);
+ /// Just the name of the principal as in DCE, or for users
+ pub const KRB_NT_PRINCIPAL : NameType = NameType(1);
+ /// Service and other unique instance (krbtgt)
+ pub const KRB_NT_SRV_INST : NameType = NameType(2);
+ /// Service with host name as instance (telnet, rcommands)
+ pub const KRB_NT_SRV_HST : NameType = NameType(3);
+ /// Service with host as remaining components
+ pub const KRB_NT_SRV_XHST : NameType = NameType(4);
+ /// Unique ID
+ pub const KRB_NT_UID : NameType = NameType(5);
+ /// Encoded X.509 Distinguished name [RFC2253]
+ pub const KRB_NT_X500_PRINCIPAL : NameType = NameType(6);
+ /// Name in form of SMTP email name (e.g., user@example.com)
+ pub const KRB_NT_SMTP_NAME : NameType = NameType(7);
+ /// Enterprise name; may be mapped to principal name
+ pub const KRB_NT_ENTERPRISE : NameType = NameType(10);
+}
+
+impl fmt::Debug for NameType {
+ #[rustfmt::skip]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self.0 {
+ 0 => f.write_str("KRB_NT_UNKNOWN"),
+ 1 => f.write_str("KRB_NT_PRINCIPAL"),
+ 2 => f.write_str("KRB_NT_SRV_INST"),
+ 3 => f.write_str("KRB_NT_SRV_HST"),
+ 4 => f.write_str("KRB_NT_SRV_XHST"),
+ 5 => f.write_str("KRB_NT_UID"),
+ 6 => f.write_str("KRB_NT_X500_PRINCIPAL"),
+ 7 => f.write_str("KRB_NT_SMTP_NAME"),
+ 10 => f.write_str("KRB_NT_ENTERPRISE"),
+ n => f.debug_tuple("NameType").field(&n).finish(),
+ }
+ }
+}
+
+/// PA-Data type
+#[derive(Clone, Copy, PartialEq, Eq)]
+pub struct PAType(pub i32);
+
+#[rustfmt::skip]
+impl PAType {
+ /// DER encoding of AP-REQ
+ pub const PA_TGS_REQ : PAType = PAType(1);
+ /// DER encoding of PA-ENC-TIMESTAMP
+ pub const PA_ENC_TS : PAType = PAType(2);
+ /// salt (not ASN.1 encoded)
+ pub const PA_PW_SALT : PAType = PAType(3);
+ /// DER encoding of ETYPE-INFO
+ pub const PA_ETYPE_INFO : PAType = PAType(11);
+ /// DER encoding of ETYPE-INFO2
+ pub const PA_ETYPE_INFO2 : PAType = PAType(19);
+ /// Windows PAC request
+ pub const PA_PAC_REQUEST : PAType = PAType(128);
+ /// Support for FAST pre-auth mechanism
+ pub const PA_REQ_ENC_PA_REP : PAType = PAType(149);
+}
+
+impl fmt::Debug for PAType {
+ #[rustfmt::skip]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self.0 {
+ 1 => f.write_str("pa-tgs-req"),
+ 2 => f.write_str("pa-enc-timestamp"),
+ 3 => f.write_str("pa-pw-salt"),
+ 11 => f.write_str("pa-etype-info"),
+ 19 => f.write_str("pa-etype-info2"),
+ 128 => f.write_str("pa-pac-request"),
+ 149 => f.write_str("pa-req-enc-pa-rep"),
+ n => f.debug_tuple("PAType").field(&n).finish(),
+ }
+ }
+}
diff --git a/rust/vendor/kerberos-parser/src/krb5_errors.rs b/rust/vendor/kerberos-parser/src/krb5_errors.rs
new file mode 100644
index 0000000..989986d
--- /dev/null
+++ b/rust/vendor/kerberos-parser/src/krb5_errors.rs
@@ -0,0 +1,153 @@
+use std::fmt;
+
+#[derive(Clone, Copy, Eq, PartialEq)]
+pub struct ErrorCode(pub i32);
+
+#[rustfmt::skip]
+impl ErrorCode {
+ pub const KDC_ERR_NONE : ErrorCode = ErrorCode(0);
+ pub const KDC_ERR_NAME_EXP : ErrorCode = ErrorCode(1);
+ pub const KDC_ERR_SERVICE_EXP : ErrorCode = ErrorCode(2);
+ pub const KDC_ERR_BAD_PVNO : ErrorCode = ErrorCode(3);
+ pub const KDC_ERR_C_OLD_MAST_KVNO : ErrorCode = ErrorCode(4);
+ pub const KDC_ERR_S_OLD_MAST_KVNO : ErrorCode = ErrorCode(5);
+ pub const KDC_ERR_C_PRINCIPAL_UNKNOWN : ErrorCode = ErrorCode(6);
+ pub const KDC_ERR_S_PRINCIPAL_UNKNOWN : ErrorCode = ErrorCode(7);
+ pub const KDC_ERR_PRINCIPAL_NOT_UNIQUE : ErrorCode = ErrorCode(8);
+ pub const KDC_ERR_NULL_KEY : ErrorCode = ErrorCode(9);
+ pub const KDC_ERR_CANNOT_POSTDATE : ErrorCode = ErrorCode(10);
+ pub const KDC_ERR_NEVER_VALID : ErrorCode = ErrorCode(11);
+ pub const KDC_ERR_POLICY : ErrorCode = ErrorCode(12);
+ pub const KDC_ERR_BADOPTION : ErrorCode = ErrorCode(13);
+ pub const KDC_ERR_ETYPE_NOSUPP : ErrorCode = ErrorCode(14);
+ pub const KDC_ERR_SUMTYPE_NOSUPP : ErrorCode = ErrorCode(15);
+ pub const KDC_ERR_PADATA_TYPE_NOSUPP : ErrorCode = ErrorCode(16);
+ pub const KDC_ERR_TRTYPE_NOSUPP : ErrorCode = ErrorCode(17);
+ pub const KDC_ERR_CLIENT_REVOKED : ErrorCode = ErrorCode(18);
+ pub const KDC_ERR_SERVICE_REVOKED : ErrorCode = ErrorCode(19);
+ pub const KDC_ERR_TGT_REVOKED : ErrorCode = ErrorCode(20);
+ pub const KDC_ERR_CLIENT_NOTYET : ErrorCode = ErrorCode(21);
+ pub const KDC_ERR_SERVICE_NOTYET : ErrorCode = ErrorCode(22);
+ pub const KDC_ERR_KEY_EXPIRED : ErrorCode = ErrorCode(23);
+ pub const KDC_ERR_PREAUTH_FAILED : ErrorCode = ErrorCode(24);
+ pub const KDC_ERR_PREAUTH_REQUIRED : ErrorCode = ErrorCode(25);
+ pub const KDC_ERR_SERVER_NOMATCH : ErrorCode = ErrorCode(26);
+ pub const KDC_ERR_MUST_USE_USER2USER : ErrorCode = ErrorCode(27);
+ pub const KDC_ERR_PATH_NOT_ACCEPTED : ErrorCode = ErrorCode(28);
+ pub const KDC_ERR_SVC_UNAVAILABLE : ErrorCode = ErrorCode(29);
+ pub const KRB_AP_ERR_BAD_INTEGRITY : ErrorCode = ErrorCode(31);
+ pub const KRB_AP_ERR_TKT_EXPIRED : ErrorCode = ErrorCode(32);
+ pub const KRB_AP_ERR_TKT_NYV : ErrorCode = ErrorCode(33);
+ pub const KRB_AP_ERR_REPEAT : ErrorCode = ErrorCode(34);
+ pub const KRB_AP_ERR_NOT_US : ErrorCode = ErrorCode(35);
+ pub const KRB_AP_ERR_BADMATCH : ErrorCode = ErrorCode(36);
+ pub const KRB_AP_ERR_SKEW : ErrorCode = ErrorCode(37);
+ pub const KRB_AP_ERR_BADADDR : ErrorCode = ErrorCode(38);
+ pub const KRB_AP_ERR_BADVERSION : ErrorCode = ErrorCode(39);
+ pub const KRB_AP_ERR_MSG_TYPE : ErrorCode = ErrorCode(40);
+ pub const KRB_AP_ERR_MODIFIED : ErrorCode = ErrorCode(41);
+ pub const KRB_AP_ERR_BADORDER : ErrorCode = ErrorCode(42);
+ pub const KRB_AP_ERR_BADKEYVER : ErrorCode = ErrorCode(44);
+ pub const KRB_AP_ERR_NOKEY : ErrorCode = ErrorCode(45);
+ pub const KRB_AP_ERR_MUT_FAIL : ErrorCode = ErrorCode(46);
+ pub const KRB_AP_ERR_BADDIRECTION : ErrorCode = ErrorCode(47);
+ pub const KRB_AP_ERR_METHOD : ErrorCode = ErrorCode(48);
+ pub const KRB_AP_ERR_BADSEQ : ErrorCode = ErrorCode(49);
+ pub const KRB_AP_ERR_INAPP_CKSUM : ErrorCode = ErrorCode(50);
+ pub const KRB_AP_PATH_NOT_ACCEPTED : ErrorCode = ErrorCode(51);
+ pub const KRB_ERR_RESPONSE_TOO_BIG : ErrorCode = ErrorCode(52);
+ pub const KRB_ERR_GENERIC : ErrorCode = ErrorCode(60);
+ pub const KRB_ERR_FIELD_TOOLONG : ErrorCode = ErrorCode(61);
+ pub const KDC_ERROR_CLIENT_NOT_TRUSTED : ErrorCode = ErrorCode(62);
+ pub const KDC_ERROR_KDC_NOT_TRUSTED : ErrorCode = ErrorCode(63);
+ pub const KDC_ERROR_INVALID_SIG : ErrorCode = ErrorCode(64);
+ pub const KDC_ERR_KEY_TOO_WEAK : ErrorCode = ErrorCode(65);
+ pub const KDC_ERR_CERTIFICATE_MISMATCH : ErrorCode = ErrorCode(66);
+ pub const KRB_AP_ERR_NO_TGT : ErrorCode = ErrorCode(67);
+ pub const KDC_ERR_WRONG_REALM : ErrorCode = ErrorCode(68);
+ pub const KRB_AP_ERR_USER_TO_USER_REQUIRED : ErrorCode = ErrorCode(69);
+ pub const KDC_ERR_CANT_VERIFY_CERTIFICATE : ErrorCode = ErrorCode(70);
+ pub const KDC_ERR_INVALID_CERTIFICATE : ErrorCode = ErrorCode(71);
+ pub const KDC_ERR_REVOKED_CERTIFICATE : ErrorCode = ErrorCode(72);
+ pub const KDC_ERR_REVOCATION_STATUS_UNKNOWN : ErrorCode = ErrorCode(73);
+ pub const KDC_ERR_REVOCATION_STATUS_UNAVAILABLE : ErrorCode = ErrorCode(74);
+ pub const KDC_ERR_CLIENT_NAME_MISMATCH : ErrorCode = ErrorCode(75);
+ pub const KDC_ERR_KDC_NAME_MISMATCH : ErrorCode = ErrorCode(76);
+}
+
+impl fmt::Debug for ErrorCode {
+ #[rustfmt::skip]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self.0 {
+ 0 => f.write_str("KDC_ERR_NONE"),
+ 1 => f.write_str("KDC_ERR_NAME_EXP"),
+ 2 => f.write_str("KDC_ERR_SERVICE_EXP"),
+ 3 => f.write_str("KDC_ERR_BAD_PVNO"),
+ 4 => f.write_str("KDC_ERR_C_OLD_MAST_KVNO"),
+ 5 => f.write_str("KDC_ERR_S_OLD_MAST_KVNO"),
+ 6 => f.write_str("KDC_ERR_C_PRINCIPAL_UNKNOWN"),
+ 7 => f.write_str("KDC_ERR_S_PRINCIPAL_UNKNOWN"),
+ 8 => f.write_str("KDC_ERR_PRINCIPAL_NOT_UNIQUE"),
+ 9 => f.write_str("KDC_ERR_NULL_KEY"),
+ 10 => f.write_str("KDC_ERR_CANNOT_POSTDATE"),
+ 11 => f.write_str("KDC_ERR_NEVER_VALID"),
+ 12 => f.write_str("KDC_ERR_POLICY"),
+ 13 => f.write_str("KDC_ERR_BADOPTION"),
+ 14 => f.write_str("KDC_ERR_ETYPE_NOSUPP"),
+ 15 => f.write_str("KDC_ERR_SUMTYPE_NOSUPP"),
+ 16 => f.write_str("KDC_ERR_PADATA_TYPE_NOSUPP"),
+ 17 => f.write_str("KDC_ERR_TRTYPE_NOSUPP"),
+ 18 => f.write_str("KDC_ERR_CLIENT_REVOKED"),
+ 19 => f.write_str("KDC_ERR_SERVICE_REVOKED"),
+ 20 => f.write_str("KDC_ERR_TGT_REVOKED"),
+ 21 => f.write_str("KDC_ERR_CLIENT_NOTYET"),
+ 22 => f.write_str("KDC_ERR_SERVICE_NOTYET"),
+ 23 => f.write_str("KDC_ERR_KEY_EXPIRED"),
+ 24 => f.write_str("KDC_ERR_PREAUTH_FAILED"),
+ 25 => f.write_str("KDC_ERR_PREAUTH_REQUIRED"),
+ 26 => f.write_str("KDC_ERR_SERVER_NOMATCH"),
+ 27 => f.write_str("KDC_ERR_MUST_USE_USER2USER"),
+ 28 => f.write_str("KDC_ERR_PATH_NOT_ACCEPTED"),
+ 29 => f.write_str("KDC_ERR_SVC_UNAVAILABLE"),
+ 31 => f.write_str("KRB_AP_ERR_BAD_INTEGRITY"),
+ 32 => f.write_str("KRB_AP_ERR_TKT_EXPIRED"),
+ 33 => f.write_str("KRB_AP_ERR_TKT_NYV"),
+ 34 => f.write_str("KRB_AP_ERR_REPEAT"),
+ 35 => f.write_str("KRB_AP_ERR_NOT_US"),
+ 36 => f.write_str("KRB_AP_ERR_BADMATCH"),
+ 37 => f.write_str("KRB_AP_ERR_SKEW"),
+ 38 => f.write_str("KRB_AP_ERR_BADADDR"),
+ 39 => f.write_str("KRB_AP_ERR_BADVERSION"),
+ 40 => f.write_str("KRB_AP_ERR_MSG_TYPE"),
+ 41 => f.write_str("KRB_AP_ERR_MODIFIED"),
+ 42 => f.write_str("KRB_AP_ERR_BADORDER"),
+ 44 => f.write_str("KRB_AP_ERR_BADKEYVER"),
+ 45 => f.write_str("KRB_AP_ERR_NOKEY"),
+ 46 => f.write_str("KRB_AP_ERR_MUT_FAIL"),
+ 47 => f.write_str("KRB_AP_ERR_BADDIRECTION"),
+ 48 => f.write_str("KRB_AP_ERR_METHOD"),
+ 49 => f.write_str("KRB_AP_ERR_BADSEQ"),
+ 50 => f.write_str("KRB_AP_ERR_INAPP_CKSUM"),
+ 51 => f.write_str("KRB_AP_PATH_NOT_ACCEPTED"),
+ 52 => f.write_str("KRB_ERR_RESPONSE_TOO_BIG"),
+ 60 => f.write_str("KRB_ERR_GENERIC"),
+ 61 => f.write_str("KRB_ERR_FIELD_TOOLONG"),
+ 62 => f.write_str("KDC_ERROR_CLIENT_NOT_TRUSTED"),
+ 63 => f.write_str("KDC_ERROR_KDC_NOT_TRUSTED"),
+ 64 => f.write_str("KDC_ERROR_INVALID_SIG"),
+ 65 => f.write_str("KDC_ERR_KEY_TOO_WEAK"),
+ 66 => f.write_str("KDC_ERR_CERTIFICATE_MISMATCH"),
+ 67 => f.write_str("KRB_AP_ERR_NO_TGT"),
+ 68 => f.write_str("KDC_ERR_WRONG_REALM"),
+ 69 => f.write_str("KRB_AP_ERR_USER_TO_USER_REQUIRED"),
+ 70 => f.write_str("KDC_ERR_CANT_VERIFY_CERTIFICATE"),
+ 71 => f.write_str("KDC_ERR_INVALID_CERTIFICATE"),
+ 72 => f.write_str("KDC_ERR_REVOKED_CERTIFICATE"),
+ 73 => f.write_str("KDC_ERR_REVOCATION_STATUS_UNKNOWN"),
+ 74 => f.write_str("KDC_ERR_REVOCATION_STATUS_UNAVAILABLE"),
+ 75 => f.write_str("KDC_ERR_CLIENT_NAME_MISMATCH"),
+ 76 => f.write_str("KDC_ERR_KDC_NAME_MISMATCH"),
+ n => f.debug_tuple("ErrorCode").field(&n).finish(),
+ }
+ }
+}
diff --git a/rust/vendor/kerberos-parser/src/krb5_parser.rs b/rust/vendor/kerberos-parser/src/krb5_parser.rs
new file mode 100644
index 0000000..3244ba6
--- /dev/null
+++ b/rust/vendor/kerberos-parser/src/krb5_parser.rs
@@ -0,0 +1,587 @@
+//! Kerberos 5 parsing functions
+
+use der_parser::ber::*;
+use der_parser::der::*;
+use der_parser::error::*;
+use nom::combinator::{complete, map, map_res, opt, verify};
+use nom::error::{make_error, ErrorKind};
+use nom::multi::many1;
+use nom::{Err, IResult};
+use std::str;
+
+use crate::krb5::*;
+
+/// Parse a signed 32 bits integer
+///
+/// <pre>
+/// Int32 ::= INTEGER (-2147483648..2147483647)
+/// -- signed values representable in 32 bits
+/// </pre>
+pub fn parse_der_int32(i: &[u8]) -> IResult<&[u8], i32, BerError> {
+ map_res(parse_der_integer, |x: DerObject| match x.content {
+ BerObjectContent::Integer(i) => match i.len() {
+ 1 => Ok(i[0] as i8 as i32),
+ 2 => Ok((i[0] as i8 as i32) << 8 | (i[1] as i32)),
+ 3 => Ok((i[0] as i8 as i32) << 16 | (i[1] as i32) << 8 | (i[2] as i32)),
+ 4 => Ok((i[0] as i8 as i32) << 24
+ | (i[1] as i32) << 16
+ | (i[2] as i32) << 8
+ | (i[3] as i32)),
+ _ => Err(BerError::IntegerTooLarge),
+ },
+ _ => Err(BerError::BerTypeError),
+ })(i)
+}
+
+// Microseconds ::= INTEGER (0..999999)
+// -- microseconds
+fn parse_der_microseconds(i: &[u8]) -> IResult<&[u8], u32, BerError> {
+ verify(parse_der_u32, |x: &u32| *x <= 999_999)(i)
+}
+
+/// Parse a Kerberos string object
+///
+/// <pre>
+/// KerberosString ::= GeneralString (IA5String)
+/// </pre>
+pub fn parse_kerberos_string(i: &[u8]) -> IResult<&[u8], String, BerError> {
+ match parse_der_generalstring(i) {
+ Ok((rem, ref obj)) => {
+ if let BerObjectContent::GeneralString(s) = obj.content {
+ match str::from_utf8(s) {
+ Ok(r) => Ok((rem, r.to_owned())),
+ Err(_) => Err(Err::Error(make_error(i, ErrorKind::IsNot))),
+ }
+ } else {
+ Err(Err::Error(make_error(i, ErrorKind::Tag)))
+ }
+ }
+ Err(e) => Err(e),
+ }
+}
+
+fn parse_kerberos_string_sequence(i: &[u8]) -> IResult<&[u8], Vec<String>, BerError> {
+ parse_ber_sequence_of_v(parse_kerberos_string)(i)
+}
+
+/// Parse Kerberos flags
+///
+/// <pre>
+/// KerberosFlags ::= BIT STRING (SIZE (32..MAX))
+/// -- minimum number of bits shall be sent,
+/// -- but no fewer than 32
+/// </pre>
+#[inline]
+pub fn parse_kerberos_flags(i: &[u8]) -> IResult<&[u8], DerObject, BerError> {
+ parse_der_bitstring(i)
+}
+
+/// Parse of a Kerberos Realm
+///
+/// <pre>
+/// Realm ::= KerberosString
+/// </pre>
+#[inline]
+pub fn parse_krb5_realm(i: &[u8]) -> IResult<&[u8], Realm, BerError> {
+ map(parse_kerberos_string, Realm)(i)
+}
+
+/// Parse Kerberos PrincipalName
+///
+/// <pre>
+/// PrincipalName ::= SEQUENCE {
+/// name-type [0] Int32,
+/// name-string [1] SEQUENCE OF KerberosString
+/// }
+/// </pre>
+pub fn parse_krb5_principalname(i: &[u8]) -> IResult<&[u8], PrincipalName, BerError> {
+ parse_ber_sequence_defined_g(|i, _| {
+ let (i, name_type) =
+ parse_ber_tagged_explicit_g(0, |a, _| map(parse_der_int32, NameType)(a))(i)?;
+ let (i, name_string) =
+ parse_ber_tagged_explicit_g(1, |a, _| parse_kerberos_string_sequence(a))(i)?;
+ Ok((
+ i,
+ PrincipalName {
+ name_type,
+ name_string,
+ },
+ ))
+ })(i)
+}
+
+/// Parse of a Kerberos Time
+///
+/// <pre>
+/// KerberosTime ::= GeneralizedTime -- with no fractional seconds
+/// </pre>
+#[inline]
+pub fn parse_kerberos_time(i: &[u8]) -> IResult<&[u8], DerObject, BerError> {
+ parse_der_generalizedtime(i)
+}
+
+/// Parse Kerberos HostAddress
+///
+/// <pre>
+/// HostAddress ::= SEQUENCE {
+/// addr-type [0] Int32,
+/// address [1] OCTET STRING
+/// }
+/// </pre>
+pub fn parse_krb5_hostaddress(i: &[u8]) -> IResult<&[u8], HostAddress, BerError> {
+ parse_ber_sequence_defined_g(|i, _| {
+ let (i, addr_type) =
+ parse_ber_tagged_explicit_g(0, |a, _| map(parse_der_int32, AddressType)(a))(i)?;
+ let (i, address) = parse_ber_tagged_explicit_g(1, |a, _| {
+ map_res(parse_ber_octetstring, |o| o.as_slice())(a)
+ })(i)?;
+ Ok((i, HostAddress { addr_type, address }))
+ })(i)
+}
+
+/// Parse Kerberos HostAddresses
+///
+/// <pre>
+/// -- NOTE: HostAddresses is always used as an OPTIONAL field and
+/// -- should not be empty.
+/// HostAddresses -- NOTE: subtly different from rfc1510,
+/// -- but has a value mapping and encodes the same
+/// ::= SEQUENCE OF HostAddress
+/// </pre>
+pub fn parse_krb5_hostaddresses(i: &[u8]) -> IResult<&[u8], Vec<HostAddress>, BerError> {
+ parse_ber_sequence_of_v(parse_krb5_hostaddress)(i)
+}
+
+/// Parse Kerberos Ticket
+///
+/// <pre>
+/// Ticket ::= [APPLICATION 1] SEQUENCE {
+/// tkt-vno [0] INTEGER (5),
+/// realm [1] Realm,
+/// sname [2] PrincipalName,
+/// enc-part [3] EncryptedData -- EncTicketPart
+/// }
+/// </pre>
+pub fn parse_krb5_ticket(i: &[u8]) -> IResult<&[u8], Ticket, BerError> {
+ parse_ber_tagged_explicit_g(BerTag(1), |i, hdr| {
+ if !hdr.is_application() {
+ return Err(Err::Error(BerError::InvalidTag));
+ }
+ parse_ber_sequence_defined_g(|i, _| {
+ let (i, tkt_vno) = parse_ber_tagged_explicit_g(0, |a, _| parse_der_u32(a))(i)?;
+ if tkt_vno != 5 {
+ return Err(Err::Error(BerError::Custom(5)));
+ }
+ let (i, realm) = parse_ber_tagged_explicit_g(1, |a, _| parse_krb5_realm(a))(i)?;
+ let (i, sname) = parse_ber_tagged_explicit_g(2, |a, _| parse_krb5_principalname(a))(i)?;
+ let (i, enc_part) = parse_ber_tagged_explicit_g(3, |a, _| parse_encrypted(a))(i)?;
+ let tkt = Ticket {
+ tkt_vno,
+ realm,
+ sname,
+ enc_part,
+ };
+ Ok((i, tkt))
+ })(i)
+ })(i)
+}
+
+/// Parse Kerberos EncryptedData
+///
+/// <pre>
+/// EncryptedData ::= SEQUENCE {
+/// etype [0] Int32 -- EncryptionType --,
+/// kvno [1] UInt32 OPTIONAL,
+/// cipher [2] OCTET STRING -- ciphertext
+/// }
+/// </pre>
+pub fn parse_encrypted(i: &[u8]) -> IResult<&[u8], EncryptedData, BerError> {
+ parse_ber_sequence_defined_g(|i, _| {
+ let (i, etype) =
+ parse_ber_tagged_explicit_g(0, |a, _| map(parse_der_int32, EncryptionType)(a))(i)?;
+ let (i, kvno) = opt(complete(parse_ber_tagged_explicit_g(1, |a, _| {
+ parse_der_u32(a)
+ })))(i)?;
+ let (i, cipher) =
+ parse_ber_tagged_explicit_g(2, |a, _| map_res(parse_der, |o| o.as_slice())(a))(i)?;
+ let enc = EncryptedData {
+ etype,
+ kvno,
+ cipher,
+ };
+ Ok((i, enc))
+ })(i)
+}
+
+/// Parse a Kerberos KDC Request
+///
+/// <pre>
+/// KDC-REQ ::= SEQUENCE {
+/// -- NOTE: first tag is [1], not [0]
+/// pvno [1] INTEGER (5) ,
+/// msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --),
+/// padata [3] SEQUENCE OF PA-DATA OPTIONAL
+/// -- NOTE: not empty --,
+/// req-body [4] KDC-REQ-BODY
+/// }
+/// </pre>
+pub fn parse_kdc_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError> {
+ parse_ber_sequence_defined_g(|i, _| {
+ let (i, pvno) = parse_ber_tagged_explicit_g(1, |a, _| parse_der_u32(a))(i)?;
+ let (i, msg_type) =
+ parse_ber_tagged_explicit_g(2, |a, _| map(parse_der_u32, MessageType)(a))(i)?;
+ let (i, padata) = parse_ber_tagged_explicit_g(3, |a, _| parse_krb5_padata_sequence(a))(i)
+ .unwrap_or_else(|_| (i, Vec::new()));
+ let (i, req_body) = parse_ber_tagged_explicit_g(4, |a, _| parse_kdc_req_body(a))(i)?;
+ let req = KdcReq {
+ pvno,
+ msg_type,
+ padata,
+ req_body,
+ };
+ Ok((i, req))
+ })(i)
+}
+
+/// Parse the body of a Kerberos KDC Request
+///
+/// <pre>
+/// KDC-REQ-BODY ::= SEQUENCE {
+/// kdc-options [0] KDCOptions,
+/// cname [1] PrincipalName OPTIONAL
+/// -- Used only in AS-REQ --,
+/// realm [2] Realm
+/// -- Server's realm
+/// -- Also client's in AS-REQ --,
+/// sname [3] PrincipalName OPTIONAL,
+/// from [4] KerberosTime OPTIONAL,
+/// till [5] KerberosTime,
+/// rtime [6] KerberosTime OPTIONAL,
+/// nonce [7] UInt32,
+/// etype [8] SEQUENCE OF Int32 -- EncryptionType
+/// -- in preference order --,
+/// addresses [9] HostAddresses OPTIONAL,
+/// enc-authorization-data [10] EncryptedData OPTIONAL
+/// -- AuthorizationData --,
+/// additional-tickets [11] SEQUENCE OF Ticket OPTIONAL
+/// -- NOTE: not empty
+/// }
+/// </pre>
+pub fn parse_kdc_req_body(i: &[u8]) -> IResult<&[u8], KdcReqBody, BerError> {
+ parse_ber_sequence_defined_g(|i, _| {
+ let (i, kdc_options) = parse_ber_tagged_explicit_g(0, |a, _| parse_kerberos_flags(a))(i)?;
+ let (i, cname) = opt(complete(parse_ber_tagged_explicit_g(1, |a, _| {
+ parse_krb5_principalname(a)
+ })))(i)?;
+ let (i, realm) = parse_ber_tagged_explicit_g(2, |a, _| parse_krb5_realm(a))(i)?;
+ let (i, sname) = opt(complete(parse_ber_tagged_explicit_g(3, |a, _| {
+ parse_krb5_principalname(a)
+ })))(i)?;
+ let (i, from) = opt(complete(parse_ber_tagged_explicit_g(4, |a, _| {
+ parse_kerberos_time(a)
+ })))(i)?;
+ let (i, till) = parse_ber_tagged_explicit_g(5, |a, _| parse_kerberos_time(a))(i)?;
+ let (i, rtime) = opt(complete(parse_ber_tagged_explicit_g(6, |a, _| {
+ parse_kerberos_time(a)
+ })))(i)?;
+ let (i, nonce) = parse_ber_tagged_explicit_g(7, |a, _| parse_der_u32(a))(i)?;
+ let (i, etype) = parse_ber_tagged_explicit_g(8, |a, _| {
+ map(parse_ber_sequence_of_v(parse_der_int32), |v| {
+ v.iter().map(|&x| EncryptionType(x)).collect()
+ })(a)
+ })(i)?;
+ let (i, addresses) = opt(complete(parse_ber_tagged_explicit_g(9, |a, _| {
+ parse_krb5_hostaddresses(a)
+ })))(i)?;
+ let addresses = addresses.unwrap_or_default();
+ let (i, enc_authorization_data) =
+ opt(complete(parse_ber_tagged_explicit_g(10, |a, _| {
+ parse_encrypted(a)
+ })))(i)?;
+ let (i, additional_tickets) = opt(complete(parse_ber_tagged_explicit_g(11, |a, _| {
+ many1(complete(parse_krb5_ticket))(a)
+ })))(i)?;
+ let additional_tickets = additional_tickets.unwrap_or_default();
+ let body = KdcReqBody {
+ kdc_options,
+ cname,
+ realm,
+ sname,
+ from,
+ till,
+ rtime,
+ nonce,
+ etype,
+ addresses,
+ enc_authorization_data,
+ additional_tickets,
+ };
+ Ok((i, body))
+ })(i)
+}
+
+/// Parse a Kerberos AS Request
+///
+/// <pre>
+/// AS-REQ ::= [APPLICATION 10] KDC-REQ
+/// </pre>
+pub fn parse_as_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError> {
+ parse_ber_tagged_explicit_g(BerTag(10), |i, hdr| {
+ if !hdr.is_application() {
+ return Err(Err::Error(BerError::InvalidTag));
+ }
+ parse_kdc_req(i)
+ })(i)
+}
+
+/// Parse a Kerberos TGS Request
+///
+/// <pre>
+/// TGS-REQ ::= [APPLICATION 12] KDC-REQ
+/// </pre>
+pub fn parse_tgs_req(i: &[u8]) -> IResult<&[u8], KdcReq, BerError> {
+ parse_ber_tagged_explicit_g(BerTag(12), |i, hdr| {
+ if !hdr.is_application() {
+ return Err(Err::Error(BerError::InvalidTag));
+ }
+ parse_kdc_req(i)
+ })(i)
+}
+
+/// Parse a Kerberos KDC Reply
+///
+/// <pre>
+/// KDC-REP ::= SEQUENCE {
+/// pvno [0] INTEGER (5),
+/// msg-type [1] INTEGER (11 -- AS -- | 13 -- TGS --),
+/// padata [2] SEQUENCE OF PA-DATA OPTIONAL
+/// -- NOTE: not empty --,
+/// crealm [3] Realm,
+/// cname [4] PrincipalName,
+/// ticket [5] Ticket,
+/// enc-part [6] EncryptedData
+/// -- EncASRepPart or EncTGSRepPart,
+/// -- as appropriate
+/// }
+/// </pre>
+pub fn parse_kdc_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError> {
+ parse_ber_sequence_defined_g(|i, _| {
+ let (i, pvno) = parse_ber_tagged_explicit_g(0, |a, _| parse_der_u32(a))(i)?;
+ let (i, msg_type) =
+ parse_ber_tagged_explicit_g(1, |a, _| map(parse_der_u32, MessageType)(a))(i)?;
+ let (i, padata) = parse_ber_tagged_explicit_g(2, |a, _| parse_krb5_padata_sequence(a))(i)
+ .unwrap_or_else(|_| (i, Vec::new()));
+ let (i, crealm) = parse_ber_tagged_explicit_g(3, |a, _| parse_krb5_realm(a))(i)?;
+ let (i, cname) = parse_ber_tagged_explicit_g(4, |a, _| parse_krb5_principalname(a))(i)?;
+ let (i, ticket) = parse_ber_tagged_explicit_g(5, |a, _| parse_krb5_ticket(a))(i)?;
+ let (i, enc_part) = parse_ber_tagged_explicit_g(6, |a, _| parse_encrypted(a))(i)?;
+ let rep = KdcRep {
+ pvno,
+ msg_type,
+ padata,
+ crealm,
+ cname,
+ ticket,
+ enc_part,
+ };
+ Ok((i, rep))
+ })(i)
+}
+
+/// Parse a Kerberos AS Reply
+///
+/// <pre>
+/// AS-REP ::= [APPLICATION 11] KDC-REP
+/// </pre>
+pub fn parse_as_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError> {
+ parse_ber_tagged_explicit_g(BerTag(11), |i, hdr| {
+ if !hdr.is_application() {
+ return Err(Err::Error(BerError::InvalidTag));
+ }
+ parse_kdc_rep(i)
+ })(i)
+}
+
+/// Parse a Kerberos TGS Reply
+///
+/// <pre>
+/// TGS-REP ::= [APPLICATION 13] KDC-REP
+/// </pre>
+pub fn parse_tgs_rep(i: &[u8]) -> IResult<&[u8], KdcRep, BerError> {
+ parse_ber_tagged_explicit_g(BerTag(13), |i, hdr| {
+ if !hdr.is_application() {
+ return Err(Err::Error(BerError::InvalidTag));
+ }
+ parse_kdc_rep(i)
+ })(i)
+}
+
+/// Parse a Kerberos Error
+///
+/// <pre>
+/// KRB-ERROR ::= [APPLICATION 30] SEQUENCE {
+/// pvno [0] INTEGER (5),
+/// msg-type [1] INTEGER (30),
+/// ctime [2] KerberosTime OPTIONAL,
+/// cusec [3] Microseconds OPTIONAL,
+/// stime [4] KerberosTime,
+/// susec [5] Microseconds,
+/// error-code [6] Int32,
+/// crealm [7] Realm OPTIONAL,
+/// cname [8] PrincipalName OPTIONAL,
+/// realm [9] Realm -- service realm --,
+/// sname [10] PrincipalName -- service name --,
+/// e-text [11] KerberosString OPTIONAL,
+/// e-data [12] OCTET STRING OPTIONAL
+/// }
+/// </pre>
+pub fn parse_krb_error(i: &[u8]) -> IResult<&[u8], KrbError, BerError> {
+ parse_ber_tagged_explicit_g(BerTag(30), |i, hdr| {
+ if !hdr.is_application() {
+ return Err(Err::Error(BerError::InvalidTag));
+ }
+ parse_ber_sequence_defined_g(|i, _| {
+ let (i, pvno) = parse_ber_tagged_explicit_g(0, |a, _| parse_der_u32(a))(i)?;
+ let (i, msg_type) =
+ parse_ber_tagged_explicit_g(1, |a, _| map(parse_der_u32, MessageType)(a))(i)?;
+ let (i, ctime) = opt(complete(parse_ber_tagged_explicit_g(2, |a, _| {
+ parse_kerberos_time(a)
+ })))(i)?;
+ let (i, cusec) = opt(complete(parse_ber_tagged_explicit_g(3, |a, _| {
+ parse_der_microseconds(a)
+ })))(i)?;
+ let (i, stime) = parse_ber_tagged_explicit_g(4, |a, _| parse_kerberos_time(a))(i)?;
+ let (i, susec) = parse_ber_tagged_explicit_g(5, |a, _| parse_der_microseconds(a))(i)?;
+ let (i, error_code) =
+ parse_ber_tagged_explicit_g(6, |a, _| map(parse_der_int32, ErrorCode)(a))(i)?;
+ let (i, crealm) = opt(complete(parse_ber_tagged_explicit_g(7, |a, _| {
+ parse_krb5_realm(a)
+ })))(i)?;
+ let (i, cname) = opt(complete(parse_ber_tagged_explicit_g(8, |a, _| {
+ parse_krb5_principalname(a)
+ })))(i)?;
+ let (i, realm) = parse_ber_tagged_explicit_g(9, |a, _| parse_krb5_realm(a))(i)?;
+ let (i, sname) =
+ parse_ber_tagged_explicit_g(10, |a, _| parse_krb5_principalname(a))(i)?;
+ let (i, etext) = opt(complete(parse_ber_tagged_explicit_g(11, |a, _| {
+ parse_kerberos_string(a)
+ })))(i)?;
+ let (i, edata) = opt(complete(parse_ber_tagged_explicit_g(12, |a, _| {
+ parse_der_octetstring(a)
+ })))(i)?;
+ let err = KrbError {
+ pvno,
+ msg_type,
+ ctime,
+ cusec,
+ stime,
+ susec,
+ error_code,
+ crealm,
+ cname,
+ realm,
+ sname,
+ etext,
+ edata,
+ };
+ Ok((i, err))
+ })(i)
+ })(i)
+}
+
+/// Parse Kerberos PA-Data
+///
+/// <pre>
+/// PA-DATA ::= SEQUENCE {
+/// -- NOTE: first tag is [1], not [0]
+/// padata-type [1] Int32,
+/// padata-value [2] OCTET STRING -- might be encoded AP-REQ
+/// }
+/// </pre>
+pub fn parse_krb5_padata(i: &[u8]) -> IResult<&[u8], PAData, BerError> {
+ parse_ber_sequence_defined_g(|i, _| {
+ let (i, padata_type) =
+ parse_ber_tagged_explicit_g(1, |a, _| map(parse_der_int32, PAType)(a))(i)?;
+ let (i, padata_value) =
+ parse_ber_tagged_explicit_g(2, |a, _| map_res(parse_der, |o| o.as_slice())(a))(i)?;
+ let padata = PAData {
+ padata_type,
+ padata_value,
+ };
+ Ok((i, padata))
+ })(i)
+}
+
+fn parse_krb5_padata_sequence(i: &[u8]) -> IResult<&[u8], Vec<PAData>, BerError> {
+ parse_ber_sequence_of_v(parse_krb5_padata)(i)
+}
+
+/// Parse a Kerberos AP Request
+///
+/// <pre>
+/// AP-REQ ::= [APPLICATION 14] SEQUENCE {
+/// pvno [0] INTEGER (5),
+/// msg-type [1] INTEGER (14),
+/// ap-options [2] APOptions,
+/// ticket [3] Ticket,
+/// authenticator [4] EncryptedData -- Authenticator
+/// }
+///
+/// APOptions ::= KerberosFlags
+/// -- reserved(0),
+/// -- use-session-key(1),
+/// -- mutual-required(2)
+/// </pre>
+pub fn parse_ap_req(i: &[u8]) -> IResult<&[u8], ApReq, BerError> {
+ parse_ber_tagged_explicit_g(BerTag(14), |i, hdr| {
+ if !hdr.is_application() {
+ return Err(Err::Error(BerError::InvalidTag));
+ }
+ parse_ber_sequence_defined_g(|i, _| {
+ let (i, pvno) = parse_ber_tagged_explicit_g(0, |a, _| parse_der_u32(a))(i)?;
+ let (i, msg_type) =
+ parse_ber_tagged_explicit_g(1, |a, _| map(parse_der_u32, MessageType)(a))(i)?;
+ let (i, ap_options) =
+ parse_ber_tagged_explicit_g(2, |a, _| parse_kerberos_flags(a))(i)?;
+ let (i, ticket) = parse_ber_tagged_explicit_g(3, |a, _| parse_krb5_ticket(a))(i)?;
+ let (i, authenticator) = parse_ber_tagged_explicit_g(4, |a, _| parse_encrypted(a))(i)?;
+ let req = ApReq {
+ pvno,
+ msg_type,
+ ap_options,
+ ticket,
+ authenticator,
+ };
+ Ok((i, req))
+ })(i)
+ })(i)
+}
+
+/// Parse a Kerberos AP Reply
+///
+/// <pre>
+/// AP-REP ::= [APPLICATION 15] SEQUENCE {
+/// pvno [0] INTEGER (5),
+/// msg-type [1] INTEGER (15),
+/// enc-part [2] EncryptedData -- EncAPRepPart
+/// }
+/// </pre>
+pub fn parse_ap_rep(i: &[u8]) -> IResult<&[u8], ApRep, BerError> {
+ parse_ber_tagged_explicit_g(BerTag(15), |i, hdr| {
+ if !hdr.is_application() {
+ return Err(Err::Error(BerError::InvalidTag));
+ }
+ parse_ber_sequence_defined_g(|i, _| {
+ let (i, pvno) = parse_ber_tagged_explicit_g(0, |a, _| parse_der_u32(a))(i)?;
+ let (i, msg_type) =
+ parse_ber_tagged_explicit_g(1, |a, _| map(parse_der_u32, MessageType)(a))(i)?;
+ let (i, enc_part) = parse_ber_tagged_explicit_g(2, |a, _| parse_encrypted(a))(i)?;
+ let rep = ApRep {
+ pvno,
+ msg_type,
+ enc_part,
+ };
+ Ok((i, rep))
+ })(i)
+ })(i)
+}
diff --git a/rust/vendor/kerberos-parser/src/lib.rs b/rust/vendor/kerberos-parser/src/lib.rs
new file mode 100644
index 0000000..d2d6794
--- /dev/null
+++ b/rust/vendor/kerberos-parser/src/lib.rs
@@ -0,0 +1,45 @@
+//! # Kerberos Parser
+//!
+//! A Kerberos v5 ([RFC4120]) parser, implemented with the [nom](https://github.com/Geal/nom)
+//! parser combinator framework.
+//!
+//! The code is available on [Github](https://github.com/rusticata/kerberos-parser).
+//!
+//! Specific parsing functions are provided for Kerberos message types. For ex. to parse a
+//! KRB_AS_REQ message, use [`parse_as_req`](krb5_parser/fn.parse_as_req.html).
+//!
+//! # Examples
+//!
+//! Parsing a KRB_AS_REQ message:
+//!
+//! ```rust,no_run
+//! use kerberos_parser::krb5::MessageType;
+//! use kerberos_parser::krb5_parser::parse_as_req;
+//!
+//! static AS_REQ: &'static [u8] = include_bytes!("../assets/as-req.bin");
+//!
+//! # fn main() {
+//! let res = parse_as_req(AS_REQ);
+//! match res {
+//! Ok((rem, kdc_req)) => {
+//! assert!(rem.is_empty());
+//! //
+//! assert_eq!(kdc_req.msg_type, MessageType::KRB_AS_REQ);
+//! },
+//! _ => panic!("KRB_AS_REQ parsing failed: {:?}", res),
+//! }
+//! # }
+//! ```
+//!
+//! [RFC4120]: https://tools.ietf.org/html/rfc4120
+
+#![deny(/*missing_docs,*/unsafe_code,
+ unstable_features,
+ unused_import_braces, unused_qualifications)]
+
+pub mod krb5;
+pub mod krb5_parser;
+
+mod krb5_constants;
+mod krb5_errors;
+pub use krb5_errors::*;
diff --git a/rust/vendor/kerberos-parser/tests/krb5_parser.rs b/rust/vendor/kerberos-parser/tests/krb5_parser.rs
new file mode 100644
index 0000000..012c8c3
--- /dev/null
+++ b/rust/vendor/kerberos-parser/tests/krb5_parser.rs
@@ -0,0 +1,253 @@
+use kerberos_parser::krb5::*;
+use kerberos_parser::krb5_parser::*;
+
+#[test]
+fn test_parse_kerberos_string() {
+ let bytes = &[0x1b, 0x04, 0x63, 0x69, 0x66, 0x73];
+ let empty = &b""[..];
+ let expected = Realm(String::from("cifs"));
+
+ let res = parse_krb5_realm(bytes);
+ assert_eq!(res, Ok((empty, expected)));
+}
+
+#[test]
+fn test_parse_realm() {
+ let bytes = &[0x1b, 0x05, 0x4a, 0x6f, 0x6e, 0x65, 0x73];
+ let empty = &b""[..];
+ let expected = Realm(String::from("Jones"));
+
+ let res = parse_krb5_realm(bytes);
+ assert_eq!(res, Ok((empty, expected)));
+}
+
+#[test]
+fn test_parse_principalname() {
+ let bytes = &[
+ 0x30, 0x81, 0x11, 0xa0, 0x03, 0x02, 0x01, 0x00, 0xa1, 0x0a, 0x30, 0x81, 0x07, 0x1b, 0x05,
+ 0x4a, 0x6f, 0x6e, 0x65, 0x73,
+ ];
+ let empty = &b""[..];
+ let expected = PrincipalName {
+ name_type: NameType(0),
+ name_string: vec![String::from("Jones")],
+ };
+
+ let res = parse_krb5_principalname(bytes);
+ assert_eq!(res, Ok((empty, expected)));
+}
+
+#[test]
+fn test_parse_principalname2() {
+ let bytes = &[
+ 0x30, 0x27, 0xa0, 0x03, 0x02, 0x01, 0x02, 0xa1, 0x20, 0x30, 0x1e, 0x1b, 0x04, 0x63, 0x69,
+ 0x66, 0x73, 0x1b, 0x16, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x2d, 0x50, 0x43, 0x2e, 0x63, 0x6f,
+ 0x6e, 0x74, 0x6f, 0x73, 0x6f, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
+ ];
+ let empty = &b""[..];
+ let expected = PrincipalName {
+ name_type: NameType::KRB_NT_SRV_INST,
+ name_string: vec![String::from("cifs"), String::from("Admin-PC.contoso.local")],
+ };
+
+ let res = parse_krb5_principalname(bytes);
+ assert_eq!(res, Ok((empty, expected)));
+}
+
+static KRB5_TICKET: &[u8] = include_bytes!("../assets/krb5-ticket.bin");
+#[test]
+fn test_parse_ticket() {
+ let bytes = KRB5_TICKET;
+
+ let res = parse_krb5_ticket(bytes);
+ // println!("parse_krb5_ticket: {:?}", res);
+ match res {
+ Ok((rem, tkt)) => {
+ assert!(rem.is_empty());
+ assert_eq!(tkt.tkt_vno, 5);
+ assert_eq!(tkt.realm, Realm(String::from("CONTOSO.LOCAL")));
+ assert_eq!(
+ tkt.sname,
+ PrincipalName {
+ name_type: NameType::KRB_NT_SRV_INST,
+ name_string: vec![String::from("cifs"), String::from("Admin-PC.contoso.local")]
+ }
+ );
+ let enc = &tkt.enc_part;
+ // println!("enc: {:?}", enc);
+ assert_eq!(enc.etype, EncryptionType::AES256_CTS_HMAC_SHA1_96);
+ assert_eq!(enc.kvno, Some(1));
+ }
+ _ => panic!("parsing failed"),
+ }
+}
+
+static AS_REQ: &[u8] = include_bytes!("../assets/as-req.bin");
+#[test]
+fn test_parse_as_req() {
+ let bytes = AS_REQ;
+
+ let res = parse_as_req(bytes);
+ // println!("parse_as_req: {:?}", res);
+ match res {
+ Ok((rem, req)) => {
+ assert!(rem.is_empty());
+ assert_eq!(req.pvno, 5);
+ assert_eq!(req.msg_type, MessageType::KRB_AS_REQ);
+ assert_eq!(req.req_body.realm, Realm(String::from("DENYDC")));
+ assert_eq!(
+ req.req_body.cname,
+ Some(PrincipalName {
+ name_type: NameType::KRB_NT_PRINCIPAL,
+ name_string: vec![String::from("des")]
+ })
+ );
+ assert_eq!(
+ req.req_body.sname,
+ Some(PrincipalName {
+ name_type: NameType::KRB_NT_SRV_INST,
+ name_string: vec![String::from("krbtgt"), String::from("DENYDC")]
+ })
+ );
+ }
+ _ => panic!("parsing failed"),
+ }
+}
+
+static AS_REP: &[u8] = include_bytes!("../assets/as-rep.bin");
+#[test]
+fn test_parse_as_rep() {
+ let bytes = AS_REP;
+
+ let res = parse_as_rep(bytes);
+ // println!("parse_as_rep: {:?}", res);
+ match res {
+ Ok((rem, req)) => {
+ assert!(rem.is_empty());
+ assert_eq!(req.pvno, 5);
+ assert_eq!(req.msg_type, MessageType::KRB_AS_REP);
+ assert_eq!(req.crealm, Realm(String::from("DENYDC.COM")));
+ assert_eq!(
+ req.cname,
+ PrincipalName {
+ name_type: NameType::KRB_NT_PRINCIPAL,
+ name_string: vec![String::from("des")]
+ }
+ );
+ }
+ _ => panic!("parsing failed"),
+ }
+}
+
+static AP_REQ: &[u8] = include_bytes!("../assets/ap-req.bin");
+#[test]
+fn test_parse_ap_req() {
+ let bytes = AP_REQ;
+
+ let res = parse_ap_req(bytes);
+ // println!("parse_ap_req: {:?}", res);
+ match res {
+ Ok((rem, req)) => {
+ assert!(rem.is_empty());
+ assert_eq!(req.pvno, 5);
+ assert_eq!(req.msg_type, MessageType::KRB_AP_REQ);
+ assert_eq!(req.ticket.realm, Realm(String::from("DENYDC.COM")));
+ assert_eq!(
+ req.ticket.sname,
+ PrincipalName {
+ name_type: NameType::KRB_NT_SRV_INST,
+ name_string: vec![String::from("krbtgt"), String::from("DENYDC.COM")]
+ }
+ );
+ }
+ _ => panic!("parsing failed"),
+ }
+}
+
+static KRB_ERROR: &[u8] = include_bytes!("../assets/krb-error.bin");
+#[test]
+fn test_parse_krb_error() {
+ let bytes = KRB_ERROR;
+
+ let res = parse_krb_error(bytes);
+ // println!("parse_krb_error: {:?}", res);
+ match res {
+ Ok((rem, err)) => {
+ assert!(rem.is_empty());
+ assert_eq!(err.pvno, 5);
+ assert_eq!(err.msg_type, MessageType::KRB_ERROR);
+ assert_eq!(err.error_code, ErrorCode::KDC_ERR_ETYPE_NOSUPP);
+ assert_eq!(err.realm, Realm(String::from("DENYDC")));
+ assert_eq!(
+ err.sname,
+ PrincipalName {
+ name_type: NameType::KRB_NT_SRV_INST,
+ name_string: vec![String::from("krbtgt"), String::from("DENYDC")]
+ }
+ );
+ }
+ _ => panic!("parsing failed"),
+ }
+}
+
+static TGS_REP_NO_PADATA: &[u8] = include_bytes!("../assets/tgs-rep-no-padata.bin");
+#[test]
+fn test_parse_tgs_rep_no_padata() {
+ let bytes = TGS_REP_NO_PADATA;
+
+ let res = parse_tgs_rep(bytes);
+ match res {
+ Ok((rem, rep)) => {
+ assert!(rem.is_empty());
+ assert_eq!(rep.pvno, 5);
+ assert_eq!(rep.msg_type, MessageType::KRB_TGS_REP);
+ assert!(rep.padata.is_empty());
+ assert_eq!(rep.crealm, Realm(String::from("DENYDC.COM")));
+ assert_eq!(
+ rep.cname,
+ PrincipalName {
+ name_type: NameType::KRB_NT_PRINCIPAL,
+ name_string: vec![String::from("des")]
+ }
+ );
+ }
+ _ => panic!("parsing failed"),
+ }
+}
+
+#[test]
+fn test_parse_int32() {
+ let empty = &b""[..];
+ assert_eq!(parse_der_int32(&[0x02, 0x01, 0xff]), Ok((empty, -1)));
+ assert_eq!(parse_der_int32(&[0x02, 0x01, 0x01]), Ok((empty, 1)));
+ assert_eq!(parse_der_int32(&[0x02, 0x02, 0xff, 0xff]), Ok((empty, -1)));
+ assert_eq!(
+ parse_der_int32(&[0x02, 0x02, 0x01, 0x23]),
+ Ok((empty, 0x123))
+ );
+ assert_eq!(
+ parse_der_int32(&[0x02, 0x03, 0xff, 0xff, 0xff]),
+ Ok((empty, -1))
+ );
+ assert_eq!(
+ parse_der_int32(&[0x02, 0x03, 0x01, 0x23, 0x45]),
+ Ok((empty, 0x12345))
+ );
+ assert_eq!(
+ parse_der_int32(&[0x02, 0x04, 0xff, 0xff, 0xff, 0xff]),
+ Ok((empty, -1))
+ );
+ assert_eq!(
+ parse_der_int32(&[0x02, 0x04, 0x01, 0x23, 0x45, 0x67]),
+ Ok((empty, 0x1234567))
+ );
+}
+
+#[test]
+fn test_principalname_display() {
+ let pn = PrincipalName {
+ name_type: NameType::KRB_NT_SRV_INST,
+ name_string: vec!["krb5".to_string(), "DOMAIN.COM".to_string()],
+ };
+ assert_eq!("krb5/DOMAIN.COM", format!("{}", pn));
+}