├── docs └── xbvpn.md ├── libs ├── smoltcp-tun-tap │ ├── src │ │ └── lib.rs │ └── Cargo.toml ├── xblive │ ├── src │ │ ├── service.rs │ │ ├── crypto.rs │ │ ├── sg │ │ │ ├── udp.rs │ │ │ └── seq.rs │ │ ├── lib.rs │ │ ├── crypto │ │ │ └── keys.rs │ │ ├── arith.rs │ │ ├── time.rs │ │ ├── addr.rs │ │ ├── ver.rs │ │ ├── dns.rs │ │ └── krb.rs │ └── Cargo.toml ├── xombie │ ├── src │ │ ├── sg.rs │ │ ├── lib.rs │ │ ├── secrets.rs │ │ ├── account.rs │ │ └── ip.rs │ └── Cargo.toml ├── xdvd │ ├── src │ │ ├── redump.rs │ │ └── lib.rs │ └── Cargo.toml ├── block-device │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── file.rs │ │ └── partition.rs ├── xbox-sys │ ├── Cargo.toml │ └── src │ │ ├── crypto │ │ └── keys.rs │ │ ├── lib.rs │ │ ├── status.rs │ │ ├── eeprom.rs │ │ ├── fatx.rs │ │ ├── config.rs │ │ └── crypto.rs ├── xombie-matchmaking │ └── Cargo.toml └── smoltcp-user-vpn │ └── Cargo.toml ├── .gitignore ├── .dockerignore ├── third_party ├── red_asn1 │ ├── red_asn1 │ │ ├── LICENSE │ │ ├── README.md │ │ ├── src │ │ │ ├── tag │ │ │ │ ├── mod.rs │ │ │ │ ├── tagtype.rs │ │ │ │ └── tagclass.rs │ │ │ └── types │ │ │ │ ├── integer │ │ │ │ ├── mod.rs │ │ │ │ └── int_trait.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── boolean.rs │ │ │ │ └── generalstring.rs │ │ └── Cargo.toml │ ├── rustfmt.toml │ ├── red_asn1_derive │ │ ├── LICENSE │ │ ├── README.md │ │ ├── Cargo.toml │ │ └── src │ │ │ ├── parse_error.rs │ │ │ └── parse_definitions.rs │ ├── .gitignore │ └── .gitlab-ci.yml └── kerbeiros │ ├── rustfmt.toml │ ├── kerberos_asn1 │ ├── rustfmt.toml │ ├── src │ │ ├── realm.rs │ │ ├── pa_data │ │ │ ├── ad_if_relevant.rs │ │ │ ├── method_data.rs │ │ │ ├── pa_enc_timestamp.rs │ │ │ ├── ad_mandatory_for_kdc.rs │ │ │ ├── pa_supported_enctypes.rs │ │ │ ├── etype_info.rs │ │ │ ├── pa_s4u_x509_user.rs │ │ │ ├── ad_and_or.rs │ │ │ ├── etype_info_entry.rs │ │ │ ├── pa_for_user.rs │ │ │ ├── ad_kdcissued.rs │ │ │ ├── s4userid.rs │ │ │ ├── mod.rs │ │ │ ├── pa_pac_options.rs │ │ │ ├── kerb_pa_pac_request.rs │ │ │ ├── pa_enc_ts_enc.rs │ │ │ └── etype_info2_entry.rs │ │ ├── ap_options.rs │ │ ├── microseconds.rs │ │ ├── kerb_key_list_rep.rs │ │ ├── kerb_key_list_req.rs │ │ ├── kerb_local.rs │ │ ├── checksum.rs │ │ ├── kerb_error_data.rs │ │ ├── kerb_ad_restriction_entry.rs │ │ ├── ticket_flags.rs │ │ ├── transited_encoding.rs │ │ ├── ap_rep.rs │ │ ├── authorization_data.rs │ │ ├── krb_priv.rs │ │ ├── krb_safe.rs │ │ ├── kdc_options.rs │ │ ├── enc_ap_rep_part.rs │ │ ├── typed_data.rs │ │ ├── uint32.rs │ │ ├── krb_safe_body.rs │ │ ├── kerberos_string.rs │ │ ├── int32.rs │ │ ├── enc_krb_priv_part.rs │ │ ├── enc_krb_cred_part.rs │ │ ├── ap_req.rs │ │ ├── krb_cred.rs │ │ ├── tgs_req.rs │ │ ├── kdc_req.rs │ │ ├── last_req.rs │ │ ├── tgs_rep.rs │ │ ├── krb_cred_info.rs │ │ ├── enc_ticket_part.rs │ │ └── authenticator.rs │ ├── Cargo.toml │ └── README.md │ ├── kerberos_crypto │ ├── src │ │ ├── algorithms │ │ │ ├── mod.rs │ │ │ ├── rc4_hmac_md5 │ │ │ │ ├── preamble.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── encrypt.rs │ │ │ │ └── key.rs │ │ │ └── aes_hmac_sha1 │ │ │ │ ├── preamble.rs │ │ │ │ ├── mod.rs │ │ │ │ └── salt.rs │ │ ├── cryptography │ │ │ ├── md4lib.rs │ │ │ ├── md5.rs │ │ │ └── mod.rs │ │ ├── ciphers │ │ │ ├── mod.rs │ │ │ ├── factory.rs │ │ │ └── cipher_trait.rs │ │ ├── error.rs │ │ ├── lib.rs │ │ ├── helpers.rs │ │ └── utils.rs │ └── Cargo.toml │ ├── kerberos_ccache │ ├── src │ │ ├── header │ │ │ ├── mod.rs │ │ │ ├── delta_time.rs │ │ │ └── header.rs │ │ ├── auth_data.rs │ │ ├── mappers │ │ │ ├── mod.rs │ │ │ ├── octet_string_mapper.rs │ │ │ └── ticket_flags_mapper.rs │ │ ├── lib.rs │ │ └── error.rs │ ├── Cargo.toml │ └── README.md │ ├── .gitignore │ ├── kerberos_constants │ ├── src │ │ ├── ap_options.rs │ │ ├── tr_types.rs │ │ ├── protocol_version.rs │ │ ├── pa_pac_options.rs │ │ ├── kerb_error_data_type.rs │ │ ├── checksum_types.rs │ │ ├── address_types.rs │ │ ├── message_types.rs │ │ ├── etypes.rs │ │ ├── lib.rs │ │ ├── ad_types.rs │ │ ├── kdc_options.rs │ │ ├── ticket_flags.rs │ │ ├── principal_names.rs │ │ └── pa_data_types.rs │ └── Cargo.toml │ ├── kerbeiros │ ├── src │ │ ├── messages │ │ │ ├── asreq │ │ │ │ └── mod.rs │ │ │ └── mod.rs │ │ ├── credentials │ │ │ ├── mappers │ │ │ │ └── mod.rs │ │ │ ├── mod.rs │ │ │ └── file.rs │ │ ├── transporter │ │ │ ├── transporter_trait.rs │ │ │ ├── mod.rs │ │ │ ├── udp_transporter.rs │ │ │ └── tcp_transporter.rs │ │ ├── requesters │ │ │ └── mod.rs │ │ ├── mappers │ │ │ ├── mod.rs │ │ │ ├── octet_string_mapper.rs │ │ │ └── ticket_flags_mapper.rs │ │ ├── utils.rs │ │ └── lib.rs │ ├── Cargo.toml │ └── README.md │ ├── .gitlab-ci.yml │ ├── kerberos_keytab │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ └── README.md ├── frontend ├── .dockerignore ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── index.html ├── src │ ├── setupTests.js │ ├── App.test.js │ ├── index.css │ ├── reportWebVitals.js │ ├── index.js │ ├── App.js │ ├── App.css │ └── logo.svg ├── .gitignore ├── package.json └── Dockerfile ├── tools ├── xbltun │ ├── src │ │ └── main.rs │ └── Cargo.toml ├── mount-memory-card │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── xbeeprom │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── dvd-tool │ └── Cargo.toml ├── config-area-tool │ └── Cargo.toml ├── mem-card-tool │ └── Cargo.toml └── get-machine-account │ └── Cargo.toml ├── services ├── sg │ ├── src │ │ ├── user.rs │ │ ├── secrets.rs │ │ └── client │ │ │ ├── service │ │ │ └── unimplemented.rs │ │ │ └── forward.rs │ ├── Dockerfile │ └── Cargo.toml ├── api │ ├── Cargo.toml │ ├── Dockerfile │ └── src │ │ └── main.rs ├── faux-dns │ ├── Cargo.toml │ └── Dockerfile └── kdc │ ├── Dockerfile │ ├── Cargo.toml │ └── src │ └── krb.rs ├── healthchecks ├── redis.sh └── postgres.sh ├── nginx.conf ├── scripts └── install_dissectors.sh ├── Cargo.toml ├── Dockerfile ├── README.md └── docker-compose.yml /docs/xbvpn.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /libs/smoltcp-tun-tap/src/lib.rs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ignore_me/ 2 | target/ 3 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | ignore_me 3 | target 4 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /frontend/.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | build -------------------------------------------------------------------------------- /third_party/kerbeiros/rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 80 2 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /third_party/red_asn1/rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 80 2 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1_derive/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1_derive/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 80 2 | -------------------------------------------------------------------------------- /libs/xblive/src/service.rs: -------------------------------------------------------------------------------- 1 | pub mod matchmaking; 2 | pub mod presence; 3 | -------------------------------------------------------------------------------- /libs/xombie/src/sg.rs: -------------------------------------------------------------------------------- 1 | pub const CLIENT_TO_SG_TICKET_NONCE: u32 = 3000; 2 | -------------------------------------------------------------------------------- /libs/xdvd/src/redump.rs: -------------------------------------------------------------------------------- 1 | pub const DATA_PARTITION_START_SECTOR: u64 = 0x30600; 2 | -------------------------------------------------------------------------------- /tools/xbltun/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | println!("Hello, world!"); 3 | } 4 | -------------------------------------------------------------------------------- /libs/xblive/src/crypto.rs: -------------------------------------------------------------------------------- 1 | pub mod derivation; 2 | pub mod keys; 3 | pub mod primitives; 4 | -------------------------------------------------------------------------------- /libs/xdvd/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod fs; 2 | pub mod redump; 3 | 4 | pub const SECTOR_LEN: usize = 2048; 5 | -------------------------------------------------------------------------------- /frontend/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XombieOnline/xombie/HEAD/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XombieOnline/xombie/HEAD/frontend/public/logo192.png -------------------------------------------------------------------------------- /frontend/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XombieOnline/xombie/HEAD/frontend/public/logo512.png -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/algorithms/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod aes_hmac_sha1; 2 | pub mod rc4_hmac_md5; 3 | -------------------------------------------------------------------------------- /third_party/red_asn1/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | Cargo.lock 4 | 5 | 6 | # emacs files 7 | \#*\# 8 | -------------------------------------------------------------------------------- /libs/xblive/src/sg/udp.rs: -------------------------------------------------------------------------------- 1 | #[derive(Debug)] 2 | pub struct UdpHeader { 3 | pub src: u16, 4 | pub dst: u16, 5 | } 6 | -------------------------------------------------------------------------------- /tools/xbltun/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xbltun" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /libs/xombie/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod account; 2 | pub mod db; 3 | pub mod krb; 4 | pub mod ip; 5 | pub mod secrets; 6 | pub mod sg; 7 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_ccache/src/header/mod.rs: -------------------------------------------------------------------------------- 1 | mod delta_time; 2 | pub use delta_time::*; 3 | 4 | mod header; 5 | pub use header::*; 6 | -------------------------------------------------------------------------------- /libs/xdvd/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xdvd" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | hex-literal = "0.3.1" 8 | nom = "^7" 9 | -------------------------------------------------------------------------------- /third_party/kerbeiros/.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | target 3 | **/*.rs.bk 4 | Cargo.lock 5 | 6 | # Files produced by emacs 7 | \#*\# 8 | *~ 9 | .projectile 10 | -------------------------------------------------------------------------------- /tools/mount-memory-card/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mount-memory-card" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | rusb = "0.9" 8 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/ap_options.rs: -------------------------------------------------------------------------------- 1 | 2 | pub const RESERVED: u32 = 0; 3 | pub const USE_SESSION_KEY: u32 = 1; 4 | pub const MUTUAL_REQUIRED: u32 = 2; 5 | -------------------------------------------------------------------------------- /services/sg/src/user.rs: -------------------------------------------------------------------------------- 1 | use xbox_sys::account::Xuid; 2 | 3 | #[derive(Clone, Copy, Debug)] 4 | pub struct CombinedId { 5 | pub machine: Xuid, 6 | pub users: [Option; 4], 7 | } 8 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1/src/tag/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | mod tag; 3 | pub use tag::*; 4 | 5 | mod tagclass; 6 | pub use tagclass::*; 7 | 8 | mod tagtype; 9 | pub use tagtype::*; 10 | -------------------------------------------------------------------------------- /services/api/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "api" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | tokio = { version = "1", features = ["full"] } 8 | warp = "0.3" 9 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/cryptography/md4lib.rs: -------------------------------------------------------------------------------- 1 | use md4::{Digest, Md4}; 2 | 3 | pub fn md4(bytes: &[u8]) -> Vec { 4 | return Md4::digest(&bytes).to_vec(); 5 | } 6 | -------------------------------------------------------------------------------- /libs/smoltcp-tun-tap/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "smoltcp-tun-tap" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | smoltcp-user-vpn = { path = "../smoltcp-user-vpn" } 8 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/tr_types.rs: -------------------------------------------------------------------------------- 1 | //! The types of TransitedEncoding tr-type field. 2 | //! Defined in RFC4120, section 7.5.5. 3 | 4 | pub const DOMAIN_X500_COMPRESS: i32 = 1; 5 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/messages/asreq/mod.rs: -------------------------------------------------------------------------------- 1 | mod builder; 2 | pub(crate) use builder::AsReqBuilder; 3 | 4 | mod options; 5 | pub(crate) use options::AsReqOptions; 6 | 7 | mod timestamp_cipher; 8 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/credentials/mappers/mod.rs: -------------------------------------------------------------------------------- 1 | mod credential_krb_info; 2 | pub use credential_krb_info::*; 3 | 4 | mod credential_warehouse_krb_cred; 5 | pub use credential_warehouse_krb_cred::*; 6 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/realm.rs: -------------------------------------------------------------------------------- 1 | use super::KerberosString; 2 | 3 | /// (*Realm*) Kerberos realm. 4 | /// ```asn1 5 | /// Realm ::= KerberosString 6 | /// ``` 7 | pub type Realm = KerberosString; 8 | -------------------------------------------------------------------------------- /healthchecks/redis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eo pipefail 3 | 4 | host="$(hostname -i || echo '127.0.0.1')" 5 | 6 | if ping="$(redis-cli -h "$host" ping)" && [ "$ping" = 'PONG' ]; then 7 | exit 0 8 | fi 9 | 10 | exit 1 11 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/protocol_version.rs: -------------------------------------------------------------------------------- 1 | //! The protocol version of Kerberos V5 2 | //! 3 | //! Defined in RFC4120, section 7.5.6. 4 | 5 | /// The version of Kerberos protocol, which is 5. 6 | pub const PVNO: i32 = 5; 7 | -------------------------------------------------------------------------------- /libs/xombie/src/secrets.rs: -------------------------------------------------------------------------------- 1 | use hex_literal::hex; 2 | 3 | use xbox_sys::crypto::SymmetricKey; 4 | 5 | pub async fn get_sg_master_key(_sg_addr: [u8;4]) -> (SymmetricKey, Option) { 6 | (SymmetricKey(hex!["205cbb97cff0058123c22658fecd6898"]), None) 7 | } -------------------------------------------------------------------------------- /third_party/kerbeiros/.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: rust 2 | 3 | test: 4 | stage: test 5 | variables: 6 | RUSTFLAGS: "-Dwarnings" 7 | script: 8 | - cargo test 9 | 10 | build-doc: 11 | stage: test 12 | script: 13 | - cargo doc --no-deps 14 | -------------------------------------------------------------------------------- /tools/xbeeprom/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xbeeprom" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | clap = "2" 8 | hex-literal = "0.3.1" 9 | xbox-sys = { path = "../../libs/xbox-sys" } 10 | xblive = { path = "../../libs/xblive" } 11 | -------------------------------------------------------------------------------- /frontend/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/messages/mod.rs: -------------------------------------------------------------------------------- 1 | //! Groups the available messages which are sent and received from KDC. 2 | 3 | mod asreq; 4 | pub(crate) use asreq::*; 5 | 6 | pub use kerberos_asn1::AsRep; 7 | pub use kerberos_asn1::AsReq; 8 | pub use kerberos_asn1::KrbError; 9 | -------------------------------------------------------------------------------- /third_party/red_asn1/.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: rust 2 | 3 | test: 4 | stage: test 5 | variables: 6 | RUSTFLAGS: "-Dwarnings" 7 | script: 8 | - cargo test --workspace 9 | 10 | build-doc: 11 | stage: test 12 | script: 13 | - cargo doc --no-deps --workspace 14 | -------------------------------------------------------------------------------- /tools/dvd-tool/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dvd-tool" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | clap = { version = "3.1.6", features = ["derive"] } 8 | block-device = { path = "../../libs/block-device" } 9 | xdvd = { path = "../../libs/xdvd" } 10 | -------------------------------------------------------------------------------- /frontend/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /libs/xblive/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![warn(rust_2018_idioms)] 2 | 3 | pub mod addr; 4 | pub(crate) mod arith; 5 | // pub mod codec; 6 | pub mod crypto; 7 | pub mod dns; 8 | pub mod net; 9 | pub mod krb; 10 | pub mod service; 11 | pub mod sg; 12 | pub mod time; 13 | pub mod user; 14 | pub mod ver; 15 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/ciphers/mod.rs: -------------------------------------------------------------------------------- 1 | mod cipher_trait; 2 | pub use cipher_trait::KerberosCipher; 3 | 4 | mod aes; 5 | pub use aes::AesCipher; 6 | 7 | mod rc4; 8 | pub use rc4::Rc4Cipher; 9 | 10 | mod factory; 11 | pub use factory::new_kerberos_cipher; 12 | 13 | 14 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/algorithms/rc4_hmac_md5/preamble.rs: -------------------------------------------------------------------------------- 1 | use crate::utils::random_bytes; 2 | 3 | /// Generate an aleatory preamble to insert at the beginning of the 4 | /// plaintext before RC4 encryption 5 | pub fn generate_preamble() -> Vec { 6 | return random_bytes(8); 7 | } 8 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/transporter/transporter_trait.rs: -------------------------------------------------------------------------------- 1 | use crate::error::*; 2 | 3 | /// Trait implemented by classes which deliver Kerberos messages 4 | pub trait Transporter { 5 | /// Sends a message and retrieves the response 6 | fn request_and_response(&self, raw_request: &[u8]) -> Result>; 7 | } 8 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/ad_if_relevant.rs: -------------------------------------------------------------------------------- 1 | use crate::AuthorizationData; 2 | 3 | /// (*AD-IF-RELEVANT*) Type of *AuthorizationData*. 4 | /// Defined in RFC4120, section 5.2.6.1. 5 | /// ```asn1 6 | /// AD-IF-RELEVANT ::= AuthorizationData 7 | /// ``` 8 | pub type AdIfRelevant = AuthorizationData; 9 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/method_data.rs: -------------------------------------------------------------------------------- 1 | use crate::PaData; 2 | use red_asn1::SequenceOf; 3 | 4 | /// (*METHOD-DATA*) Sequence of *PA-DATA*. 5 | /// Defined in RFC4120, section 5.9.1. 6 | /// ```asn1 7 | /// METHOD-DATA ::= SEQUENCE OF PA-DATA 8 | /// ``` 9 | pub type MethodData = SequenceOf; 10 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/pa_enc_timestamp.rs: -------------------------------------------------------------------------------- 1 | use crate::EncryptedData; 2 | 3 | /// (*PA-ENC-TIMESTAMP*) Encrypted *PA-ENC-TS-ENC*. 4 | /// Defined in RFC4120, section 5.2.7.2. 5 | /// ```asn1 6 | /// PA-ENC-TIMESTAMP ::= EncryptedData -- PA-ENC-TS-ENC 7 | /// ``` 8 | pub type PaEncTimestamp = EncryptedData; 9 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1/src/types/integer/mod.rs: -------------------------------------------------------------------------------- 1 | mod general; 2 | mod int128; 3 | mod int16; 4 | mod int32; 5 | mod int64; 6 | mod int_trait; 7 | mod uint32; 8 | 9 | pub static INTEGER_TAG_NUMBER: u8 = 0x2; 10 | /// Class to build/parse Integer ASN1 11 | pub type Integer = i128; 12 | 13 | pub use int_trait::Asn1Int; 14 | -------------------------------------------------------------------------------- /libs/block-device/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "block-device" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | hex = { version = "0.4", optional = true } 8 | rusb = { version = "0.9.0", optional = true } 9 | 10 | [features] 11 | default = ["usb", "scsi"] 12 | usb = ["dep:hex", "dep:rusb", "scsi"] 13 | scsi = [] 14 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/ad_mandatory_for_kdc.rs: -------------------------------------------------------------------------------- 1 | use crate::AuthorizationData; 2 | 3 | /// (*AD-MANDATORY-FOR-KDC*) Type of *AuthorizationData*. 4 | /// Defined in RFC4120, section 5.2.6.4. 5 | /// ```asn1 6 | /// AD-MANDATORY-FOR-KDC ::= AuthorizationData 7 | /// ``` 8 | pub type AdMandatoryForKdc = AuthorizationData; 9 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/cryptography/md5.rs: -------------------------------------------------------------------------------- 1 | use crypto::md5::Md5; 2 | use crypto::digest::Digest; 3 | 4 | pub fn md5(bytes: &[u8]) -> Vec { 5 | let mut md5 = Md5::new(); 6 | let mut output = vec![0; md5.output_bytes()]; 7 | md5.input(bytes); 8 | md5.result(&mut output); 9 | return output; 10 | } 11 | -------------------------------------------------------------------------------- /libs/xbox-sys/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xbox-sys" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | bytes = { version = "^1", default-features = false } 8 | hex-literal = "0.3.1" 9 | nom = "^7" 10 | 11 | [features] 12 | default = ["std"] 13 | 14 | # enable support for the standard library 15 | std = ["bytes/std"] 16 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/requesters/mod.rs: -------------------------------------------------------------------------------- 1 | //! This module exports the classes that are responsible for send the different requests to the KDC and receive its responses 2 | 3 | mod as_requester; 4 | pub use as_requester::*; 5 | 6 | mod tgt_requester; 7 | pub use tgt_requester::*; 8 | 9 | pub use crate::transporter::TransportProtocol; 10 | -------------------------------------------------------------------------------- /libs/xombie-matchmaking/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xombie-matchmaking" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | log = { version = "0.4.4", default-features = false } 8 | rand = "0.7" 9 | tokio = { version = "1.12.0", features = ["full"] } 10 | xblive = { path = "../xblive" } 11 | xbox-sys = { path = "../xbox-sys" } 12 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/pa_supported_enctypes.rs: -------------------------------------------------------------------------------- 1 | use crate::Int32; 2 | 3 | /// (*PA-SUPPORTED-ENCTYPES*) specify the encryption types supported. 4 | /// Defined in MS-KILE, section 2.2.8. 5 | /// ```asn1 6 | /// PA-SUPPORTED-ENCTYPES ::= Int32 –Supported Encryption Types Bit Field-- 7 | /// ``` 8 | pub type PaSupportedEnctypes = Int32; 9 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_ccache/src/auth_data.rs: -------------------------------------------------------------------------------- 1 | use super::address::*; 2 | 3 | /// Container that encapsules different types of preauthentication data structures. 4 | /// # Definition 5 | /// ```c 6 | /// authdata { 7 | /// uint16_t authtype; 8 | /// counted_octet_string authdata; 9 | /// }; 10 | /// ``` 11 | /// 12 | pub type AuthData = Address; 13 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kerberos_constants" 3 | description = "Constants used by differente objects and actors of the Kerberos protocol" 4 | version = "0.0.9" 5 | authors = ["Eloy "] 6 | edition = "2018" 7 | license = "AGPL-3.0" 8 | repository = "https://gitlab.com/Zer1t0/kerbeiros" 9 | 10 | 11 | -------------------------------------------------------------------------------- /libs/smoltcp-user-vpn/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "smoltcp-user-vpn" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | async-trait = "^0.1" 8 | bytes = "^1" 9 | httparse = "1.7.1" 10 | log = { version = "0.4.4", default-features = false } 11 | smoltcp = "^0.8" 12 | tokio = { version = "1.12.0", features = ["full"] } 13 | tokio-stream = "0.1.8" 14 | -------------------------------------------------------------------------------- /services/faux-dns/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "faux-dns" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | clap = { version = "3.2.8", features = ["derive"] } 8 | nom = "^5.0" 9 | tokio = { version = "1.12.0", features = ["full"] } 10 | tokio-postgres = "0.7.3" 11 | xblive = { path = "../../libs/xblive" } 12 | xombie = { path = "../../libs/xombie" } 13 | -------------------------------------------------------------------------------- /tools/config-area-tool/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "config-area-tool" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | clap = { version = "3.1.6", features = ["derive"] } 8 | hex = "0.4.3" 9 | nom = "^7" 10 | rand = "0.7" 11 | xblive = { path = "../../libs/xblive" } 12 | xbox-sys = { path = "../../libs/xbox-sys" } 13 | xombie = { path = "../../libs/xombie" } 14 | -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | events { worker_connections 1024; } 2 | 3 | http { 4 | 5 | upstream app_servers { 6 | server api:80; 7 | } 8 | 9 | server { 10 | listen 80; 11 | 12 | location /api { 13 | proxy_pass http://app_servers; 14 | } 15 | 16 | location / { 17 | root /frontend; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/ap_options.rs: -------------------------------------------------------------------------------- 1 | use crate::KerberosFlags; 2 | 3 | /// (*ApOptions*) Options used in *AP-REQ*. 4 | /// Defined in RFC4120, section 5.5.1. 5 | /// ```asn1 6 | /// APOptions ::= KerberosFlags 7 | /// -- reserved(0), 8 | /// -- use-session-key(1), 9 | /// -- mutual-required(2) 10 | /// ``` 11 | pub type ApOptions = KerberosFlags; 12 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/etype_info.rs: -------------------------------------------------------------------------------- 1 | use crate::EtypeInfoEntry; 2 | use red_asn1::SequenceOf; 3 | 4 | /// (*ETYPE-INFO*) Sent in *KRB-ERROR* to require additional pre-authentication. 5 | /// Defined RFC4120, section 5.2.7.4. 6 | /// ```asn1 7 | /// ETYPE-INFO ::= SEQUENCE OF ETYPE-INFO-ENTRY 8 | /// ``` 9 | pub type EtypeInfo = SequenceOf; 10 | -------------------------------------------------------------------------------- /services/api/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.55 as builder 2 | 3 | RUN mkdir -p /opt/xombie 4 | COPY . /opt/xombie 5 | 6 | WORKDIR /opt/xombie/services/api 7 | RUN cargo build --release 8 | 9 | FROM debian:buster 10 | 11 | EXPOSE 80 12 | 13 | RUN mkdir -p /opt/xombie/bin 14 | WORKDIR /opt/xombie 15 | 16 | COPY --from=builder /opt/xombie/target/release/api /opt/xombie/bin/api 17 | 18 | CMD ["./bin/api"] 19 | -------------------------------------------------------------------------------- /scripts/install_dissectors.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_RELATIVE_DIR=$(dirname "${BASH_SOURCE[0]}") 4 | 5 | CONFIG_DIR="$XDG_CONFIG_HOME" 6 | 7 | if [ -z "$CONFIG_DIR" ]; then 8 | CONFIG_DIR="$HOME/.config" 9 | fi 10 | 11 | PLUGIN_DIR="$CONFIG_DIR/wireshark/plugins" 12 | 13 | if [[ -f "$PLUGIN_DIR" ]]; then 14 | mkdir -p "$PLUGIN_DIR" 15 | fi 16 | 17 | cp $SCRIPT_RELATIVE_DIR/*.lua "$PLUGIN_DIR" 18 | -------------------------------------------------------------------------------- /services/sg/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.55 as builder 2 | 3 | RUN mkdir -p /opt/xombie 4 | COPY . /opt/xombie 5 | 6 | WORKDIR /opt/xombie/services/sg 7 | RUN cargo build --release 8 | 9 | FROM debian:buster-slim 10 | 11 | EXPOSE 3074/udp 12 | 13 | RUN mkdir -p /opt/xombie/bin 14 | WORKDIR /opt/xombie 15 | 16 | COPY --from=builder /opt/xombie/target/release/sg /opt/xombie/bin/sg 17 | 18 | CMD ["./bin/sg"] 19 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/algorithms/aes_hmac_sha1/preamble.rs: -------------------------------------------------------------------------------- 1 | use crate::cryptography::{AesSizes}; 2 | use crate::utils::random_bytes; 3 | 4 | /// Generate an aleatory preamble to insert at the beginning of the 5 | /// plaintext before AES encryption 6 | pub fn generate_preamble( 7 | aes_sizes: &AesSizes 8 | ) -> Vec { 9 | return random_bytes(aes_sizes.block_size()); 10 | } 11 | -------------------------------------------------------------------------------- /tools/mount-memory-card/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | for device in rusb::devices().unwrap().iter() { 3 | let device_desc = device.device_descriptor().unwrap(); 4 | 5 | println!("Bus {:03} Device {:03} ID {:04x}:{:04x}", 6 | device.bus_number(), 7 | device.address(), 8 | device_desc.vendor_id(), 9 | device_desc.product_id()); 10 | } 11 | } -------------------------------------------------------------------------------- /services/kdc/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.55 as builder 2 | 3 | RUN mkdir -p /opt/xombie 4 | COPY . /opt/xombie 5 | 6 | WORKDIR /opt/xombie/services/kdc 7 | RUN cargo build --release 8 | 9 | FROM debian:buster-slim 10 | 11 | EXPOSE 88/udp 12 | 13 | RUN mkdir -p /opt/xombie/bin 14 | WORKDIR /opt/xombie 15 | 16 | COPY --from=builder /opt/xombie/target/release/kdc /opt/xombie/bin/kdc 17 | 18 | CMD ["./bin/kdc"] 19 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/algorithms/rc4_hmac_md5/mod.rs: -------------------------------------------------------------------------------- 1 | //! This module provides routines to encrypt/decrypt by using the RC4 2 | //! algorithm with HMAC-MD5 required by RC4_HMAC 3 | //! 4 | 5 | mod encrypt; 6 | pub use encrypt::{decrypt, encrypt}; 7 | 8 | 9 | mod key; 10 | pub use key::{generate_key, generate_key_from_string}; 11 | 12 | mod preamble; 13 | pub use preamble::generate_preamble; 14 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/pa_pac_options.rs: -------------------------------------------------------------------------------- 1 | //! Options used by the PA-PAC-OPTIONS struct 2 | //! 3 | //! # References 4 | //! * MS-KILE, Section 2.2.10. 5 | //! * MS-SFU, Section 2.2.5. 6 | 7 | pub const CLAIMS: u32 = 0x80000000; 8 | pub const BRANCH_AWARE: u32 = 0x40000000; 9 | pub const FORWARD_TO_FULL_DC: u32 = 0x20000000; 10 | pub const RESOURCE_BASED_CONSTRAINED_DELEGATION: u32 = 0x10000000; 11 | -------------------------------------------------------------------------------- /tools/mem-card-tool/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mem-card-tool" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | block-device = { path = "../../libs/block-device" } 8 | clap = { version = "3.1.6", features = ["derive"] } 9 | hex = "0.4" 10 | rusb = "0.9.0" 11 | xblive = { path = "../../libs/xblive" } 12 | xbox-sys = { path = "../../libs/xbox-sys" } 13 | xombie = { path = "../../libs/xombie" } 14 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /libs/xblive/src/crypto/keys.rs: -------------------------------------------------------------------------------- 1 | use hex_literal::hex; 2 | 3 | use xbox_sys::crypto::SymmetricKey; 4 | 5 | pub const HDD_MORPH_KEY: SymmetricKey = 6 | SymmetricKey(hex!["60 59 E8 2E DF BF 7F D3 23 35 74 2a 64 8B B1 2c"]); 7 | 8 | pub const SIGNATURE_KEY: &[u8] = "signaturekey\0".as_bytes(); 9 | 10 | pub const DEVKIT_MACHINE_KEY: SymmetricKey = 11 | SymmetricKey(hex!["B2 74 D2 92 FE 16 A0 17 58 70 DB 61 7B 02 D0 AD"]); 12 | -------------------------------------------------------------------------------- /services/faux-dns/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.55 as builder 2 | 3 | RUN mkdir -p /opt/xombie 4 | COPY . /opt/xombie 5 | 6 | WORKDIR /opt/xombie/services/faux-dns 7 | RUN cargo build --release 8 | 9 | FROM debian:buster-slim 10 | 11 | EXPOSE 5300/udp 12 | 13 | RUN mkdir -p /opt/xombie/bin 14 | WORKDIR /opt/xombie 15 | 16 | COPY --from=builder /opt/xombie/target/release/faux-dns /opt/xombie/bin/faux-dns 17 | 18 | CMD ["./bin/faux-dns"] 19 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/kerb_error_data_type.rs: -------------------------------------------------------------------------------- 1 | //! Values used in KerbErrorData data_type field. 2 | //! 3 | //! # References 4 | //! * MS-KILE, Section 2.2.2. 5 | 6 | /// Clock skew recovery was attempted. 7 | pub const KERB_AP_ERR_TYPE_SKEW_RECOVERY: i32 = 2; 8 | 9 | /// The Data-value field contains extended, implementation-specific 10 | /// error information. 11 | pub const KERB_ERR_TYPE_EXTENDED: i32 = 3; 12 | -------------------------------------------------------------------------------- /frontend/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/microseconds.rs: -------------------------------------------------------------------------------- 1 | 2 | /// (*Microseconds*) Kerberos Microseconds. 3 | /// Defined in RFC4120, section 5.2.4. 4 | /// ```asn1 5 | /// Microseconds ::= INTEGER (0..999999) 6 | /// -- microseconds 7 | /// ``` 8 | /// The value must be between 0 and 999999. 9 | pub type Microseconds = i32; 10 | 11 | pub const MAX_MICROSECONDS: i32 = 999999; 12 | pub const MIN_MICROSECONDS: i32 = 0; 13 | -------------------------------------------------------------------------------- /frontend/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/kerb_key_list_rep.rs: -------------------------------------------------------------------------------- 1 | use crate::EncryptionKey; 2 | use red_asn1::SequenceOf; 3 | 4 | /// (*KERB-KEY-LIST-REP*) Contains a list of key types the KDC has 5 | /// supplied to the client to support single sign-on capabilities in 6 | /// legacy protocols. Defined in MS-KILE, section 2.2.12. 7 | /// ```asn1 8 | /// KERB-KEY-LIST-REP ::= SEQUENCE OF EncryptionKey 9 | /// ``` 10 | pub type KerbKeyListRep = SequenceOf; 11 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/checksum_types.rs: -------------------------------------------------------------------------------- 1 | //! Checksum types defined in RFC-4757 2 | 3 | pub const RSA_MD5_DES: i32 = 8; 4 | pub const RSA_MD4_DES: i32 = 4; 5 | pub const HMAC_MD5: i32 = -138; 6 | pub const HMAC_SHA1_DES3_KD: i32 = 12; 7 | pub const HMAC_SHA1_96_AES128: i32 = 15; 8 | pub const HMAC_SHA1_96_AES256: i32 = 16; 9 | 10 | // RFC 8009 11 | pub const HMAC_SHA256_128_AES128: i32 = 19; 12 | pub const HMAC_SHA384_192_AES256: i32 = 20; 13 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/kerb_key_list_req.rs: -------------------------------------------------------------------------------- 1 | use crate::Int32; 2 | use red_asn1::SequenceOf; 3 | 4 | /// (*KERB-KEY-LIST-REQ*) Used to request a list of key types the KDC 5 | /// can supply to the client to support single sign-on capabilities in 6 | /// legacy protocols. Defined in MS-KILE, section 2.2.11. 7 | /// ```asn1 8 | /// KERB-KEY-LIST-REQ ::= SEQUENCE OF Int32 --encryption type -- 9 | /// ``` 10 | pub type KerbKeyListReq = SequenceOf; 11 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/address_types.rs: -------------------------------------------------------------------------------- 1 | //! Types of addresses used by Kerberos protocol. 2 | //! 3 | //! # References 4 | //! * RFC 4120, Section 7.5.3. 5 | 6 | pub const IPV4: i32 = 2; 7 | pub const DIRECTIONAL: i32 = 3; 8 | pub const CHAOSNET: i32 = 5; 9 | pub const XNS: i32 = 6; 10 | pub const ISO: i32 = 7; 11 | pub const DECNET_PHASE_IV: i32 = 12; 12 | pub const APPLETALK_DDP: i32 = 16; 13 | pub const NETBIOS: i32 = 20; 14 | pub const IPV6: i32 = 24; 15 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_keytab/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kerberos_keytab" 3 | description = "Library to parse keytab kerberos files" 4 | version = "0.0.2" 5 | authors = ["Eloy Pérez "] 6 | edition = "2018" 7 | license = "AGPL-3.0" 8 | repository = "https://gitlab.com/Zer1t0/kerbeiros/kerberos_keytab" 9 | 10 | 11 | [dependencies] 12 | nom = "6.0" 13 | 14 | [dev-dependencies] 15 | kerberos_constants = { version = "0.0", path = "../kerberos_constants"} -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/credentials/mod.rs: -------------------------------------------------------------------------------- 1 | //! Classes that represents the Kerberos credentials 2 | //! 3 | //! Each credential if composed by a ticket and information related to the Kerberos session, such as client name, realm name or session key. 4 | //! 5 | 6 | mod file; 7 | 8 | mod credential; 9 | pub use credential::*; 10 | 11 | mod credential_warehouse; 12 | pub use credential_warehouse::*; 13 | 14 | mod mappers; 15 | pub(crate) use mappers::CredentialKrbInfoMapper; 16 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/kerb_local.rs: -------------------------------------------------------------------------------- 1 | use red_asn1::OctetString; 2 | 3 | /// (*KERB-LOCAL*) contain implementation-specific data used 4 | /// when the Kerberos client and application server are on the same host. 5 | /// Defined in MS-KILE, 2.2.4. 6 | /// ```asn1 7 | /// KERB-LOCAL ::= OCTET STRING --Implementation-specific data which MUST be 8 | /// --ignored if Kerberos client is not local. 9 | /// ``` 10 | pub type KerbLocal = OctetString; 11 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/mappers/mod.rs: -------------------------------------------------------------------------------- 1 | mod key_block_mapper; 2 | pub use key_block_mapper::*; 3 | 4 | mod principal_mapper; 5 | pub use principal_mapper::*; 6 | 7 | mod times_mapper; 8 | pub use times_mapper::*; 9 | 10 | mod ticket_flags_mapper; 11 | pub use ticket_flags_mapper::*; 12 | 13 | mod address_mapper; 14 | pub use address_mapper::*; 15 | 16 | mod auth_data_mapper; 17 | pub use auth_data_mapper::*; 18 | 19 | mod octet_string_mapper; 20 | pub use octet_string_mapper::*; 21 | -------------------------------------------------------------------------------- /tools/get-machine-account/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "get-machine-account" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | chrono = "0.4.19" 8 | clap = "~2.33" 9 | kerberos_asn1 = { path = "../../third_party/kerbeiros/kerberos_asn1" } 10 | kerberos_constants = { path = "../../third_party/kerbeiros/kerberos_constants" } 11 | red_asn1 = { path = "../../third_party/red_asn1/red_asn1" } 12 | tokio = { version = "1.12.0", features = ["full"] } 13 | xblive = { path = "../../libs/xblive" } 14 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/algorithms/aes_hmac_sha1/mod.rs: -------------------------------------------------------------------------------- 1 | //! This module provides routines to encrypt/decrypt by using the AES 2 | //! algorithm with HMAC-SHA1 required by AES128_CTS_HMAC_SHA1_96 and 3 | //! AES256_CTS_HMAC_SHA1_96. 4 | 5 | mod keys; 6 | pub use keys::{ 7 | generate_key, generate_key_from_string 8 | }; 9 | 10 | mod decrypt; 11 | pub use decrypt::{decrypt, encrypt}; 12 | 13 | mod preamble; 14 | pub use preamble::generate_preamble; 15 | 16 | mod salt; 17 | pub use salt::generate_salt; 18 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/message_types.rs: -------------------------------------------------------------------------------- 1 | //! Codes of the kerberos messages 2 | 3 | pub const KRB_AS_REQ: i32 = 10; 4 | pub const KRB_AS_REP: i32 = 11; 5 | pub const KRB_TGS_REQ: i32 = 12; 6 | pub const KRB_TGS_REP: i32 = 13; 7 | pub const KRB_AP_REQ: i32 = 14; 8 | pub const KRB_AP_REP: i32 = 15; 9 | pub const KRB_RESERVED16: i32 = 16; 10 | pub const KRB_RESERVED17: i32 = 17; 11 | pub const KRB_SAFE: i32 = 20; 12 | pub const KRB_PRIV: i32 = 21; 13 | pub const KRB_CRED: i32 = 22; 14 | pub const KRB_ERROR: i32 = 30; 15 | 16 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kerberos_crypto" 3 | description = "Cryptography algorithms for Kerberos" 4 | version = "0.3.6" 5 | authors = ["Eloy Perez "] 6 | edition = "2018" 7 | license = "AGPL-3.0" 8 | repository = "https://gitlab.com/Zer1t0/kerbeiros" 9 | 10 | 11 | [dependencies] 12 | kerberos_constants = { version = "0.0", path = "../kerberos_constants"} 13 | 14 | chrono = "0.4" 15 | rand = "0.6.5" 16 | md4 = "0.8" 17 | rust-crypto = "0.2" 18 | num = "0.2" 19 | failure = "0.1" 20 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/etypes.rs: -------------------------------------------------------------------------------- 1 | //! Encryption types used by Kerberos protocol. 2 | 3 | pub const NO_ENCRYPTION: i32 = 0; 4 | pub const DES_CBC_CRC: i32 = 1; 5 | pub const DES_CBC_MD5: i32 = 3; 6 | pub const AES256_CTS_HMAC_SHA1_96: i32 = 18; 7 | pub const AES128_CTS_HMAC_SHA1_96: i32 = 17; 8 | pub const RC4_HMAC: i32 = 23; 9 | pub const RC4_HMAC_EXP: i32 = 24; 10 | pub const RC4_HMAC_OLD_EXP: i32 = -135; 11 | 12 | // RFC 8009 13 | pub const AES128_CTS_HMAC_SHA256_128: i32 = 19; 14 | pub const AES256_CTS_HMAC_SHA284_192: i32 = 20; 15 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "red_asn1" 3 | description = "A little library to encode/decode ASN1 DER" 4 | version = "0.3.5" 5 | authors = ["Eloy Pérez "] 6 | edition = "2018" 7 | license = "AGPL-3.0" 8 | repository = "https://gitlab.com/Zer1t0/red_asn1" 9 | documentation = "https://docs.rs/red_asn1/" 10 | readme = "README.md" 11 | 12 | [dependencies] 13 | ascii = "1" 14 | chrono = "0.4" 15 | nom = "5" 16 | 17 | [dev-dependencies] 18 | red_asn1_derive = { path = "../red_asn1_derive", version = "0.2" } 19 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kerberos_asn1" 3 | description = "Parse/Build Kerberos ASN1 DER To/From Rust structs" 4 | version = "0.2.1" 5 | authors = ["Eloy "] 6 | edition = "2018" 7 | license = "AGPL-3.0" 8 | repository = "https://gitlab.com/Zer1t0/kerbeiros" 9 | 10 | [dependencies] 11 | kerberos_constants = { version = "0.0", path = "../kerberos_constants"} 12 | 13 | red_asn1 = { path = "../../red_asn1/red_asn1" } 14 | red_asn1_derive = { path = "../../red_asn1/red_asn1_derive"} 15 | chrono = "0.4" 16 | 17 | -------------------------------------------------------------------------------- /healthchecks/postgres.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eo pipefail 3 | 4 | host="$(hostname -i || echo '127.0.0.1')" 5 | user="${POSTGRES_USER:-postgres}" 6 | db="${POSTGRES_DB:-$POSTGRES_USER}" 7 | export PGPASSWORD="${POSTGRES_PASSWORD:-}" 8 | 9 | args=( 10 | # force postgres to not use the local unix socket (test "external" connectibility) 11 | --host "$host" 12 | --username "$user" 13 | --dbname "$db" 14 | --quiet --no-align --tuples-only 15 | ) 16 | 17 | if select="$(echo 'SELECT 1' | psql "${args[@]}")" && [ "$select" = '1' ]; then 18 | exit 0 19 | fi 20 | 21 | exit 1 22 | -------------------------------------------------------------------------------- /libs/xblive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xblive" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | block-modes = "0.7.0" 8 | bytes = "^1" 9 | des = "0.6.0" 10 | hex-literal = "0.3.1" 11 | kerberos_asn1 = { path = "../../third_party/kerbeiros/kerberos_asn1" } 12 | kerberos_constants = { path = "../../third_party/kerbeiros/kerberos_constants" } 13 | log = { version = "0.4.4", default-features = false } 14 | nom = "^7" 15 | num-bigint = { version = "0.3", features = ["rand"] } 16 | rand = "0.7" 17 | rust-crypto = "^0.2" 18 | xbox-sys = { path = "../xbox-sys" } 19 | -------------------------------------------------------------------------------- /frontend/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | 14 | // If you want to start measuring performance in your app, pass a function 15 | // to log results (for example: reportWebVitals(console.log)) 16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 17 | reportWebVitals(); 18 | -------------------------------------------------------------------------------- /libs/xblive/src/arith.rs: -------------------------------------------------------------------------------- 1 | #[allow(dead_code)] 2 | pub const fn roundup(unrounded: usize, to: usize) -> usize { 3 | let rem = unrounded % to; 4 | if rem == 0 { 5 | unrounded 6 | } else { 7 | unrounded - rem + to 8 | } 9 | } 10 | 11 | #[cfg(test)] 12 | mod tests { 13 | use super::*; 14 | 15 | #[test] 16 | fn test_roundup() { 17 | assert_eq!(0x000, roundup(0, 0x100)); 18 | assert_eq!(0x100, roundup(1, 0x100)); 19 | assert_eq!(0x100, roundup(0x100, 0x100)); 20 | assert_eq!(0x200, roundup(0x101, 0x100)); 21 | } 22 | } -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | members = [ 4 | "libs/block-device", 5 | "libs/smoltcp-tun-tap", 6 | "libs/smoltcp-user-vpn", 7 | "libs/xblive", 8 | "libs/xbox-sys", 9 | "libs/xdvd", 10 | "libs/xombie", 11 | "libs/xombie-matchmaking", 12 | "services/api", 13 | "services/faux-dns", 14 | "services/kdc", 15 | "services/sg", 16 | "tools/config-area-tool", 17 | "tools/dvd-tool", 18 | "tools/get-machine-account", 19 | "tools/mem-card-tool", 20 | "tools/mount-memory-card", 21 | "tools/xbeeprom", 22 | "tools/xbltun", 23 | ] 24 | -------------------------------------------------------------------------------- /libs/xblive/src/time.rs: -------------------------------------------------------------------------------- 1 | use bytes::BufMut; 2 | 3 | use nom::number::complete::le_u64; 4 | 5 | use xbox_sys::codec::{BufPut, Decode}; 6 | 7 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] 8 | #[repr(C)] 9 | pub struct TimeStamp(pub u64); 10 | 11 | impl BufPut for TimeStamp { 12 | fn put(&self, buf: &mut AnyBufMut) { 13 | buf.put_u64_le(self.0) 14 | } 15 | } 16 | 17 | impl Decode for TimeStamp { 18 | fn decode<'a>(input: &'a [u8]) -> nom::IResult<&'a [u8], Self> { 19 | let (input, val) = le_u64(input)?; 20 | Ok((input, TimeStamp(val))) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /services/api/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::process::exit; 2 | 3 | use tokio::signal::unix::{signal, SignalKind}; 4 | 5 | use warp::Filter; 6 | 7 | #[tokio::main] 8 | async fn main() { 9 | let routes = warp::any().map(|| "Hello, World!"); 10 | 11 | let mut sigterm_stream = signal(SignalKind::terminate()).unwrap(); 12 | 13 | tokio::select! { 14 | _ = warp::serve(routes).run(([0, 0, 0, 0], 80)) => { 15 | eprintln!("warp main loop quit") 16 | } 17 | _ = sigterm_stream.recv() => { 18 | println!("Received SIGTERM"); 19 | exit(0) 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # Kerberos constants 2 | //! This library defines the numeric constants used across the Kerberos protocol by different objects and actors. 3 | 4 | pub mod ad_types; 5 | pub mod address_types; 6 | pub mod ap_options; 7 | pub mod checksum_types; 8 | pub mod error_codes; 9 | pub mod etypes; 10 | pub mod kdc_options; 11 | pub mod kerb_error_data_type; 12 | pub mod key_usages; 13 | pub mod message_types; 14 | pub mod pa_data_types; 15 | pub mod pa_pac_options; 16 | pub mod principal_names; 17 | pub mod protocol_version; 18 | pub mod ticket_flags; 19 | pub mod tr_types; 20 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/cryptography/mod.rs: -------------------------------------------------------------------------------- 1 | //! Module to provide low-level cryptographic routines 2 | 3 | mod aes; 4 | pub use aes::{ 5 | decrypt_aes_ecb, encrypt_aes_cbc, pbkdf2_sha1, AesSizes, AES128_KEY_SIZE, 6 | AES128_SEED_SIZE, AES256_KEY_SIZE, AES256_SEED_SIZE, AES_BLOCK_SIZE, 7 | AES_MAC_SIZE, 8 | }; 9 | 10 | mod hmac; 11 | pub use hmac::{hmac_md5, hmac_sha1}; 12 | 13 | mod rc4; 14 | pub use rc4::{rc4_decrypt, rc4_encrypt, RC4_KEY_SIZE}; 15 | 16 | mod md4lib; 17 | pub use md4lib::md4; 18 | 19 | mod md5; 20 | pub use md5::md5; 21 | 22 | mod nfold_dk; 23 | pub use nfold_dk::dk; 24 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1_derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "red_asn1_derive" 3 | description = "macros for red_asn1" 4 | version = "0.2.1" 5 | authors = ["Eloy Perez "] 6 | edition = "2018" 7 | license = "AGPL-3.0" 8 | repository = "https://gitlab.com/Zer1t0/red_asn1" 9 | documentation = "https://docs.rs/red_asn1_derive/" 10 | 11 | [lib] 12 | proc-macro = true 13 | 14 | [dependencies] 15 | syn = "0.15" 16 | quote = "0.6" 17 | failure = "0.1.5" 18 | failure_derive = "0.1.5" 19 | proc-macro2 = "0.4" 20 | 21 | [dev-dependencies] 22 | red_asn1 = { version = "0.3", path = "../red_asn1" } 23 | -------------------------------------------------------------------------------- /frontend/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /frontend/src/App.js: -------------------------------------------------------------------------------- 1 | import logo from './logo.svg'; 2 | import './App.css'; 3 | 4 | function App() { 5 | return ( 6 |
7 |
8 | logo 9 |

10 | Edit src/App.js and save to reload. 11 |

12 | 18 | Learn React 19 | 20 |
21 |
22 | ); 23 | } 24 | 25 | export default App; 26 | -------------------------------------------------------------------------------- /services/sg/src/secrets.rs: -------------------------------------------------------------------------------- 1 | use hex_literal::hex; 2 | use xblive::crypto::primitives::DiffieHellmanModulus; 3 | 4 | const FIXED_SG_NONCE: [u8;8] = hex!["1d 87 44 40 8c 89 b1 13"]; 5 | 6 | const FIXED_DH_X: DiffieHellmanModulus = DiffieHellmanModulus(hex![" 7 | 8bd371a22b8a5d5abe5ab715c481e456e3b655283fa40a3f 8 | 8f9f970ced89d0b12dd8abb515fc14684d8dbc5d8c727de6 9 | 3e178bb232c2f4192a0061aedbb0b7f8a6c88e344a431b1c 10 | 4a78a19a501625046cbafa8c48662273db29c77402fa8ab3"]); 11 | 12 | pub fn generate_sg_nonce() -> [u8;8] { 13 | FIXED_SG_NONCE 14 | } 15 | 16 | pub fn generate_dh_x() -> DiffieHellmanModulus { 17 | FIXED_DH_X 18 | } 19 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/checksum.rs: -------------------------------------------------------------------------------- 1 | use crate::Int32; 2 | use red_asn1::{Asn1Object, OctetString}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*Checksum*) Checksum of the related message. 6 | /// Defined in RFC4120, section 5.2.9. 7 | ///```asn1 8 | /// Checksum ::= SEQUENCE { 9 | /// cksumtype [0] Int32, 10 | /// checksum [1] OCTET STRING 11 | /// } 12 | ///``` 13 | #[derive(Sequence, Default, Clone, Debug, PartialEq)] 14 | pub struct Checksum { 15 | #[seq_field(context_tag = 0)] 16 | pub cksumtype: Int32, 17 | #[seq_field(context_tag = 1)] 18 | pub checksum: OctetString, 19 | } 20 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1_derive/src/parse_error.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | pub type ParseResult = Result; 4 | 5 | 6 | #[derive(Clone, Debug)] 7 | pub enum ParseError { 8 | 9 | /// The field has not attribute tag seq_field 10 | NotFoundAttributeTag, 11 | InvalidTagNumberValue, 12 | 13 | AttributeInvalidFormat(String), 14 | AttributeUnknown(String), 15 | /// The data type with [derive(Sequence)] it is not an struct 16 | NotStruct 17 | } 18 | 19 | impl fmt::Display for ParseError { 20 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 21 | fmt::Display::fmt(&self, f) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /services/kdc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kdc" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | chrono = "0.4.19" 8 | clap = { version = "3.2.8", features = ["derive"] } 9 | hex-literal = "0.3.1" 10 | kerberos_asn1 = { path = "../../third_party/kerbeiros/kerberos_asn1" } 11 | kerberos_constants = { path = "../../third_party/kerbeiros/kerberos_constants" } 12 | red_asn1 = { path = "../../third_party/red_asn1/red_asn1" } 13 | tokio = { version = "1.12.0", features = ["full"] } 14 | tokio-postgres = "0.7.3" 15 | xblive = { path = "../../libs/xblive" } 16 | xbox-sys = { path = "../../libs/xbox-sys" } 17 | xombie = { path = "../../libs/xombie" } 18 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/pa_s4u_x509_user.rs: -------------------------------------------------------------------------------- 1 | use crate::{Checksum, S4uUserId}; 2 | use red_asn1::Asn1Object; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*PA-S4U-X509-USER*) Used in S4U2Self, to specify the user certificate. 6 | /// Defined MS-SFU, section 2.2.2. 7 | /// ```asn1 8 | /// PA-S4U-X509-USER::= SEQUENCE { 9 | /// user-id[0] S4UUserID, 10 | /// checksum[1] Checksum 11 | /// } 12 | /// ``` 13 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 14 | pub struct PaS4uX509User { 15 | #[seq_field(context_tag = 0)] 16 | pub user_id: S4uUserId, 17 | #[seq_field(context_tag = 1)] 18 | pub checksum: Checksum, 19 | } 20 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/kerb_error_data.rs: -------------------------------------------------------------------------------- 1 | use crate::Int32; 2 | use red_asn1::{Asn1Object, OctetString}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*KERB-ERROR-DATA*) returned in e-data field of *KRB-ERROR*. 6 | /// Defined in MS-KILE, section 2.2.2. 7 | /// ```asn1 8 | /// KERB-ERROR-DATA ::= SEQUENCE { 9 | /// data-type [1] INTEGER, 10 | /// data-value [2] OCTET STRING OPTIONAL 11 | /// } 12 | /// ``` 13 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 14 | pub struct KerbErrorData { 15 | #[seq_field(context_tag = 1)] 16 | pub data_type: Int32, 17 | #[seq_field(context_tag = 2)] 18 | pub data_value: Option, 19 | } 20 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/ad_and_or.rs: -------------------------------------------------------------------------------- 1 | use crate::{Int32, AuthorizationData}; 2 | use red_asn1::Asn1Object; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*AD-AND-OR*) Type of *AuthorizationData*. 6 | /// Defined in RFC4120, section 5.2.6.3. 7 | /// ```asn1 8 | /// AD-AND-OR ::= SEQUENCE { 9 | /// condition-count [0] Int32, 10 | /// elements [1] AuthorizationData 11 | /// } 12 | /// ``` 13 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 14 | pub struct AdAndOr { 15 | #[seq_field(context_tag = 0)] 16 | pub condition_count: Int32, 17 | #[seq_field(context_tag = 1)] 18 | pub elements: AuthorizationData, 19 | } 20 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/etype_info_entry.rs: -------------------------------------------------------------------------------- 1 | use crate::Int32; 2 | use red_asn1::{Asn1Object, OctetString}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*ETYPE-INFO-ENTRY*) Entry of *ETYPE-INFO*. 6 | /// Defined RFC4120, section 5.2.7.4. 7 | /// ```asn1 8 | /// ETYPE-INFO-ENTRY ::= SEQUENCE { 9 | /// etype [0] Int32, 10 | /// salt [1] OCTET STRING OPTIONAL 11 | /// } 12 | /// ``` 13 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 14 | pub struct EtypeInfoEntry { 15 | #[seq_field(context_tag = 0)] 16 | pub etype: Int32, 17 | #[seq_field(context_tag = 1)] 18 | pub salt: Option, 19 | } 20 | -------------------------------------------------------------------------------- /libs/xombie/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "xombie" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | chrono = "0.4.19" 8 | eui48 = "1.0.1" 9 | hex-literal = "0.3.1" 10 | kerberos_asn1 = { path = "../../third_party/kerbeiros/kerberos_asn1" } 11 | kerberos_constants = { path = "../../third_party/kerbeiros/kerberos_constants" } 12 | red_asn1 = { path = "../../third_party/red_asn1/red_asn1" } 13 | regex = "^1.0" 14 | serde = { version = "1.0", features = ["derive"] } 15 | tokio = { version = "1.12.0", features = ["full"] } 16 | tokio-postgres = { version = "0.7.3", features = ["with-eui48-1"] } 17 | toml = "^0.5" 18 | xblive = { path = "../xblive" } 19 | xbox-sys = { path = "../xbox-sys" } 20 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_ccache/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kerberos_ccache" 3 | description = "Library to parse ccache kerberos structures" 4 | version = "0.0.7" 5 | authors = ["Eloy Perez "] 6 | edition = "2018" 7 | license = "AGPL-3.0" 8 | repository = "https://gitlab.com/Zer1t0/kerbeiros/kerberos_ccache" 9 | 10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 11 | 12 | [dependencies] 13 | kerberos_constants = { version = "0.0", path = "../kerberos_constants"} 14 | kerberos_asn1 = { version = "0.2", path = "../kerberos_asn1"} 15 | 16 | failure = "0.1" 17 | failure_derive = "0.1" 18 | 19 | nom = "5" 20 | chrono = "0.4" 21 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/ad_types.rs: -------------------------------------------------------------------------------- 1 | //! Types of *AuthorizationData*. Specify in the ad-type field. 2 | //! RFC4120, Section 7.5.4. 3 | 4 | pub const AD_IF_RELEVANT: i32 = 1; 5 | pub const AD_INTENDED_FOR_SERVER: i32 = 2; 6 | pub const AD_INTENDED_FOR_APPLICATION_CLASS: i32 = 3; 7 | pub const AD_KDCISSUED: i32 = 4; 8 | pub const AD_AND_OR: i32 = 5; 9 | pub const AD_MANDATORY_TICKET_EXTENSIONS: i32 = 6; 10 | pub const AD_IN_TICKET_EXTENSIONS: i32 = 7; 11 | pub const AD_MANDATORY_FOR_KDC: i32 = 8; 12 | pub const OSF_DCE: i32 = 64; 13 | pub const SESAME: i32 = 65; 14 | pub const AD_OSF_DCE_PKI_CERTID: i32 = 66; 15 | pub const AD_WIN2K_PACK: i32 = 128; 16 | pub const AD_ETYPE_NEGOTIATION: i32 = 129; 17 | 18 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/kerb_ad_restriction_entry.rs: -------------------------------------------------------------------------------- 1 | use crate::Int32; 2 | use red_asn1::{Asn1Object, OctetString}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*KERB-AD-RESTRICTION-ENTRY*) Specify additional restrictions 6 | /// for the client. Defined in MS-KILE, section 2.2.6. 7 | /// ```asn1 8 | /// KERB-AD-RESTRICTION-ENTRY ::= SEQUENCE { 9 | /// restriction-type [0] Int32, 10 | /// restriction [1] OCTET STRING 11 | /// } 12 | /// ``` 13 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 14 | pub struct KerbAdRestrictionEntry { 15 | #[seq_field(context_tag = 0)] 16 | pub restriction_type: Int32, 17 | #[seq_field(context_tag = 1)] 18 | pub restriction: OctetString, 19 | } 20 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust:1.62-slim-buster as builder 2 | 3 | RUN mkdir -p /opt/xombie-build 4 | COPY . /opt/xombie-build 5 | 6 | WORKDIR /opt/xombie-build 7 | 8 | RUN cargo build --release 9 | 10 | FROM debian:buster-slim 11 | 12 | # api 13 | EXPOSE 80 14 | # kdc 15 | EXPOSE 88/udp 16 | # faux_dns 17 | EXPOSE 5300/udp 18 | # sg 19 | EXPOSE 3074/udp 20 | 21 | RUN mkdir -p /opt/xombie/bin 22 | WORKDIR /opt/xombie 23 | 24 | COPY --from=builder /opt/xombie-build/target/release/api /opt/xombie/bin/api 25 | COPY --from=builder /opt/xombie-build/target/release/kdc /opt/xombie/bin/kdc 26 | COPY --from=builder /opt/xombie-build/target/release/faux-dns /opt/xombie/bin/faux-dns 27 | COPY --from=builder /opt/xombie-build/target/release/sg /opt/xombie/bin/sg 28 | -------------------------------------------------------------------------------- /frontend/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "kerbeiros" 3 | description = "Kerberos client library" 4 | version = "0.2.2" 5 | authors = ["Eloy Perez "] 6 | edition = "2018" 7 | license = "AGPL-3.0" 8 | repository = "https://gitlab.com/Zer1t0/kerbeiros" 9 | 10 | 11 | [dependencies] 12 | kerberos_asn1 = { version = "0.2", path = "../kerberos_asn1"} 13 | kerberos_ccache = { version = "0.0", path = "../kerberos_ccache"} 14 | kerberos_crypto = { version = "0.3", path = "../kerberos_crypto"} 15 | kerberos_constants = { version = "0.0", path = "../kerberos_constants"} 16 | 17 | ascii = "0.9.1" 18 | chrono = "0.4" 19 | failure = "0.1.5" 20 | failure_derive = "0.1.5" 21 | rand = "0.6.5" 22 | dns-lookup = "1.0" 23 | getset = "0.1" 24 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/ticket_flags.rs: -------------------------------------------------------------------------------- 1 | use crate::KerberosFlags; 2 | 3 | /// (*TicketFlags*) Flags for tickets. 4 | /// ```asn1 5 | /// TicketFlags ::= KerberosFlags 6 | /// -- reserved(0), 7 | /// -- forwardable(1), 8 | /// -- forwarded(2), 9 | /// -- proxiable(3), 10 | /// -- proxy(4), 11 | /// -- may-postdate(5), 12 | /// -- postdated(6), 13 | /// -- invalid(7), 14 | /// -- renewable(8), 15 | /// -- initial(9), 16 | /// -- pre-authent(10), 17 | /// -- hw-authent(11), 18 | /// -- the following are new since 1510 19 | /// -- transited-policy-checked(12), 20 | /// -- ok-as-delegate(13) 21 | /// ``` 22 | pub type TicketFlags = KerberosFlags; 23 | 24 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_ccache/src/mappers/mod.rs: -------------------------------------------------------------------------------- 1 | mod key_block_mapper; 2 | pub use key_block_mapper::*; 3 | 4 | mod principal_mapper; 5 | pub use principal_mapper::*; 6 | 7 | mod times_mapper; 8 | pub use times_mapper::*; 9 | 10 | mod ticket_flags_mapper; 11 | pub use ticket_flags_mapper::*; 12 | 13 | mod address_mapper; 14 | pub use address_mapper::*; 15 | 16 | mod auth_data_mapper; 17 | pub use auth_data_mapper::*; 18 | 19 | mod octet_string_mapper; 20 | pub use octet_string_mapper::*; 21 | 22 | mod credential_mapper; 23 | pub use credential_mapper::{ 24 | credential_to_krb_cred_info_and_ticket, 25 | krb_cred_info_and_ticket_to_credential, 26 | }; 27 | 28 | mod ccache_mapper; 29 | pub use ccache_mapper::{ccache_to_krb_cred, krb_cred_to_ccache}; 30 | 31 | -------------------------------------------------------------------------------- /libs/xbox-sys/src/crypto/keys.rs: -------------------------------------------------------------------------------- 1 | use hex_literal::hex; 2 | 3 | use super::{SymmetricKey, DesIv}; 4 | 5 | pub const V_1_0_EEPROM_KEY: SymmetricKey = 6 | SymmetricKey(hex!["2a3bad2cb1944f93aacdcd7e0ac2ee5a"]); 7 | 8 | pub const MU_USER_ACCOUNT_IV: DesIv = 9 | DesIv(hex!["7b35a8b727ed437a"]); 10 | 11 | pub const MU_USER_ACCOUNT_DES_SEED: SymmetricKey = 12 | SymmetricKey(hex!["a714213d94461e05976de835212ae57c"]); 13 | 14 | pub const MU_USER_ACCOUNT_SIGNATURE_KEY: SymmetricKey = 15 | SymmetricKey(hex!["62bd92b64f458470d3ff4f223c6ee7ea"]); 16 | 17 | pub const USER_ACCOUNT_DES_SEED_KEY_0: SymmetricKey = 18 | SymmetricKey(hex!["2bb8d9efd2046d9d1f39b15b465801d7"]); 19 | 20 | pub const USER_ACCOUNT_DES_SEED_KEY_1: SymmetricKey = 21 | SymmetricKey(hex!["1e05d73aa4206a7ba05bcddfad26d3de"]); 22 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/transited_encoding.rs: -------------------------------------------------------------------------------- 1 | use crate::{Int32}; 2 | use red_asn1::{OctetString, Asn1Object}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*TransitedEncoding*) Lists the names of the Kerberos realms that took part in the client authentication. 6 | /// Defined in RFC4120, section 5.3. 7 | /// ```asn1 8 | /// -- encoded Transited field 9 | /// TransitedEncoding ::= SEQUENCE { 10 | /// tr-type [0] Int32 -- must be registered --, 11 | /// contents [1] OCTET STRING 12 | /// } 13 | /// ``` 14 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 15 | pub struct TransitedEncoding { 16 | #[seq_field(context_tag = 0)] 17 | pub tr_type: Int32, 18 | #[seq_field(context_tag = 1)] 19 | pub contents: OctetString, 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_ccache/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Types used to store Kerberos credentials in a ccache 4 | 5 | # Example 6 | Load and save into a file: 7 | ```no_run 8 | use kerberos_ccache::CCache; 9 | use std::fs; 10 | 11 | let data = fs::read("./bob_tgt.ccache").expect("Unable to read file"); 12 | 13 | let ccache = CCache::parse(&data) 14 | .expect("Unable to parse file content") 15 | .1; 16 | 17 | let data_2 = ccache.build(); 18 | fs::write("./bob_tgt2.ccache", data_2).expect("Unable to write file"); 19 | ``` 20 | # References 21 | * [ccache definition](https://web.mit.edu/kerberos/krb5-1.12/doc/basic/ccache_def.html) 22 | * [ccache types definition](https://repo.or.cz/w/krb5dissect.git/blob_plain/HEAD:/ccache.txt) 23 | 24 | 25 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1/src/types/integer/int_trait.rs: -------------------------------------------------------------------------------- 1 | use crate::INTEGER_TAG_NUMBER; 2 | use crate::Tag; 3 | use crate::Asn1Object; 4 | use crate::error as asn1err; 5 | 6 | /// A trait to identify types that are ASN.1 integers 7 | pub trait Asn1Int: Sized + Default { 8 | fn build_int_value(&self) -> Vec; 9 | fn parse_int_value(raw: &[u8]) -> asn1err::Result; 10 | } 11 | 12 | 13 | impl Asn1Object for T { 14 | fn tag() -> Tag { 15 | return Tag::new_primitive_universal(INTEGER_TAG_NUMBER); 16 | } 17 | 18 | fn build_value(&self) -> Vec { 19 | return self.build_int_value(); 20 | } 21 | 22 | fn parse_value(&mut self, raw: &[u8]) -> asn1err::Result<()> { 23 | *self = Self::parse_int_value(raw)?; 24 | return Ok(()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1/src/tag/tagtype.rs: -------------------------------------------------------------------------------- 1 | use std::convert::From; 2 | 3 | /// Enum with the different tag types 4 | /// * Primitive: Object which are not composed by other objects. For example, basic types like Integer, Boolean, ... 5 | /// * Constructed: Object composed by other objects, such as Sequences. 6 | /// 7 | #[derive(Debug, PartialEq, Copy, Clone)] 8 | pub enum TagType { 9 | Primitive = 0b0, 10 | Constructed = 0b1 11 | } 12 | 13 | impl From for TagType { 14 | fn from(u: u8) -> TagType { 15 | match u & 0x01 { 16 | 0 => TagType::Primitive, 17 | 1 => TagType::Constructed, 18 | _ => unreachable!() 19 | } 20 | } 21 | } 22 | 23 | 24 | impl Default for TagType { 25 | fn default() -> Self { 26 | return Self::Primitive; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/utils.rs: -------------------------------------------------------------------------------- 1 | //! Implement functions that can be useful to support the main library functionality. 2 | 3 | use crate::{Result, Error}; 4 | use ascii::AsciiString; 5 | use dns_lookup; 6 | use std::net::IpAddr; 7 | 8 | /// Resolve the address of the KDC from the name of the realm. 9 | /// 10 | /// # Errors 11 | /// Returns [`Error`](../error/struct.Error.html) if it is not possible to resolve the domain name or the resolution does not include any IP address. 12 | pub fn resolve_realm_kdc(realm: &AsciiString) -> Result { 13 | let ips = dns_lookup::lookup_host(&realm.to_string()) 14 | .map_err(|_| Error::NameResolutionError(realm.to_string()))?; 15 | 16 | if ips.len() == 0 { 17 | return Err(Error::NameResolutionError(realm.to_string()))?; 18 | } 19 | 20 | return Ok(ips[0]); 21 | } 22 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/ap_rep.rs: -------------------------------------------------------------------------------- 1 | use crate::{Int32, EncryptedData}; 2 | use red_asn1::Asn1Object; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*AP-REP*) Response to *AP-REQ*, sent when mutual authentication is selected. 6 | /// Defined in RFC4120, section 5.5.2. 7 | /// ```asn1 8 | /// AP-REP ::= [APPLICATION 15] SEQUENCE { 9 | /// pvno [0] INTEGER (5), 10 | /// msg-type [1] INTEGER (15), 11 | /// enc-part [2] EncryptedData -- EncAPRepPart 12 | /// } 13 | /// ``` 14 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 15 | #[seq(application_tag = 15)] 16 | pub struct ApRep { 17 | #[seq_field(context_tag = 0)] 18 | pub pvno: Int32, 19 | #[seq_field(context_tag = 1)] 20 | pub msg_type: Int32, 21 | #[seq_field(context_tag = 2)] 22 | pub enc_part: EncryptedData, 23 | } 24 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/authorization_data.rs: -------------------------------------------------------------------------------- 1 | use crate::Int32; 2 | use red_asn1::{OctetString, Asn1Object}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*AuthorizationData*) Defined in RFC4120, section 5.2.6. 6 | /// ```asn1 7 | /// -- NOTE: AuthorizationData is always used as an OPTIONAL field and 8 | /// -- should not be empty. 9 | /// AuthorizationData ::= SEQUENCE OF SEQUENCE { 10 | /// ad-type [0] Int32, 11 | /// ad-data [1] OCTET STRING 12 | /// } 13 | /// ``` 14 | pub type AuthorizationData = Vec; 15 | 16 | /// Entry of the AuthorizationData 17 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 18 | pub struct AuthorizationDataEntry { 19 | #[seq_field(context_tag = 0)] 20 | pub ad_type: Int32, 21 | #[seq_field(context_tag = 1)] 22 | pub ad_data: OctetString 23 | } 24 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/kdc_options.rs: -------------------------------------------------------------------------------- 1 | //! Options used by the message [`AsReq`](../../messages/struct.AsReq.html). 2 | 3 | pub const NO_OPTION: u32 = 0x00000000; 4 | pub const FORWARDABLE: u32 = 0x40000000; 5 | pub const FORWARDED: u32 = 0x20000000; 6 | pub const PROXIABLE: u32 = 0x10000000; 7 | pub const PROXY: u32 = 0x08000000; 8 | pub const ALLOW_POSTDATE: u32 = 0x04000000; 9 | pub const POSTDATED: u32 = 0x02000000; 10 | pub const RENEWABLE: u32 = 0x00800000; 11 | pub const OPT_HARDWARE_AUTH: u32 = 0x00100000; 12 | pub const CONSTRAINED_DELEGATION: u32 = 0x00020000; 13 | pub const CANONICALIZE: u32 = 0x00010000; 14 | pub const REQUEST_ANONYMOUS: u32 = 0x8000; 15 | pub const DISABLE_TRANSITED_CHECK: u32 = 0x20; 16 | pub const RENEWABLE_OK: u32 = 0x10; 17 | pub const ENC_TKT_IN_SKEY: u32 = 0x08; 18 | pub const RENEW: u32 = 0x02; 19 | pub const VALIDATE: u32 = 0x01; 20 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/krb_priv.rs: -------------------------------------------------------------------------------- 1 | use crate::{EncryptedData, Int32}; 2 | use red_asn1::Asn1Object; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*KRB-PRIV*) To send a message securely and privately. 6 | /// Defined RFC4120, section 5.7.1. 7 | /// ```asn1 8 | /// KRB-PRIV ::= [APPLICATION 21] SEQUENCE { 9 | /// pvno [0] INTEGER (5), 10 | /// msg-type [1] INTEGER (21), 11 | /// -- NOTE: there is no [2] tag 12 | /// enc-part [3] EncryptedData -- EncKrbPrivPart 13 | /// } 14 | /// ``` 15 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 16 | #[seq(application_tag = 21)] 17 | pub struct KrbPriv { 18 | #[seq_field(context_tag = 0)] 19 | pub pvno: Int32, 20 | #[seq_field(context_tag = 1)] 21 | pub msg_type: Int32, 22 | #[seq_field(context_tag = 3)] 23 | pub enc_part: EncryptedData, 24 | } 25 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/ticket_flags.rs: -------------------------------------------------------------------------------- 1 | //! Flags used by `Ticket` in Kerberos protocol. 2 | //! 3 | //! # References 4 | //! * RFC 4120, Section 5.3. 5 | //! * RFC 6806, Section 11 6 | 7 | pub const RESERVED: u32 = 0x80000000; 8 | pub const FORWARDABLE: u32 = 0x40000000; 9 | pub const FORWARDED: u32 = 0x20000000; 10 | pub const PROXIABLE: u32 = 0x10000000; 11 | pub const PROXY: u32 = 0x08000000; 12 | pub const MAY_POSTDATE: u32 = 0x04000000; 13 | pub const POSTDATE: u32 = 0x02000000; 14 | pub const INVALID: u32 = 0x01000000; 15 | pub const RENEWABLE: u32 = 0x00800000; 16 | pub const INITIAL: u32 = 0x00400000; 17 | pub const PRE_AUTHENT: u32 = 0x00200000; 18 | pub const HW_AUTHENT: u32 = 0x00100000; 19 | pub const TRANSITED_POLICY_CHECKED: u32 = 0x00080000; 20 | pub const OK_AS_DELEGATE: u32 = 0x00040000; 21 | 22 | pub const REQUEST_ANONYMOUS: u32 = 0x00020000; 23 | pub const NAME_CANONICALIZE: u32 = 0x00010000; 24 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/ciphers/factory.rs: -------------------------------------------------------------------------------- 1 | use crate::{Error, Result}; 2 | use crate::cryptography::AesSizes; 3 | use kerberos_constants::etypes::{ 4 | AES128_CTS_HMAC_SHA1_96, AES256_CTS_HMAC_SHA1_96, RC4_HMAC, 5 | }; 6 | use crate::{KerberosCipher, AesCipher, Rc4Cipher}; 7 | 8 | /// Creates the appropiate cipher based on the encryption type specified 9 | pub fn new_kerberos_cipher(etype: i32) -> Result> { 10 | match etype { 11 | AES256_CTS_HMAC_SHA1_96 => { 12 | return Ok(Box::new(AesCipher::new(AesSizes::Aes256))); 13 | } 14 | AES128_CTS_HMAC_SHA1_96 => { 15 | return Ok(Box::new(AesCipher::new(AesSizes::Aes128))); 16 | } 17 | RC4_HMAC => { 18 | return Ok(Box::new(Rc4Cipher::new())); 19 | } 20 | _ => { 21 | return Err(Error::UnsupportedAlgorithm(etype))?; 22 | } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/error.rs: -------------------------------------------------------------------------------- 1 | use failure::Fail; 2 | use std::result; 3 | 4 | /// Result that encapsulates the Error type of this library 5 | pub type Result = result::Result; 6 | 7 | /// Error raised by the routines of this library 8 | #[derive(Fail, Clone, Debug, PartialEq)] 9 | pub enum Error { 10 | /// Error while decrypting the data 11 | #[fail(display = "DecryptionError: {}", _0)] 12 | DecryptionError(String), 13 | 14 | /// Data is encrypted with an unsupported crypto algorithm 15 | #[fail(display = "UnsupportedAlgorithm: {}", _0)] 16 | UnsupportedAlgorithm(i32), 17 | 18 | /// Invalid key 19 | #[fail( 20 | display = "Invalid key: Only hexadecimal characters are allowed [1234567890abcdefABCDEF]" 21 | )] 22 | InvalidKeyCharset, 23 | 24 | /// Invalid key 25 | #[fail(display = "Invalid key: Length should be {}", _0)] 26 | InvalidKeyLength(usize), 27 | } 28 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/pa_for_user.rs: -------------------------------------------------------------------------------- 1 | use red_asn1::Asn1Object; 2 | use red_asn1_derive::Sequence; 3 | use crate::{PrincipalName, Realm, Checksum, KerberosString}; 4 | 5 | /// (*PA-FOR-USER*) Used in S4U2Self, to specify user to impersonate. 6 | /// Defined in MS-SFU, section 2.2.1. 7 | /// ```asn1 8 | /// PA-FOR-USER ::= SEQUENCE { 9 | /// -- PA TYPE 129 10 | /// userName [0] PrincipalName, 11 | /// userRealm [1] Realm, 12 | /// cksum [2] Checksum, 13 | /// auth-package [3] KerberosString 14 | /// } 15 | /// ``` 16 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 17 | pub struct PaForUser { 18 | #[seq_field(context_tag = 0)] 19 | pub username: PrincipalName, 20 | #[seq_field(context_tag = 1)] 21 | pub userrealm: Realm, 22 | #[seq_field(context_tag = 2)] 23 | pub cksum: Checksum, 24 | #[seq_field(context_tag = 3)] 25 | pub auth_package: KerberosString, 26 | } 27 | 28 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/krb_safe.rs: -------------------------------------------------------------------------------- 1 | use crate::{Int32, KrbSafeBody, Checksum}; 2 | use red_asn1::Asn1Object; 3 | use red_asn1_derive::Sequence; 4 | 5 | 6 | /// (*KRB-SAFE*) Used to send a tamper-proof message to a peer. 7 | /// Defined in RFC4120, section 5.6.1. 8 | /// ```asn1 9 | /// KRB-SAFE ::= [APPLICATION 20] SEQUENCE { 10 | /// pvno [0] INTEGER (5), 11 | /// msg-type [1] INTEGER (20), 12 | /// safe-body [2] KRB-SAFE-BODY, 13 | /// cksum [3] Checksum 14 | /// } 15 | /// ``` 16 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 17 | #[seq(application_tag = 20)] 18 | pub struct KrbSafe { 19 | #[seq_field(context_tag = 0)] 20 | pub pvno: Int32, 21 | #[seq_field(context_tag = 1)] 22 | pub msg_type: Int32, 23 | #[seq_field(context_tag = 2)] 24 | pub safe_body: KrbSafeBody, 25 | #[seq_field(context_tag = 3)] 26 | pub cksum: Checksum 27 | 28 | } 29 | -------------------------------------------------------------------------------- /libs/xbox-sys/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Declaring our library as `no-std` unconditionally lets us be consistent 2 | // in how we `use` items from `std` or `core` 3 | #![no_std] 4 | 5 | // We always pull in `std` during tests, because it's just easier 6 | // to write tests when you can assume you're on a capable platform 7 | #[cfg(any(feature = "std", test))] 8 | #[allow(unused_imports)] // Justification: In case no macros are actually used 9 | #[macro_use] 10 | extern crate std; 11 | 12 | // When we're building for a no-std target, we pull in `core`, but alias 13 | // it as `std` so the `use` statements are the same between `std` and `core`. 14 | #[cfg(all(not(feature = "std"), not(test)))] 15 | #[allow(unused_imports)] // Justification: In case no macros are actually used 16 | #[macro_use] 17 | extern crate core as std; 18 | 19 | pub mod account; 20 | pub mod codec; 21 | pub mod config_area; 22 | pub mod config; 23 | pub mod crypto; 24 | pub mod eeprom; 25 | pub mod fatx; 26 | pub mod status; 27 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.14.1", 7 | "@testing-library/react": "^11.2.7", 8 | "@testing-library/user-event": "^12.8.3", 9 | "react": "^17.0.2", 10 | "react-dom": "^17.0.2", 11 | "react-scripts": "4.0.3", 12 | "web-vitals": "^1.1.2" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test", 18 | "eject": "react-scripts eject" 19 | }, 20 | "eslintConfig": { 21 | "extends": [ 22 | "react-app", 23 | "react-app/jest" 24 | ] 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/ad_kdcissued.rs: -------------------------------------------------------------------------------- 1 | use crate::{AuthorizationData, Checksum, PrincipalName, Realm}; 2 | use red_asn1::Asn1Object; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*AD-KDCIssued*) Type of *AuthorizationData*. 6 | /// Defined in RFC4120, section 5.2.6.2. 7 | /// ```asn1 8 | /// AD-KDCIssued ::= SEQUENCE { 9 | /// ad-checksum [0] Checksum, 10 | /// i-realm [1] Realm OPTIONAL, 11 | /// i-sname [2] PrincipalName OPTIONAL, 12 | /// elements [3] AuthorizationData 13 | /// } 14 | /// ``` 15 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 16 | pub struct AdKdcIssued { 17 | #[seq_field(context_tag = 0)] 18 | pub ad_checksum: Checksum, 19 | #[seq_field(context_tag = 1)] 20 | pub i_realm: Option, 21 | #[seq_field(context_tag = 2)] 22 | pub i_sname: Option, 23 | #[seq_field(context_tag = 3)] 24 | pub elements: AuthorizationData, 25 | } 26 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/kdc_options.rs: -------------------------------------------------------------------------------- 1 | use crate::KerberosFlags; 2 | 3 | /// (*KDCOptions*) Options used in Kerberos requests. 4 | /// ```asn1 5 | /// KDCOptions ::= KerberosFlags 6 | /// -- reserved(0), 7 | /// -- forwardable(1), 8 | /// -- forwarded(2), 9 | /// -- proxiable(3), 10 | /// -- proxy(4), 11 | /// -- allow-postdate(5), 12 | /// -- postdated(6), 13 | /// -- unused7(7), 14 | /// -- renewable(8), 15 | /// -- unused9(9), 16 | /// -- unused10(10), 17 | /// -- opt-hardware-auth(11), 18 | /// -- unused12(12), 19 | /// -- unused13(13), 20 | /// -- 15 is reserved for canonicalize 21 | /// -- unused15(15), 22 | /// -- 26 was unused in 1510 23 | /// -- disable-transited-check(26), 24 | /// -- 25 | /// -- renewable-ok(27), 26 | /// -- enc-tkt-in-skey(28), 27 | /// -- renew(30), 28 | /// -- validate(31) 29 | /// ``` 30 | pub type KdcOptions = KerberosFlags; 31 | 32 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/enc_ap_rep_part.rs: -------------------------------------------------------------------------------- 1 | use crate::{KerberosTime, Microseconds, EncryptionKey, UInt32}; 2 | use red_asn1::Asn1Object; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*EncAPRepPart*) Encrypted part of the message *AP-REP*. 6 | /// Defined in RFC4120, section 5.5.2. 7 | /// ```asn1 8 | /// EncAPRepPart ::= [APPLICATION 27] SEQUENCE { 9 | /// ctime [0] KerberosTime, 10 | /// cusec [1] Microseconds, 11 | /// subkey [2] EncryptionKey OPTIONAL, 12 | /// seq-number [3] UInt32 OPTIONAL 13 | /// } 14 | /// ``` 15 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 16 | #[seq(application_tag = 27)] 17 | pub struct EncApRepPart { 18 | #[seq_field(context_tag = 0)] 19 | pub ctime: KerberosTime, 20 | #[seq_field(context_tag = 1)] 21 | pub cusec: Microseconds, 22 | #[seq_field(context_tag = 2)] 23 | pub subkey: Option, 24 | #[seq_field(context_tag = 3)] 25 | pub seq_number: Option, 26 | } 27 | -------------------------------------------------------------------------------- /libs/xbox-sys/src/status.rs: -------------------------------------------------------------------------------- 1 | use bytes::BufMut; 2 | 3 | use nom::number::complete::le_u32; 4 | 5 | use crate::codec::{BufPut, Decode}; 6 | 7 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] 8 | pub struct HResult(pub u32); 9 | 10 | impl HResult { 11 | pub const SUCCESS: HResult = HResult(0x0000_0000); 12 | 13 | pub const XONLINETASK_S_SUCCESS: HResult = HResult(0x0015_00F0); 14 | pub const XONLINETASK_S_RESULTS_AVAIL: HResult = HResult(0x0015_00F1); 15 | pub const XONLINETASK_S_RUNNING_IDLE: HResult = HResult(0x0015_00F2); 16 | 17 | pub fn is_successful(&self) -> bool { 18 | self.0 & 0x8000_0000 != 0 19 | } 20 | 21 | pub fn is_failure(&self) -> bool { 22 | !self.is_successful() 23 | } 24 | } 25 | 26 | impl BufPut for HResult { 27 | fn put(&self, buf: &mut AnyBufMut) { 28 | buf.put_u32_le(self.0) 29 | } 30 | } 31 | 32 | impl Decode for HResult { 33 | fn decode<'a>(input: &'a [u8]) -> nom::IResult<&'a [u8], Self> { 34 | let (input, val) = le_u32(input)?; 35 | Ok((input, HResult(val))) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/typed_data.rs: -------------------------------------------------------------------------------- 1 | use crate::Int32; 2 | use red_asn1::{Asn1Object, OctetString, SequenceOf}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*TYPED-DATA*) For add information to errors in *KRB-ERROR*. 6 | /// Defined in RFC4120, section 5.9.1. 7 | /// ```asn1 8 | /// TYPED-DATA ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { 9 | /// data-type [0] Int32, 10 | /// data-value [1] OCTET STRING OPTIONAL 11 | /// } 12 | /// ``` 13 | pub type TypedData = SequenceOf; 14 | 15 | /// Entry of *TYPED-DATA*. Pseudotype type defined in this library for implementation. 16 | /// ```asn1 17 | /// TYPED-DATA ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { 18 | /// data-type [0] Int32, 19 | /// data-value [1] OCTET STRING OPTIONAL 20 | /// } 21 | /// ``` 22 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 23 | pub struct TypedDataEntry { 24 | #[seq_field(context_tag = 0)] 25 | pub data_type: Int32, 26 | #[seq_field(context_tag = 1)] 27 | pub data_value: Option, 28 | } 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Xombie 2 | ====== 3 | 4 | Replacement Original Xbox Live Infrastructure 5 | 6 | Notes 7 | ----- 8 | 9 | **This is a proof of concept! Some keys are chosen by fair dice rolls, 10 | databases are exposed on default ports with default credentials, etc. Run at 11 | your own risk.** 12 | 13 | Running 14 | ------- 15 | 16 | ```docker-compose up -d``` 17 | 18 | Notes: 19 | 20 | Ubuntu 20.04 runs dnsmasq by default. To disable dnsmasq first disable systemd-resolved with 21 | 22 | ```$ sudo service systemd-resolved stop``` 23 | 24 | 25 | Then edit systemd's config to remove it by adding ```DNSStubListener=no``` to ```/etc/systemd/resolved.conf```. 26 | 27 | Then keep NetworkManager from overwriting your /etc/resolv.conf by adding 28 | ```dns=none``` to the ```[main]``` section of ```/etc/NetworkManager/NetworkManager.conf```. 29 | 30 | Then remove the symlink to systemctl's ```/etc/resolv.conf``` with 31 | ```$ rm /etc/resolv.conf``` 32 | 33 | Then write your own resolv.conf containing (for instance to use google's DNS 34 | servers) 35 | 36 | ```nameserver 8.8.8.8``` 37 | -------------------------------------------------------------------------------- /frontend/Dockerfile: -------------------------------------------------------------------------------- 1 | #### Stage 1: Build the react application 2 | FROM node:16.10.0-alpine as build 3 | 4 | # Configure the main working directory inside the docker image. 5 | # This is the base directory used in any further RUN, COPY, and ENTRYPOINT 6 | # commands. 7 | WORKDIR /app 8 | 9 | # Copy the package.json as well as the package-lock.json and install 10 | # the dependencies. This is a separate step so the dependencies 11 | # will be cached unless changes to one of those two files 12 | # are made. 13 | COPY package.json package-lock.json ./ 14 | RUN npm install 15 | 16 | # Copy the main application 17 | COPY . ./ 18 | 19 | # Arguments 20 | ARG REACT_APP_API_BASE_URL 21 | ENV REACT_APP_API_BASE_URL=${REACT_APP_API_BASE_URL} 22 | 23 | # Build the application 24 | RUN npm run build 25 | 26 | #### Stage 2: Serve the React application from Nginx 27 | FROM nginx:1.21.3-alpine 28 | 29 | # Copy the react build from Stage 1 30 | COPY --from=build /app/build /frontend 31 | 32 | # Expose port 80 to the Docker host, so we can access it 33 | # from the outside. 34 | EXPOSE 80 35 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_keytab/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Types used to store Kerberos credentials in a keytab 2 | //! 3 | //! # Example 4 | //! Load and save into a file: 5 | //! ```no_run 6 | //! use kerberos_keytab::Keytab; 7 | //! use std::fs; 8 | //! 9 | //! let data = fs::read("./user.keytab").expect("Unable to read file"); 10 | //! 11 | //! let keytab = Keytab::parse(&data) 12 | //! .expect("Unable to parse file content") 13 | //! .1; 14 | //! 15 | //! let data_2 = keytab.build(); 16 | //! fs::write("./user2.keytab", data_2).expect("Unable to write file"); 17 | //! ``` 18 | //! # References 19 | //! * [keytab definition](https://web.mit.edu/kerberos/www/krb5-latest/doc/formats/keytab_file_format.html) 20 | //! * [keytab types definition](https://repo.or.cz/w/krb5dissect.git/blob_plain/HEAD:/keytab.txt) 21 | //! 22 | //! 23 | 24 | 25 | mod counted_octet_string; 26 | pub use counted_octet_string::CountedOctetString; 27 | 28 | mod key_block; 29 | pub use key_block::KeyBlock; 30 | 31 | mod keytab_entry; 32 | pub use keytab_entry::KeytabEntry; 33 | 34 | mod keytab; 35 | pub use keytab::Keytab; 36 | -------------------------------------------------------------------------------- /services/sg/src/client/service/unimplemented.rs: -------------------------------------------------------------------------------- 1 | use log::error; 2 | 3 | use std::{sync::Arc, collections::BTreeMap, convert::Infallible}; 4 | 5 | use smoltcp_user_vpn::tcp::{http::{gen_http_accept, Request, Response, ResponseHeader, StatusCode}, AcceptFn}; 6 | 7 | use crate::client::ClientState; 8 | 9 | const NOT_FOUND_STR: &'static str = "Not found"; 10 | 11 | pub fn new_unimplemented_connection(state: Arc) -> AcceptFn { 12 | gen_http_accept(state, Arc::new(move |state, req: Request| async move { 13 | log::error!("unimplemented http request {:x?}", req); 14 | not_found_handler(state, req).await 15 | })) 16 | } 17 | 18 | 19 | pub async fn not_found_handler(_ctx: Ctx, req: Request) -> Result { 20 | error!("404ing request: {:?}", req); 21 | 22 | let mut headers = BTreeMap::new(); 23 | headers.insert("Content-Length".to_owned(), format!("{}", NOT_FOUND_STR.len())); 24 | 25 | Ok(Response { 26 | header: ResponseHeader { 27 | version: req.header.version, 28 | code: StatusCode::NotFound404, 29 | headers, 30 | }, 31 | body: NOT_FOUND_STR.as_bytes().to_vec(), 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/principal_names.rs: -------------------------------------------------------------------------------- 1 | //! Types of names used by Kerberos protocol. 2 | //! 3 | //! # References 4 | //! * RFC 4210, Section 6.2. 5 | 6 | /// Name type not known 7 | pub const NT_UNKNOWN: i32 = 0; 8 | 9 | /// Just the name of the principal as in DCE, or for users 10 | pub const NT_PRINCIPAL: i32 = 1; 11 | 12 | /// Service and other unique instance (krbtgt) 13 | pub const NT_SRV_INST: i32 = 2; 14 | 15 | /// Service with host name as instance (telnet, rcommands) 16 | pub const NT_SRV_HST: i32 = 3; 17 | 18 | /// Service with host as remaining components 19 | pub const NT_SRV_XHST: i32 = 4; 20 | 21 | /// Unique ID 22 | pub const NT_UID: i32 = 5; 23 | 24 | /// Encoded X.509 Distinguished name 25 | pub const NT_X500_PRINCIPAL: i32 = 6; 26 | 27 | /// Name in form of SMTP email name (e.g., user@example.com) 28 | pub const NT_SMTP_NAME: i32 = 7; 29 | 30 | /// Enterprise name - may be mapped to principal name 31 | pub const NT_ENTERPRISE: i32 = 10; 32 | 33 | pub const NT_MS_PRINCIPAL: i32 = -128; 34 | 35 | pub const NT_MS_PRINCIPAL_AND_ID: i32 = -129; 36 | 37 | pub const NT_ENT_PRINCIPAL_AND_ID: i32 = -130; 38 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! # Kerberos crypto 2 | //! Library to implement the cryptographic algorithms involved in the kerberos protocol. 3 | //! 4 | //! The library provides different ciphers. The ciphers are classes which implements the diferent algorithms. 5 | //! All of them implement the KerberosCipher trait. 6 | //! ## Supported algorithms 7 | //! - RC4-HMAC 8 | //! - AES128-CTS-HMAC-SHA1-96 9 | //! - AES256-CTS-HMAC-SHA1-96 10 | 11 | mod algorithms; 12 | pub use algorithms::aes_hmac_sha1; 13 | pub use algorithms::rc4_hmac_md5; 14 | 15 | mod cryptography; 16 | pub use cryptography::{ 17 | AesSizes, AES128_KEY_SIZE, AES128_SEED_SIZE, AES256_KEY_SIZE, 18 | AES256_SEED_SIZE, AES_BLOCK_SIZE, AES_MAC_SIZE, RC4_KEY_SIZE 19 | }; 20 | 21 | mod utils; 22 | 23 | mod error; 24 | pub use error::{Error, Result}; 25 | 26 | mod checksum; 27 | pub use checksum::{checksum_hmac_md5, checksum_sha_aes}; 28 | 29 | mod ciphers; 30 | pub use ciphers::{new_kerberos_cipher, AesCipher, KerberosCipher, Rc4Cipher}; 31 | 32 | mod helpers; 33 | pub use helpers::{is_supported_etype, supported_etypes}; 34 | 35 | mod key; 36 | pub use key::Key; 37 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/s4userid.rs: -------------------------------------------------------------------------------- 1 | use red_asn1::{Asn1Object, OctetString, BitString}; 2 | use red_asn1_derive::Sequence; 3 | use crate::{PrincipalName, UInt32, Realm}; 4 | 5 | /// (*S4UUserID*) Used in *PA-S4U-X509-USER*, to specify the user certificate. 6 | /// Defined in MS-SFU, section 2.2.2. 7 | /// ```asn1 8 | /// S4UUserID ::= SEQUENCE { 9 | /// nonce [0] UInt32, -- the nonce in KDC-REQ-BODY 10 | /// cname [1] PrincipalName OPTIONAL, 11 | /// -- Certificate mapping hints 12 | /// crealm [2] Realm, 13 | /// subject-certificate [3] OCTET STRING OPTIONAL, 14 | /// options [4] BIT STRING OPTIONAL, 15 | /// ... 16 | /// } 17 | /// ``` 18 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 19 | pub struct S4uUserId { 20 | #[seq_field(context_tag = 0)] 21 | pub nonce: UInt32, 22 | #[seq_field(context_tag = 1)] 23 | pub cname: Option, 24 | #[seq_field(context_tag = 2)] 25 | pub crealm: Realm, 26 | #[seq_field(context_tag = 3)] 27 | pub subject_certificate: Option, 28 | #[seq_field(context_tag = 4)] 29 | pub options: Option, 30 | } 31 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/transporter/mod.rs: -------------------------------------------------------------------------------- 1 | //! Module to provide means to transport Kerberos messages 2 | //! 3 | 4 | use std::net::*; 5 | 6 | mod transporter_trait; 7 | pub use transporter_trait::*; 8 | 9 | mod tcp_transporter; 10 | use tcp_transporter::*; 11 | 12 | mod udp_transporter; 13 | use udp_transporter::*; 14 | 15 | /// Default Kerberos port 88 16 | pub const DEFAULT_KERBEROS_PORT: u16 = 88; 17 | 18 | /// Transport protocols available to send Kerberos messages 19 | #[derive(Debug, PartialEq, Clone, Copy)] 20 | pub enum TransportProtocol { 21 | TCP, 22 | UDP, 23 | } 24 | 25 | /// Generates a transporter given and address and transport protocol 26 | pub fn new_transporter( 27 | host_address: IpAddr, 28 | transport_protocol: TransportProtocol, 29 | ) -> Box { 30 | let dst_addr = SocketAddr::new(host_address, DEFAULT_KERBEROS_PORT); 31 | 32 | match transport_protocol { 33 | TransportProtocol::TCP => { 34 | return Box::new(TCPTransporter::new(dst_addr)); 35 | } 36 | TransportProtocol::UDP => { 37 | return Box::new(UDPTransporter::new(dst_addr)); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/uint32.rs: -------------------------------------------------------------------------------- 1 | 2 | /// (*UInt32*) Kerberos u32. 3 | /// Defined RFC4120, section 5.2.4. 4 | /// ```asn1 5 | /// UInt32 ::= INTEGER (0..4294967295) 6 | /// -- unsigned 32 bit values 7 | /// ``` 8 | pub type UInt32 = u32; 9 | 10 | #[cfg(test)] 11 | mod test { 12 | use super::UInt32; 13 | use red_asn1::Asn1Object; 14 | 15 | #[test] 16 | fn test_encode_uint32() { 17 | assert_eq!( 18 | vec![0x02, 0x04, 0x06, 0x08, 0x95, 0xb6], 19 | (101225910 as u32).build() 20 | ); 21 | 22 | assert_eq!( 23 | vec![0x02, 0x04, 0xc1, 0x75, 0xc7, 0xce], 24 | (3245721550 as u32).build() 25 | ); 26 | } 27 | 28 | #[test] 29 | fn test_decode_uint32() { 30 | assert_eq!( 31 | 101225910, 32 | UInt32::parse(&[0x02, 0x04, 0x06, 0x08, 0x95, 0xb6]) 33 | .unwrap() 34 | .1 35 | ); 36 | 37 | assert_eq!( 38 | 3245721550, 39 | UInt32::parse(&[0x02, 0x04, 0xc1, 0x75, 0xc7, 0xce]) 40 | .unwrap() 41 | .1 42 | ) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /services/sg/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "sg" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | async-stream = "0.3.3" 8 | async-trait = "^0.1" 9 | byteorder = "^1" 10 | bytes = "^1" 11 | chrono = "0.4.19" 12 | clap = { version = "3.2.8", features = ["derive"] } 13 | futures-util = "^0.3" 14 | hex-literal = "0.3.1" 15 | kerberos_asn1 = { path = "../../third_party/kerbeiros/kerberos_asn1" } 16 | kerberos_constants = { path = "../../third_party/kerbeiros/kerberos_constants" } 17 | log = { version = "0.4.4", default-features = false } 18 | nom = "^7" 19 | pcapng-writer = "0.1.0" 20 | phf = { version = "0.10", features = ["macros"] } 21 | rand = "0.7" 22 | rust-crypto = "^0.2" 23 | simple_logger = "^2" 24 | smoltcp = "^0.8" 25 | smoltcp-user-vpn = { path = "../../libs/smoltcp-user-vpn" } 26 | tempfile = "^3" 27 | tokio = { version = "1.12.0", features = ["full"] } 28 | tokio-postgres = "0.7.3" 29 | tokio-stream = "0.1.8" 30 | tokio-util = { version = "^0.6", features = ["time"]} 31 | xblive = { path = "../../libs/xblive" } 32 | xbox-sys = { path = "../../libs/xbox-sys" } 33 | xombie = { path = "../../libs/xombie" } 34 | xombie-matchmaking = { path = "../../libs/xombie-matchmaking" } 35 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1_derive/src/parse_definitions.rs: -------------------------------------------------------------------------------- 1 | use syn::{Ident, PathSegment}; 2 | use proc_macro2::TokenStream; 3 | 4 | pub struct SequenceDefinition { 5 | pub name: Ident, 6 | pub application_tag_number: Option, 7 | pub fields: Vec 8 | } 9 | 10 | pub struct FieldDefinition { 11 | pub id: Ident, 12 | pub kind: Ident, 13 | pub sub_kinds: Option, 14 | pub optional: bool, 15 | pub context_tag_number: Option 16 | } 17 | 18 | 19 | impl FieldDefinition { 20 | pub fn parser_name(&self) -> Ident { 21 | let concatenated = format!("parse_{}", self.id); 22 | return Ident::new(&concatenated, self.id.span()); 23 | } 24 | 25 | pub fn builder_name(&self) -> Ident { 26 | let concatenated = format!("build_{}", self.id); 27 | return Ident::new(&concatenated, self.id.span()); 28 | } 29 | 30 | } 31 | 32 | pub struct FieldCode { 33 | pub builder: TokenStream, 34 | pub parser: TokenStream 35 | } 36 | 37 | 38 | pub struct SequenceInnerCallsCode { 39 | pub build_calls: TokenStream, 40 | pub parse_calls: TokenStream, 41 | pub components_unit_functions: TokenStream 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/krb_safe_body.rs: -------------------------------------------------------------------------------- 1 | use crate::{HostAddress, KerberosTime, Microseconds, UInt32}; 2 | use red_asn1::{Asn1Object, OctetString}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*KRB-SAFE-BODY*) Included in *KRB-SAFE*. 6 | /// Defined in RFC4120, section 5.6.1. 7 | /// ```asn1 8 | /// KRB-SAFE-BODY ::= SEQUENCE { 9 | /// user-data [0] OCTET STRING, 10 | /// timestamp [1] KerberosTime OPTIONAL, 11 | /// usec [2] Microseconds OPTIONAL, 12 | /// seq-number [3] UInt32 OPTIONAL, 13 | /// s-address [4] HostAddress, 14 | /// r-address [5] HostAddress OPTIONAL 15 | /// } 16 | /// ``` 17 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 18 | pub struct KrbSafeBody { 19 | #[seq_field(context_tag = 0)] 20 | pub user_data: OctetString, 21 | #[seq_field(context_tag = 1)] 22 | pub timestamp: Option, 23 | #[seq_field(context_tag = 2)] 24 | pub usec: Option, 25 | #[seq_field(context_tag = 3)] 26 | pub seq_number: Option, 27 | #[seq_field(context_tag = 4)] 28 | pub s_address: HostAddress, 29 | #[seq_field(context_tag = 5)] 30 | pub r_address: Option, 31 | } 32 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/kerberos_string.rs: -------------------------------------------------------------------------------- 1 | use red_asn1::GeneralString; 2 | 3 | /// (*KerberosString*) String used in Kerberos. 4 | /// Defined in RFC4120, section 5.2.1. 5 | /// ```asn1 6 | /// KerberosString ::= GeneralString (IA5String) 7 | /// ``` 8 | pub type KerberosString = GeneralString; 9 | 10 | #[cfg(test)] 11 | mod tests { 12 | use super::*; 13 | use red_asn1::Asn1Object; 14 | 15 | #[test] 16 | fn test_encode_kerberos_string() { 17 | let kerberos_string = 18 | KerberosString::from("KINGDOM.HEARTS"); 19 | 20 | assert_eq!( 21 | vec![ 22 | 0x1b, 0x0e, 0x4b, 0x49, 0x4e, 0x47, 0x44, 0x4f, 0x4d, 0x2e, 23 | 0x48, 0x45, 0x41, 0x52, 0x54, 0x53 24 | ], 25 | kerberos_string.build() 26 | ); 27 | } 28 | 29 | #[test] 30 | fn test_decode_kerberos_string() { 31 | assert_eq!( 32 | KerberosString::from("KINGDOM.HEARTS"), 33 | KerberosString::parse(&[ 34 | 0x1b, 0x0e, 0x4b, 0x49, 0x4e, 0x47, 0x44, 0x4f, 0x4d, 0x2e, 35 | 0x48, 0x45, 0x41, 0x52, 0x54, 0x53, 36 | ]) 37 | .unwrap() 38 | .1 39 | ); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /libs/xblive/src/addr.rs: -------------------------------------------------------------------------------- 1 | use bytes::BufMut; 2 | 3 | use nom::number::complete::le_u16; 4 | 5 | use xbox_sys::codec::{BufPut, Decode, decode_array_u8}; 6 | 7 | use crate::net::{InAddr, Eui48}; 8 | 9 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] 10 | #[repr(C)] 11 | pub struct Addr { 12 | pub addr: InAddr, 13 | pub addr_online: InAddr, 14 | pub port_online: u16, 15 | pub enet: Eui48, 16 | pub online: [u8;20], 17 | } 18 | 19 | impl Addr { 20 | pub const ENCODED_LEN: usize = 4 + 4 + 2 + 6 + 20; 21 | } 22 | 23 | impl BufPut for Addr { 24 | fn put(&self, buf: &mut AnyBufMut) { 25 | self.addr.put(buf); 26 | self.addr_online.put(buf); 27 | buf.put_u16_le(self.port_online); 28 | self.enet.put(buf); 29 | buf.put_slice(&self.online); 30 | } 31 | } 32 | 33 | impl Decode for Addr { 34 | fn decode<'a>(input: &'a [u8]) -> nom::IResult<&'a [u8], Self> { 35 | let (input, addr) = InAddr::decode(input)?; 36 | let (input, addr_online) = InAddr::decode(input)?; 37 | let (input, port_online) = le_u16(input)?; 38 | let (input, enet) = Eui48::decode(input)?; 39 | let (input, online) = decode_array_u8(input)?; 40 | 41 | Ok((input, Addr { 42 | addr, 43 | addr_online, 44 | port_online, 45 | enet, 46 | online, 47 | })) 48 | } 49 | } -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/int32.rs: -------------------------------------------------------------------------------- 1 | 2 | /// (*Int32*) Kerberos i32. 3 | /// Defined in RFC4120, section 5.2.4. 4 | /// ```asn1 5 | /// Int32 ::= INTEGER (-2147483648..2147483647) 6 | /// -- signed values representable in 32 bits 7 | /// ``` 8 | pub type Int32 = i32; 9 | 10 | #[cfg(test)] 11 | mod test { 12 | use super::*; 13 | use red_asn1::Asn1Object; 14 | 15 | #[test] 16 | fn test_encode_int32() { 17 | assert_eq!(vec![0x02, 0x02, 0xff, 0x79], Int32::from(-135).build()); 18 | 19 | assert_eq!(vec![0x02, 0x01, 0x03], Int32::from(3).build()); 20 | } 21 | 22 | #[test] 23 | fn test_decode_int32() { 24 | assert_eq!(-135, Int32::parse(&[0x02, 0x02, 0xff, 0x79]).unwrap().1); 25 | 26 | assert_eq!(3, Int32::parse(&[0x02, 0x01, 0x03]).unwrap().1); 27 | } 28 | 29 | #[should_panic(expected = "IncorrectValue")] 30 | #[test] 31 | fn test_decode_higher_value_than_int32() { 32 | Int32::parse(&[0x02, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00]).unwrap(); 33 | } 34 | 35 | #[should_panic(expected = "IncorrectValue")] 36 | #[test] 37 | fn test_decode_lower_value_than_int32() { 38 | Int32::parse(&[0x02, 0x05, 0xf1, 0x00, 0x00, 0x00, 0x00]).unwrap(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/algorithms/aes_hmac_sha1/salt.rs: -------------------------------------------------------------------------------- 1 | /// Creates the AES salt from the realm and the client name 2 | pub fn generate_salt(realm: &str, client_name: &str) -> Vec { 3 | let mut salt = realm.to_uppercase(); 4 | let mut lowercase_username = client_name.to_lowercase(); 5 | 6 | if lowercase_username.ends_with("$") { 7 | // client name = "host.lower.domain.com" 8 | salt.push_str("host"); 9 | lowercase_username.pop(); 10 | salt.push_str(&lowercase_username); 11 | salt.push('.'); 12 | salt.push_str(&realm.to_lowercase()); 13 | } else { 14 | salt.push_str(&lowercase_username); 15 | } 16 | 17 | return salt.as_bytes().to_vec(); 18 | } 19 | 20 | #[cfg(test)] 21 | mod test { 22 | use super::*; 23 | 24 | #[test] 25 | fn test_generate_aes_user_salt() { 26 | assert_eq!( 27 | "KINGDOM.HEARTSmickey".as_bytes().to_vec(), 28 | generate_salt("KINGdom.HEARTS", "MicKey") 29 | ); 30 | } 31 | 32 | #[test] 33 | fn test_generate_aes_host_salt() { 34 | assert_eq!( 35 | "KINGDOM.HEARTShostpc.kingdom.hearts".as_bytes().to_vec(), 36 | generate_salt("kingdom.Hearts", "PC$") 37 | ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Kerberos ASN1 4 | This library defines the ASN1 structures used by the Kerberos 5 | protocol as Rust structs. Based in the red_asn1 library. 6 | 7 | Each type defined in this library provides a method `parse` to parse 8 | an array of bytes and create the type, and a method `build` to create 9 | an array of bytes from the type and its values. 10 | 11 | ## Examples 12 | 13 | Decoding a string of Kerberos: 14 | ```rust 15 | use kerberos_asn1::KerberosString; 16 | use red_asn1::Asn1Object; 17 | 18 | let raw_string = &[ 19 | 0x1b, 0x0e, 0x4b, 0x49, 0x4e, 0x47, 0x44, 0x4f, 0x4d, 0x2e, 20 | 0x48, 0x45, 0x41, 0x52, 0x54, 0x53, 21 | ]; 22 | let (rest_raw, kerberos_string) = KerberosString::parse(raw_string).unwrap(); 23 | 24 | assert_eq!("KINGDOM.HEARTS", kerberos_string); 25 | ``` 26 | ## References 27 | - [RFC 4120, The Kerberos Network Authentication Service (V5)](https://tools.ietf.org/html/rfc4120) 28 | - [RFC 6806, Kerberos Principal Name Canonicalization and Cross-Realm Referrals](https://tools.ietf.org/html/rfc6806) 29 | - [MS-KILE](https://docs.microsoft.com/en-us/openspecs/windows_protocols/MS-KILE/2a32282e-dd48-4ad9-a542-609804b02cc9) 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | mod ad_and_or; 3 | pub use ad_and_or::AdAndOr; 4 | 5 | mod ad_if_relevant; 6 | pub use ad_if_relevant::AdIfRelevant; 7 | 8 | mod ad_kdcissued; 9 | pub use ad_kdcissued::AdKdcIssued; 10 | 11 | mod ad_mandatory_for_kdc; 12 | pub use ad_mandatory_for_kdc::AdMandatoryForKdc; 13 | 14 | mod etype_info; 15 | pub use etype_info::EtypeInfo; 16 | 17 | mod etype_info2; 18 | pub use etype_info2::EtypeInfo2; 19 | 20 | mod etype_info2_entry; 21 | pub use etype_info2_entry::EtypeInfo2Entry; 22 | 23 | mod etype_info_entry; 24 | pub use etype_info_entry::EtypeInfoEntry; 25 | 26 | mod kerb_pa_pac_request; 27 | pub use kerb_pa_pac_request::KerbPaPacRequest; 28 | 29 | mod method_data; 30 | pub use method_data::MethodData; 31 | 32 | mod pa_data; 33 | pub use pa_data::PaData; 34 | 35 | mod pa_enc_timestamp; 36 | pub use pa_enc_timestamp::PaEncTimestamp; 37 | 38 | mod pa_enc_ts_enc; 39 | pub use pa_enc_ts_enc::PaEncTsEnc; 40 | 41 | mod pa_for_user; 42 | pub use pa_for_user::PaForUser; 43 | 44 | mod pa_pac_options; 45 | pub use pa_pac_options::PaPacOptions; 46 | 47 | mod pa_s4u_x509_user; 48 | pub use pa_s4u_x509_user::PaS4uX509User; 49 | 50 | mod pa_supported_enctypes; 51 | pub use pa_supported_enctypes::PaSupportedEnctypes; 52 | 53 | mod s4userid; 54 | pub use s4userid::S4uUserId; 55 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/enc_krb_priv_part.rs: -------------------------------------------------------------------------------- 1 | use crate::{KerberosTime, Microseconds, UInt32, HostAddress}; 2 | use red_asn1::{OctetString, Asn1Object}; 3 | use red_asn1_derive::Sequence; 4 | 5 | 6 | /// (*EncKrbPrivPart*) Encripted part of the *KRB-PRIV* message. Defined in RFC4120, section 5.7.1. 7 | /// ```asn1 8 | /// EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE { 9 | /// user-data [0] OCTET STRING, 10 | /// timestamp [1] KerberosTime OPTIONAL, 11 | /// usec [2] Microseconds OPTIONAL, 12 | /// seq-number [3] UInt32 OPTIONAL, 13 | /// s-address [4] HostAddress -- sender's addr --, 14 | /// r-address [5] HostAddress OPTIONAL -- recip's addr 15 | /// } 16 | /// ``` 17 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 18 | #[seq(application_tag = 28)] 19 | pub struct EncKrbPrivPart { 20 | #[seq_field(context_tag = 0)] 21 | pub user_data: OctetString, 22 | #[seq_field(context_tag = 1)] 23 | pub timestamp: Option, 24 | #[seq_field(context_tag = 2)] 25 | pub usec: Option, 26 | #[seq_field(context_tag = 3)] 27 | pub seq_number: Option, 28 | #[seq_field(context_tag = 4)] 29 | pub s_address: HostAddress, 30 | #[seq_field(context_tag = 5)] 31 | pub r_address: Option, 32 | } 33 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/enc_krb_cred_part.rs: -------------------------------------------------------------------------------- 1 | use crate::{HostAddress, KerberosTime, KrbCredInfo, Microseconds, UInt32}; 2 | use red_asn1::{Asn1Object, SequenceOf}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*EncKrbCredPart*) The encrypted part of the *KRB-CRED* message. Defined in RFC4120, section 5.8.1. 6 | /// ```asn1 7 | /// EncKrbCredPart ::= [APPLICATION 29] SEQUENCE { 8 | /// ticket-info [0] SEQUENCE OF KrbCredInfo, 9 | /// nonce [1] UInt32 OPTIONAL, 10 | /// timestamp [2] KerberosTime OPTIONAL, 11 | /// usec [3] Microseconds OPTIONAL, 12 | /// s-address [4] HostAddress OPTIONAL, 13 | /// r-address [5] HostAddress OPTIONAL 14 | /// } 15 | /// ``` 16 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 17 | #[seq(application_tag = 29)] 18 | pub struct EncKrbCredPart { 19 | #[seq_field(context_tag = 0)] 20 | pub ticket_info: SequenceOf, 21 | #[seq_field(context_tag = 1)] 22 | pub nonce: Option, 23 | #[seq_field(context_tag = 2)] 24 | pub timestamp: Option, 25 | #[seq_field(context_tag = 3)] 26 | pub usec: Option, 27 | #[seq_field(context_tag = 4)] 28 | pub s_address: Option, 29 | #[seq_field(context_tag = 5)] 30 | pub r_address: Option, 31 | } 32 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1/src/types/mod.rs: -------------------------------------------------------------------------------- 1 | mod bitstring; 2 | pub use bitstring::*; 3 | 4 | mod boolean; 5 | pub use boolean::*; 6 | 7 | mod generalizedtime; 8 | pub use generalizedtime::{GeneralizedTime, GENERALIZED_TIME_TAG_NUMBER}; 9 | 10 | mod generalstring; 11 | pub use generalstring::*; 12 | 13 | mod ia5string; 14 | pub use ia5string::*; 15 | 16 | mod enumerated; 17 | pub use enumerated::{Enumerated, ENUMERATED_TAG_NUMBER}; 18 | 19 | mod integer; 20 | pub use integer::*; 21 | 22 | mod octetstring; 23 | pub use octetstring::*; 24 | 25 | mod oid; 26 | pub use oid::Oid; 27 | 28 | mod sequenceof; 29 | pub use sequenceof::*; 30 | 31 | mod optional; 32 | pub use optional::Optional; 33 | 34 | #[cfg(test)] 35 | mod tests { 36 | use super::*; 37 | use crate::traits::*; 38 | 39 | #[test] 40 | fn test_build_common_tags() { 41 | assert_eq!(vec![0x01], Boolean::tag().build()); 42 | assert_eq!(vec![0x02], Integer::tag().build()); 43 | assert_eq!(vec![0x03], BitString::tag().build()); 44 | assert_eq!(vec![0x04], OctetString::tag().build()); 45 | assert_eq!(vec![0x0a], Enumerated::::tag().build()); 46 | assert_eq!(vec![0x30], SequenceOf::::tag().build()); 47 | assert_eq!(vec![0x16], IA5String::tag().build()); 48 | assert_eq!(vec![0x18], GeneralizedTime::tag().build()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /services/sg/src/client/forward.rs: -------------------------------------------------------------------------------- 1 | use async_trait::async_trait; 2 | 3 | use crate::client::{ClientState, PacketProcessError}; 4 | use crate::client::service::Service; 5 | use crate::client::tcp::{ServerImpl, ServerStack}; 6 | 7 | use xblive::sg::tcp::TcpHeader; 8 | 9 | pub struct ForwardTcpService { 10 | server: ServerStack, 11 | } 12 | 13 | impl ForwardTcpService { 14 | pub fn new() -> Self { 15 | ForwardTcpService { 16 | server: ServerStack::new(Box::new(|| { 17 | Ok(ForwardServiceImpl { 18 | }) 19 | })) 20 | } 21 | } 22 | } 23 | 24 | #[async_trait] 25 | impl Service for ForwardTcpService { 26 | async fn on_tcp_packet<'a>(&mut self, header: &TcpHeader, packet: &[u8], state: &ClientState) -> Result<(), PacketProcessError> { 27 | self.server.on_packet(header, packet, state) 28 | .await 29 | } 30 | } 31 | 32 | struct ForwardServiceImpl { 33 | 34 | } 35 | 36 | #[async_trait] 37 | impl ServerImpl for ForwardServiceImpl { 38 | async fn on_accept(&mut self) -> Result<(), PacketProcessError> { 39 | println!("Accepted connection"); 40 | 41 | Ok(()) 42 | } 43 | 44 | async fn on_incoming_data(&mut self, data: &[u8]) -> Result<(), PacketProcessError> { 45 | println!("on_incoming_data: {:02x?}", data); 46 | 47 | Ok(()) 48 | } 49 | } -------------------------------------------------------------------------------- /libs/block-device/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | pub mod file; 4 | pub mod partition; 5 | #[cfg(feature = "scsi")] 6 | pub mod scsi; 7 | #[cfg(feature = "usb")] 8 | pub mod usb; 9 | 10 | pub trait BlockDevice { 11 | fn block_size(&self) -> usize { 12 | BLOCK_SIZE 13 | } 14 | 15 | fn num_blocks(&mut self) -> u64; 16 | 17 | fn read_block(&mut self, block_num: u64) -> io::Result<[u8;BLOCK_SIZE]>; 18 | fn write_block(&mut self, block_num: u64, block: &[u8;BLOCK_SIZE]) -> io::Result<()>; 19 | 20 | fn read_sequence_to_vec(&mut self, base_block: u64, num_blocks: usize) -> io::Result> { 21 | let mut result = vec![]; 22 | 23 | for i in 0..num_blocks { 24 | let block = self.read_block(base_block + i as u64)?; 25 | result.extend_from_slice(&block); 26 | } 27 | 28 | Ok(result) 29 | } 30 | 31 | fn write_sequence(&mut self, buf: &[u8], base_block: u64) -> io::Result<()> { 32 | if buf.len() % BLOCK_SIZE != 0 { 33 | return Err(io::Error::new(io::ErrorKind::Other, "Buffer length not multiple of block size")) 34 | } 35 | 36 | for (i, block) in buf.chunks(BLOCK_SIZE).enumerate() { 37 | let block = block.try_into().unwrap(); 38 | self.write_block(base_block + i as u64, block)?; 39 | } 40 | 41 | Ok(()) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /libs/xblive/src/ver.rs: -------------------------------------------------------------------------------- 1 | use bytes::BufMut; 2 | 3 | use nom::number::streaming::le_u16; 4 | 5 | use xbox_sys::codec::{BufPut, Decode}; 6 | 7 | #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] 8 | pub struct LibraryVersion { 9 | pub major: u16, 10 | pub minor: u16, 11 | pub build: u16, 12 | pub qfe: u16, 13 | } 14 | 15 | impl LibraryVersion { 16 | pub fn from_raw(raw: &[u8]) -> Option { 17 | let (remainder, library_version) = Self::decode(raw) 18 | .ok()?; 19 | 20 | if remainder.len() == 0 { 21 | Some(library_version) 22 | } else { 23 | None 24 | } 25 | } 26 | } 27 | 28 | impl BufPut for LibraryVersion { 29 | fn put(&self, buf: &mut AnyBufMut) { 30 | buf.put_u16_le(self.major); 31 | buf.put_u16_le(self.minor); 32 | buf.put_u16_le(self.build); 33 | buf.put_u16_le(self.qfe); 34 | } 35 | } 36 | 37 | impl Decode for LibraryVersion { 38 | fn decode<'a>(input: &'a [u8]) -> nom::IResult<&'a [u8], Self> { 39 | let (input, major) = le_u16(input)?; 40 | let (input, minor) = le_u16(input)?; 41 | let (input, build) = le_u16(input)?; 42 | let (input, qfe) = le_u16(input)?; 43 | 44 | Ok((input, LibraryVersion { 45 | major, 46 | minor, 47 | build, 48 | qfe, 49 | })) 50 | } 51 | } -------------------------------------------------------------------------------- /services/kdc/src/krb.rs: -------------------------------------------------------------------------------- 1 | use hex_literal::hex; 2 | 3 | use kerberos_asn1::{AsReq, Asn1Object, TgsReq}; 4 | 5 | use xbox_sys::crypto::SymmetricKey; 6 | 7 | pub const TGS_MASTER_KEY: SymmetricKey = 8 | SymmetricKey(hex!["8b27f6581f2695da755f8f8ffea571f1"]); 9 | 10 | pub enum RequestType { 11 | As(AsReq), 12 | Tgs(TgsReq), 13 | } 14 | 15 | pub fn request_type(buf: &[u8]) -> Option { 16 | match buf.get(0) { 17 | //ASN.1 DER Application 10 tag 18 | Some(0x6a) => { 19 | let (rem, as_req) = AsReq::parse(buf) 20 | .map_err(|err| eprintln!("Warning: Couldn't parse AS-REQ: {:?}: {:02x?}", 21 | err, buf)) 22 | .ok()?; 23 | if !rem.is_empty() { 24 | eprintln!("Warning: AS-REQ had remainder bytes: {:02x?}", buf); 25 | } 26 | Some(RequestType::As(as_req)) 27 | } 28 | 29 | //ASN.1 DER Application 12 tag 30 | Some(0x6c) => { 31 | let (rem, tgs_req) = TgsReq::parse(buf) 32 | .map_err(|err| eprintln!("Warning: Couldn't parse TGS-REQ: {:?}: {:02x?}", 33 | err, buf)) 34 | .ok()?; 35 | 36 | if !rem.is_empty() { 37 | eprintln!("Warning: TGS-REQ had remainder bytes: {:02x?}", buf); 38 | } 39 | Some(RequestType::Tgs(tgs_req)) 40 | } 41 | _ => None, 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /libs/block-device/src/file.rs: -------------------------------------------------------------------------------- 1 | use std::io::{Read, Seek, SeekFrom, Write, self}; 2 | use std::fs::{File, OpenOptions}; 3 | use std::path::Path; 4 | 5 | use crate::BlockDevice; 6 | 7 | pub struct FileBlockDevice { 8 | f: File, 9 | } 10 | 11 | impl FileBlockDevice { 12 | pub fn open>(path: P) -> io::Result> { 13 | Ok(FileBlockDevice { 14 | f: OpenOptions::new() 15 | .read(true) 16 | .write(true) 17 | .open(path)?, 18 | }) 19 | } 20 | 21 | pub fn seek_to_block(&mut self, block_num: u64) -> io::Result<()> { 22 | let byte_offset = block_num * (BLOCK_SIZE as u64); 23 | self.f.seek(SeekFrom::Start(byte_offset))?; 24 | 25 | Ok(()) 26 | } 27 | } 28 | 29 | impl BlockDevice for FileBlockDevice { 30 | fn num_blocks(&mut self) -> u64 { 31 | todo!() 32 | } 33 | 34 | fn read_block(&mut self, block_num: u64) -> io::Result<[u8;BLOCK_SIZE]> { 35 | let mut buf = [0u8;BLOCK_SIZE]; 36 | 37 | self.seek_to_block(block_num)?; 38 | self.f.read_exact(&mut buf)?; 39 | 40 | Ok(buf) 41 | } 42 | 43 | fn write_block(&mut self, block_num: u64, block: &[u8;BLOCK_SIZE]) -> io::Result<()> { 44 | self.seek_to_block(block_num)?; 45 | 46 | self.f.write_all(block)?; 47 | 48 | Ok(()) 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /libs/xombie/src/account.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | use std::io; 4 | use std::fs; 5 | use std::path::Path; 6 | 7 | use xbox_sys::crypto::SymmetricKey; 8 | use xbox_sys::account::{Gamertag, Domain, PassCode, Realm, UnsignedAccount, Xuid}; 9 | 10 | #[derive(Debug, Deserialize, Serialize)] 11 | struct TomlAccount { 12 | xuid: [u8;8], 13 | gamertag: String, 14 | domain: String, 15 | realm: String, 16 | key: [u8;16], 17 | } 18 | 19 | #[derive(Debug)] 20 | pub enum ReadTomlAccountError { 21 | Io(io::Error), 22 | ParseFile(toml::de::Error), 23 | ParseField(&'static str), 24 | } 25 | 26 | pub fn read_toml_account_file>(path: P) -> Result { 27 | use ReadTomlAccountError::*; 28 | 29 | let s = fs::read_to_string(path) 30 | .map_err(|err| Io(err))?; 31 | 32 | let toml_account: TomlAccount = toml::from_str(&s) 33 | .map_err(|err| ParseFile(err))?; 34 | 35 | let xuid = Xuid(u64::from_be_bytes(toml_account.xuid)); 36 | 37 | Ok(UnsignedAccount { 38 | xuid, 39 | user_flags: 0, 40 | gamertag: Gamertag::try_from(toml_account.gamertag.as_str()) 41 | .map_err(|_| ParseField("gamertag"))?, 42 | user_options: 0, 43 | passcode: PassCode::default(), 44 | domain: Domain::try_from(toml_account.domain.as_str()) 45 | .map_err(|_| ParseField("domain"))?, 46 | kerberos_realm: Realm::try_from(toml_account.realm.as_str()) 47 | .map_err(|_| ParseField("kerberos_realm"))?, 48 | key: SymmetricKey(toml_account.key), 49 | }) 50 | } 51 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/ap_req.rs: -------------------------------------------------------------------------------- 1 | use crate::{Int32, ApOptions, Ticket, EncryptedData}; 2 | use red_asn1::Asn1Object; 3 | use red_asn1_derive::Sequence; 4 | use kerberos_constants::message_types::KRB_AP_REQ; 5 | use kerberos_constants::protocol_version::PVNO; 6 | 7 | /// (*AP-REQ*) Message sent to the application server to authenticate the client. 8 | /// Defined in RFC4120, section 5.5.1. 9 | ///```asn1 10 | /// AP-REQ ::= [APPLICATION 14] SEQUENCE { 11 | /// pvno [0] INTEGER (5), 12 | /// msg-type [1] INTEGER (14), 13 | /// ap-options [2] APOptions, 14 | /// ticket [3] Ticket, 15 | /// authenticator [4] EncryptedData -- Authenticator 16 | /// } 17 | /// ``` 18 | #[derive(Sequence, Debug, Clone, PartialEq)] 19 | #[seq(application_tag = 14)] 20 | pub struct ApReq { 21 | #[seq_field(context_tag = 0)] 22 | pub pvno: Int32, 23 | #[seq_field(context_tag = 1)] 24 | pub msg_type: Int32, 25 | #[seq_field(context_tag = 2)] 26 | pub ap_options: ApOptions, 27 | #[seq_field(context_tag = 3)] 28 | pub ticket: Ticket, 29 | #[seq_field(context_tag = 4)] 30 | pub authenticator: EncryptedData 31 | } 32 | 33 | impl Default for ApReq { 34 | fn default() -> Self { 35 | Self { 36 | pvno: PVNO, 37 | msg_type: KRB_AP_REQ, 38 | ap_options: ApOptions::default(), 39 | ticket: Ticket::default(), 40 | authenticator: EncryptedData::default() 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/helpers.rs: -------------------------------------------------------------------------------- 1 | //! Useful public functions 2 | 3 | use kerberos_constants::etypes::{ 4 | AES128_CTS_HMAC_SHA1_96, AES256_CTS_HMAC_SHA1_96, RC4_HMAC, 5 | }; 6 | 7 | 8 | /// Helper to check is an encryption type is supported by this library 9 | pub fn is_supported_etype(etype: i32) -> bool { 10 | return supported_etypes().contains(&etype); 11 | } 12 | 13 | /// Returns a vector with the etypes of the supported algorithms 14 | /// by this library 15 | pub fn supported_etypes() -> Vec { 16 | vec![ 17 | AES256_CTS_HMAC_SHA1_96, 18 | AES128_CTS_HMAC_SHA1_96, 19 | RC4_HMAC 20 | ] 21 | } 22 | 23 | #[cfg(test)] 24 | mod test { 25 | use super::*; 26 | use kerberos_constants::etypes::*; 27 | 28 | #[test] 29 | fn supported_etypes() { 30 | assert_eq!(true, is_supported_etype(AES256_CTS_HMAC_SHA1_96)); 31 | assert_eq!(true, is_supported_etype(AES128_CTS_HMAC_SHA1_96)); 32 | assert_eq!(true, is_supported_etype(RC4_HMAC)); 33 | assert_eq!(false, is_supported_etype(NO_ENCRYPTION)); 34 | assert_eq!(false, is_supported_etype(RC4_HMAC_EXP)); 35 | assert_eq!(false, is_supported_etype(DES_CBC_MD5)); 36 | assert_eq!(false, is_supported_etype(DES_CBC_CRC)); 37 | assert_eq!(false, is_supported_etype(RC4_HMAC_OLD_EXP)); 38 | assert_eq!( 39 | false, 40 | is_supported_etype( 41 | AES256_CTS_HMAC_SHA1_96 | AES128_CTS_HMAC_SHA1_96 42 | ) 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/krb_cred.rs: -------------------------------------------------------------------------------- 1 | use crate::{Int32, Ticket, EncryptedData}; 2 | use red_asn1::{SequenceOf, Asn1Object}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*KRB-CRED*) Message used to send Kerberos credentials form one principal to another. 6 | /// Defined in RFC4120, section 5.8.1. 7 | /// ```asn1 8 | /// KRB-CRED ::= [APPLICATION 22] SEQUENCE { 9 | /// pvno [0] INTEGER (5), 10 | /// msg-type [1] INTEGER (22), 11 | /// tickets [2] SEQUENCE OF Ticket, 12 | /// enc-part [3] EncryptedData -- EncKrbCredPart 13 | /// } 14 | /// ``` 15 | #[derive(Sequence, Debug, Clone, PartialEq)] 16 | #[seq(application_tag = 22)] 17 | pub struct KrbCred { 18 | #[seq_field(context_tag = 0)] 19 | pub pvno: Int32, 20 | #[seq_field(context_tag = 1)] 21 | pub msg_type: Int32, 22 | #[seq_field(context_tag = 2)] 23 | pub tickets: SequenceOf, 24 | #[seq_field(context_tag = 3)] 25 | pub enc_part: EncryptedData, 26 | } 27 | 28 | 29 | impl KrbCred { 30 | pub fn new(tickets: SequenceOf, enc_part: EncryptedData) -> Self { 31 | let mut s = Self::default(); 32 | s.tickets = tickets; 33 | s.enc_part = enc_part; 34 | return s; 35 | } 36 | } 37 | 38 | impl Default for KrbCred { 39 | fn default() -> Self { 40 | return Self { 41 | pvno: 5, 42 | msg_type: 22, 43 | tickets: SequenceOf::default(), 44 | enc_part: EncryptedData::default() 45 | }; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | Kerberos client 4 | 5 | # Concepts 6 | * KDC (Key Distribution Center): Service that distributes the tickets. The host that provides this server is also called KDC. 7 | * TGS (Ticket Granting Server): Ticket used to authenticate the user against a specified service. 8 | * TGT (Ticket Granting Ticket): Ticket used to retrieve the TGS's from the KDC. 9 | 10 | # Examples 11 | 12 | Asking for a TGT: 13 | 14 | ```no_run 15 | use kerbeiros::*; 16 | use ascii::AsciiString; 17 | use std::net::*; 18 | 19 | // Prepare the arguments 20 | let realm = AsciiString::from_ascii("CONTOSO.COM").unwrap(); 21 | let kdc_address = IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)); 22 | let username = AsciiString::from_ascii("Bob").unwrap(); 23 | let user_key = Key::Password("S3cr3t".to_string()); 24 | 25 | // Request the TGT 26 | let tgt_requester = TgtRequester::new(realm, kdc_address); 27 | let credential = tgt_requester.request(&username, Some(&user_key)).unwrap(); 28 | 29 | // Save the ticket into a Windows format file 30 | credential.clone().save_into_krb_cred_file("bob_tgt.krb").unwrap(); 31 | 32 | // Save the ticket into a Linux format file 33 | credential.save_into_ccache_file("bob_tgt.ccache").unwrap(); 34 | ``` 35 | 36 | # Kerberos References 37 | * [RFC 4120: The Kerberos Network Authentication Service (V5)](https://tools.ietf.org/html/rfc4120) 38 | * [\[MS-KILE\]: Kerberos Protocol Extensions](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-kile) 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /libs/xombie/src/ip.rs: -------------------------------------------------------------------------------- 1 | /// Convert a string representaion of an IPV4 address to an array of four bytes 2 | /// 3 | /// ``` 4 | /// # use xombie::ip::ipv4_str_as_bytes; 5 | /// let addr = ipv4_str_as_bytes("10.24.73.99"); 6 | /// assert_eq!(Some([10, 24, 73, 99]), addr); 7 | /// ``` 8 | pub fn ipv4_str_as_bytes(s: &str) -> Option<[u8;4]> { 9 | let captures = regex::Regex::new("^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)$") 10 | .ok()? 11 | .captures(s)?; 12 | 13 | Some([ 14 | captures[1].parse().ok()?, 15 | captures[2].parse().ok()?, 16 | captures[3].parse().ok()?, 17 | captures[4].parse().ok()?, 18 | ]) 19 | } 20 | 21 | #[cfg(test)] 22 | mod tests { 23 | use super::ipv4_str_as_bytes; 24 | 25 | #[test] 26 | fn ipv4_str_as_bytes_good() { 27 | assert_eq!(Some([ 0, 0, 0, 0]), ipv4_str_as_bytes("0.0.0.0")); 28 | assert_eq!(Some([ 10, 24, 73, 99]), ipv4_str_as_bytes("10.24.73.99")); 29 | assert_eq!(Some([192, 168, 0, 1]), ipv4_str_as_bytes("192.168.0.1")); 30 | assert_eq!(Some([255, 255, 255, 255]), ipv4_str_as_bytes("255.255.255.255")); 31 | } 32 | 33 | #[test] 34 | fn ipv4_str_as_bytes_fails_with_wrong_number_of_arguments() { 35 | assert_eq!(None, ipv4_str_as_bytes("0.0.0.0.0")); 36 | assert_eq!(None, ipv4_str_as_bytes("0.0.0")); 37 | } 38 | 39 | #[test] 40 | fn ipv4_str_as_bytes_fails_with_arguments_out_of_bounds() { 41 | assert_eq!(None, ipv4_str_as_bytes("256.0.0.0")); 42 | assert_eq!(None, ipv4_str_as_bytes("-1.0.0.0")); 43 | } 44 | } -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_ccache/src/mappers/octet_string_mapper.rs: -------------------------------------------------------------------------------- 1 | use crate::CountedOctetString; 2 | use kerberos_asn1::KerberosString; 3 | use crate::{ConvertResult}; 4 | 5 | pub fn kerberos_string_to_counted_octet_string( 6 | kerberos_string: &KerberosString, 7 | ) -> CountedOctetString { 8 | return CountedOctetString::new(kerberos_string.as_bytes().to_vec()); 9 | } 10 | 11 | pub fn counted_octet_string_to_kerberos_string( 12 | counted_octet_string: CountedOctetString, 13 | ) -> ConvertResult { 14 | return Ok(KerberosString::from_utf8(counted_octet_string.data)?); 15 | } 16 | 17 | #[cfg(test)] 18 | mod test { 19 | use super::*; 20 | 21 | #[test] 22 | fn test_kerberos_string_to_counted_octet_string() { 23 | let cos_string = kerberos_string_to_counted_octet_string( 24 | &KerberosString::from("ABC"), 25 | ); 26 | 27 | assert_eq!(CountedOctetString::from("ABC"), cos_string); 28 | } 29 | 30 | #[test] 31 | fn test_counted_octet_string_to_kerberos_string() { 32 | let k_string: KerberosString = counted_octet_string_to_kerberos_string( 33 | CountedOctetString::from("ABC"), 34 | ) 35 | .unwrap(); 36 | 37 | assert_eq!(KerberosString::from("ABC"), k_string) 38 | } 39 | 40 | #[test] 41 | #[should_panic(expected = "FromUtf8Error")] 42 | fn test_counted_octet_string_to_kerberos_string_fail() { 43 | counted_octet_string_to_kerberos_string(CountedOctetString::new(vec![ 44 | 0xff, 45 | ])) 46 | .unwrap(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /libs/xblive/src/dns.rs: -------------------------------------------------------------------------------- 1 | pub const UDP_PORT: u16 = 53; 2 | 3 | #[derive(Clone, Copy, Debug)] 4 | pub enum ServiceType { 5 | MachineAccountCreationService, 6 | AuthenticationService, 7 | TicketGrantingService, 8 | } 9 | 10 | #[derive(Debug)] 11 | pub struct Service { 12 | pub service_type: ServiceType, 13 | pub partner_net: bool, 14 | } 15 | 16 | impl Service { 17 | pub fn from_domain_name(domain: &str) -> Option { 18 | Some(match domain { 19 | "as.part.xboxlive.com" => Service { 20 | service_type: ServiceType::AuthenticationService, 21 | partner_net: true, 22 | }, 23 | "as.xboxlive.com" => Service { 24 | service_type: ServiceType::AuthenticationService, 25 | partner_net: false, 26 | }, 27 | "macs.part.xboxlive.com" => Service { 28 | service_type: ServiceType::MachineAccountCreationService, 29 | partner_net: true, 30 | }, 31 | "macs.xboxlive.com" => Service { 32 | service_type: ServiceType::MachineAccountCreationService, 33 | partner_net: false, 34 | }, 35 | "tgs.part.xboxlive.com" => Service { 36 | service_type: ServiceType::TicketGrantingService, 37 | partner_net: true, 38 | }, 39 | "tgs.xboxlive.com" => Service { 40 | service_type: ServiceType::TicketGrantingService, 41 | partner_net: false, 42 | }, 43 | _ => return None, 44 | }) 45 | } 46 | } -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/pa_pac_options.rs: -------------------------------------------------------------------------------- 1 | use crate::KerberosFlags; 2 | use red_asn1::Asn1Object; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*PA-PAC-OPTIONS*) To request options of the PAC. 6 | /// Defined in MS-KILE, section 2.2.10 and MS-SFU, section 2.2.5. 7 | /// ```asn1 8 | /// PA-PAC-OPTIONS ::= SEQUENCE { 9 | /// KerberosFlags 10 | /// --Claims (0) 11 | /// --Branch Aware (1) 12 | /// --Forward to Full DC (2) 13 | /// -- resource-based constrained delegation (3) 14 | /// } 15 | /// ``` 16 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 17 | pub struct PaPacOptions { 18 | #[seq_field(context_tag = 0)] 19 | pub kerberos_flags: KerberosFlags, 20 | } 21 | 22 | #[cfg(test)] 23 | mod tests { 24 | use super::*; 25 | 26 | #[test] 27 | fn test_build_pa_pac_options() { 28 | let options = PaPacOptions { 29 | kerberos_flags: 0x10000000.into(), 30 | }; 31 | assert_eq!( 32 | vec![ 33 | 0x30, 0x09, 0xa0, 0x07, 0x03, 0x05, 0x00, 0x10, 0x00, 0x00, 34 | 0x00 35 | ], 36 | options.build() 37 | ) 38 | } 39 | 40 | #[test] 41 | fn test_parse_pa_pac_options() { 42 | let options = PaPacOptions { 43 | kerberos_flags: 0x10000000.into(), 44 | }; 45 | assert_eq!( 46 | options, 47 | PaPacOptions::parse(&[ 48 | 0x30, 0x09, 0xa0, 0x07, 0x03, 0x05, 0x00, 0x10, 0x00, 0x00, 49 | 0x00 50 | ]) 51 | .unwrap() 52 | .1 53 | ) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/tgs_req.rs: -------------------------------------------------------------------------------- 1 | use red_asn1::{SequenceOf, Asn1Object}; 2 | use red_asn1_derive::Sequence; 3 | use crate::{Int32, PaData, KdcReqBody, KdcReq}; 4 | 5 | /// (*TGS-REQ*) Message used to request a TGS. 6 | /// ```asn1 7 | /// TGS-REQ ::= [APPLICATION 12] KDC-REQ 8 | /// 9 | /// KDC-REQ ::= SEQUENCE { 10 | /// -- NOTE: first tag is [1], not [0] 11 | /// pvno [1] INTEGER (5) , 12 | /// msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), 13 | /// padata [3] SEQUENCE OF PA-DATA OPTIONAL 14 | /// -- NOTE: not empty --, 15 | /// req-body [4] KDC-REQ-BODY 16 | /// } 17 | /// ``` 18 | 19 | #[derive(Sequence, Debug, PartialEq, Clone)] 20 | #[seq(application_tag = 12)] 21 | pub struct TgsReq { 22 | #[seq_field(context_tag = 1)] 23 | pub pvno: Int32, 24 | #[seq_field(context_tag = 2)] 25 | pub msg_type: Int32, 26 | #[seq_field(context_tag = 3)] 27 | pub padata: Option>, 28 | #[seq_field(context_tag = 4)] 29 | pub req_body: KdcReqBody, 30 | } 31 | 32 | impl Default for TgsReq { 33 | fn default() -> Self { 34 | return Self { 35 | pvno: 5, 36 | msg_type: 12, 37 | padata: Option::default(), 38 | req_body: KdcReqBody::default() 39 | } 40 | } 41 | } 42 | 43 | impl From for TgsReq { 44 | fn from(req: KdcReq) -> Self { 45 | Self { 46 | pvno: req.pvno, 47 | msg_type: 12, 48 | padata: req.padata, 49 | req_body: req.req_body 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_ccache/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Types used to store Kerberos credentials in a ccache 2 | //! 3 | //! # Example 4 | //! Load and save into a file: 5 | //! ```no_run 6 | //! use kerberos_ccache::CCache; 7 | //! use std::fs; 8 | //! 9 | //! let data = fs::read("./bob_tgt.ccache").expect("Unable to read file"); 10 | //! 11 | //! let ccache = CCache::parse(&data) 12 | //! .expect("Unable to parse file content") 13 | //! .1; 14 | //! 15 | //! let data_2 = ccache.build(); 16 | //! fs::write("./bob_tgt2.ccache", data_2).expect("Unable to write file"); 17 | //! ``` 18 | //! # References 19 | //! * [ccache definition](https://web.mit.edu/kerberos/krb5-1.12/doc/basic/ccache_def.html) 20 | //! * [ccache types definition](https://repo.or.cz/w/krb5dissect.git/blob_plain/HEAD:/ccache.txt) 21 | //! * [keytab definition](https://web.mit.edu/kerberos/www/krb5-latest/doc/formats/keytab_file_format.html) 22 | //! * [keytab types definition](https://repo.or.cz/w/krb5dissect.git/blob_plain/HEAD:/keytab.txt) 23 | //! 24 | //! 25 | 26 | mod header; 27 | pub use header::*; 28 | 29 | mod counted_octet_string; 30 | pub use counted_octet_string::*; 31 | 32 | mod principal; 33 | pub use principal::*; 34 | 35 | mod key_block; 36 | pub use key_block::*; 37 | 38 | mod times; 39 | pub use times::*; 40 | 41 | mod address; 42 | pub use address::*; 43 | 44 | mod auth_data; 45 | pub use auth_data::*; 46 | 47 | mod credential; 48 | pub use credential::*; 49 | 50 | mod ccache; 51 | pub use ccache::*; 52 | 53 | pub use nom::Err as Error; 54 | pub use nom::IResult as Result; 55 | 56 | pub mod mappers; 57 | 58 | mod error; 59 | pub use error::{ConvertResult, ConvertError}; 60 | 61 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1/src/tag/tagclass.rs: -------------------------------------------------------------------------------- 1 | use std::fmt; 2 | 3 | /// Enum with the different tag classes 4 | /// * Universal: basic common types that are the same in all applications, defined in X.208 (all defined in this library are of this type) 5 | /// * Application: types specific to an application (custom types) 6 | /// * Context: types which depends on context, as sequence fields 7 | /// * Private: types specific to an enterprise 8 | #[derive(Debug, PartialEq, Copy, Clone)] 9 | pub enum TagClass { 10 | Universal = 0b00, 11 | Application = 0b01, 12 | Context = 0b10, 13 | Private = 0b11 14 | } 15 | 16 | 17 | impl From for TagClass { 18 | fn from(u: u8) -> TagClass { 19 | match u & 0x03 { 20 | 0b00 => TagClass::Universal, 21 | 0b01 => TagClass::Application, 22 | 0b10 => TagClass::Context, 23 | 0b11 => TagClass::Private, 24 | _ => unreachable!() 25 | } 26 | } 27 | } 28 | 29 | impl fmt::Display for TagClass { 30 | 31 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 32 | match self { 33 | TagClass::Universal => { 34 | write!(f, "universal") 35 | } 36 | TagClass::Application => { 37 | write!(f, "application") 38 | } 39 | TagClass::Context => { 40 | write!(f, "context") 41 | } 42 | TagClass::Private => { 43 | write!(f, "private") 44 | } 45 | } 46 | 47 | } 48 | 49 | } 50 | 51 | impl Default for TagClass { 52 | fn default() -> Self { 53 | return Self::Universal; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/algorithms/rc4_hmac_md5/encrypt.rs: -------------------------------------------------------------------------------- 1 | use crate::cryptography::{hmac_md5, rc4_decrypt, rc4_encrypt}; 2 | use crate::{Error, Result}; 3 | 4 | 5 | /// Encrypt plaintext by using the RC4 algorithm with HMAC-MD5 6 | pub fn encrypt( 7 | key: &[u8], 8 | key_usage: i32, 9 | timestamp: &[u8], 10 | preamble: &[u8], 11 | ) -> Vec { 12 | let mut plaintext: Vec = Vec::new(); 13 | plaintext.append(&mut preamble.to_vec()); 14 | plaintext.append(&mut timestamp.to_vec()); 15 | 16 | let ki = hmac_md5(key, &key_usage.to_le_bytes()); 17 | let mut cksum = hmac_md5(&ki, &plaintext); 18 | let ke = hmac_md5(&ki, &cksum); 19 | 20 | let mut enc = rc4_encrypt(&ke, &plaintext); 21 | 22 | cksum.append(&mut enc); 23 | 24 | return cksum; 25 | } 26 | 27 | /// Decrypt ciphertext by using the RC4 algorithm with HMAC-MD5 28 | pub fn decrypt( 29 | key: &[u8], 30 | key_usage: i32, 31 | ciphertext: &[u8], 32 | ) -> Result> { 33 | if ciphertext.len() < 24 { 34 | return Err(Error::DecryptionError( 35 | "Ciphertext too short".to_string(), 36 | ))?; 37 | } 38 | 39 | let cksum = &ciphertext[0..16]; 40 | let basic_ciphertext = &ciphertext[16..]; 41 | let ki = hmac_md5(key, &key_usage.to_le_bytes()); 42 | let ke = hmac_md5(&ki, &cksum); 43 | let plaintext = rc4_decrypt(&ke, &basic_ciphertext); 44 | 45 | let plaintext_cksum = hmac_md5(&ki, &plaintext); 46 | 47 | if cksum != &plaintext_cksum[..] { 48 | return Err(Error::DecryptionError( 49 | "Hmac integrity failure".to_string(), 50 | ))?; 51 | } 52 | 53 | return Ok(plaintext[8..].to_vec()); 54 | } 55 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/credentials/file.rs: -------------------------------------------------------------------------------- 1 | use super::credential_warehouse::*; 2 | use crate::{Result, Error}; 3 | use std::fs::File; 4 | use std::io::Write; 5 | use kerberos_ccache::CCache; 6 | use kerberos_asn1::Asn1Object; 7 | 8 | pub struct CredentialFileConverter<'a> { 9 | credentials: &'a CredentialWarehouse, 10 | path: &'a str, 11 | } 12 | 13 | impl<'a> CredentialFileConverter<'a> { 14 | pub fn save_into_krb_cred_file( 15 | credentials: &'a CredentialWarehouse, 16 | path: &'a str, 17 | ) -> Result<()> { 18 | let converter = Self::new(credentials, path); 19 | let data = converter.build_krb_cred(); 20 | return converter.save_data_to_file(&data); 21 | } 22 | 23 | pub fn save_into_ccache_file( 24 | credentials: &'a CredentialWarehouse, 25 | path: &'a str, 26 | ) -> Result<()> { 27 | let converter = Self::new(credentials, path); 28 | let data = converter.build_ccache(); 29 | return converter.save_data_to_file(&data); 30 | } 31 | 32 | fn new(credentials: &'a CredentialWarehouse, path: &'a str) -> Self { 33 | return Self { credentials, path }; 34 | } 35 | 36 | fn save_data_to_file(&self, data: &[u8]) -> Result<()> { 37 | let mut fp = File::create(self.path).map_err(|_| Error::IOError)?; 38 | 39 | fp.write_all(data).map_err(|_| Error::IOError)?; 40 | 41 | return Ok(()); 42 | } 43 | 44 | fn build_krb_cred(&self) -> Vec { 45 | return self.credentials.into_krb_cred().build(); 46 | } 47 | 48 | fn build_ccache(&self) -> Vec { 49 | let ccache: CCache = self.credentials.clone().into(); 50 | return ccache.build(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /third_party/kerbeiros/README.md: -------------------------------------------------------------------------------- 1 | # Kerbeiros 2 | 3 | Kerberos client 4 | 5 | ## Concepts 6 | * KDC (Key Distribution Center): Service that distributes the tickets. The host that provides this server is also called KDC. 7 | * TGS (Ticket Granting Server): Ticket used to authenticate the user against a specified service. 8 | * TGT (Ticket Granting Ticket): Ticket used to retrieve the TGS's from the KDC. 9 | 10 | ## Examples 11 | 12 | Asking for a TGT: 13 | 14 | ```rust 15 | use kerbeiros::*; 16 | use ascii::AsciiString; 17 | use std::net::*; 18 | 19 | // Prepare the arguments 20 | let realm = AsciiString::from_ascii("CONTOSO.COM").unwrap(); 21 | let kdc_address = IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)); 22 | let username = AsciiString::from_ascii("Bob").unwrap(); 23 | let user_key = Key::Password("S3cr3t".to_string()); 24 | 25 | // Request the TGT 26 | let tgt_requester = TgtRequester::new(realm, kdc_address); 27 | let credential = tgt_requester.request(&username, Some(&user_key)).unwrap(); 28 | 29 | // Save the ticket into a Windows format file 30 | credential.save_into_krb_cred_file("bob_tgt.krb").unwrap(); 31 | 32 | // Save the ticket into a Linux format file 33 | credential.save_into_ccache_file("bob_tgt.ccache").unwrap(); 34 | ``` 35 | 36 | 37 | ## Development 38 | 39 | ### Code style 40 | 41 | Follow the [rustfmt](https://github.com/rust-lang/rustfmt) code style. 42 | 43 | To format code: 44 | ``` 45 | cargo fmt 46 | ``` 47 | 48 | ### Test 49 | To run tests: 50 | ``` 51 | cargo test 52 | ``` 53 | 54 | 55 | ## References 56 | * [RFC 4120: The Kerberos Network Authentication Service (V5)](https://tools.ietf.org/html/rfc4120) 57 | * [\[MS-KILE\]: Kerberos Protocol Extensions](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-kile) 58 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_ccache/src/error.rs: -------------------------------------------------------------------------------- 1 | //! Errors raised by this library 2 | 3 | use failure::Fail; 4 | use std::result; 5 | use std::string::FromUtf8Error; 6 | use kerberos_asn1; 7 | 8 | /// Result to wrap kerbeiros error. 9 | pub type ConvertResult = result::Result; 10 | 11 | /// Type of error in kerbeiros library. 12 | #[derive(Clone, PartialEq, Debug, Fail)] 13 | pub enum ConvertError { 14 | /// Error handlening asn1 entities. 15 | #[fail(display = "Asn1 error: {}", _0)] 16 | Asn1Error(kerberos_asn1::Error), 17 | 18 | /// Invalid ascii string. 19 | #[fail(display = "Invalid ascii string")] 20 | InvalidAscii, 21 | 22 | /// Invalid utf8 string. 23 | #[fail(display = "Invalid utf8 string")] 24 | FromUtf8Error, 25 | 26 | /// No principal name 27 | #[fail(display = "No principal name found")] 28 | NoPrincipalName, 29 | 30 | /// No address found 31 | #[fail(display = "No address found")] 32 | NoAddress, 33 | 34 | /// Error parsing binary data 35 | #[fail(display = "Error parsing binary data")] 36 | BinaryParseError, 37 | 38 | 39 | /// The parsed struct doesn't have a required field. 40 | /// This could be due a Option field which is None. 41 | #[fail(display = "A required field is missing: {}", _0)] 42 | MissingField(String), 43 | 44 | #[fail(display = "KrbCredError: {}", _0)] 45 | KrbCredError(String) 46 | } 47 | 48 | 49 | impl From for ConvertError { 50 | fn from(_error: FromUtf8Error) -> Self { 51 | return Self::FromUtf8Error; 52 | } 53 | } 54 | 55 | impl From for ConvertError { 56 | fn from(error: kerberos_asn1::Error) -> Self { 57 | return Self::Asn1Error(error); 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/mappers/octet_string_mapper.rs: -------------------------------------------------------------------------------- 1 | use crate::error; 2 | use kerberos_asn1::KerberosString; 3 | use kerberos_ccache::CountedOctetString; 4 | 5 | pub struct CountedOctetStringMapper {} 6 | 7 | impl CountedOctetStringMapper { 8 | pub fn kerberos_string_to_counted_octet_string( 9 | kerberos_string: &KerberosString, 10 | ) -> CountedOctetString { 11 | return CountedOctetString::new(kerberos_string.as_bytes().to_vec()) 12 | } 13 | 14 | pub fn counted_octet_string_to_kerberos_string( 15 | counted_octet_string: CountedOctetString, 16 | ) -> error::Result { 17 | return Ok(KerberosString::from_utf8(counted_octet_string.data)?); 18 | } 19 | } 20 | 21 | #[cfg(test)] 22 | mod test { 23 | use super::*; 24 | 25 | #[test] 26 | fn test_kerberos_string_to_counted_octet_string() { 27 | let cos_string = CountedOctetStringMapper::kerberos_string_to_counted_octet_string( 28 | &KerberosString::from("ABC") 29 | ); 30 | 31 | assert_eq!(CountedOctetString::from("ABC"), cos_string); 32 | } 33 | 34 | #[test] 35 | fn test_counted_octet_string_to_kerberos_string() { 36 | let k_string: KerberosString = CountedOctetStringMapper::counted_octet_string_to_kerberos_string( 37 | CountedOctetString::from("ABC") 38 | ).unwrap(); 39 | 40 | assert_eq!(KerberosString::from("ABC"), k_string) 41 | } 42 | 43 | #[test] 44 | #[should_panic(expected = "InvalidUtf8")] 45 | fn test_counted_octet_string_to_kerberos_string_fail() { 46 | CountedOctetStringMapper::counted_octet_string_to_kerberos_string( 47 | CountedOctetString::new(vec![0xff]) 48 | ).unwrap(); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /tools/xbeeprom/src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::{App, Arg, ArgMatches, SubCommand}; 2 | 3 | use std::fs; 4 | use std::io::{self, Read}; 5 | use std::path::Path; 6 | use std::process::exit; 7 | 8 | fn main() { 9 | let matches = App::new("xbeeprom") 10 | .version("0.1.0") 11 | .about("Tool for inspecting and manipulating xbox eeprom images") 12 | .subcommand(SubCommand::with_name("info") 13 | .about("Print information about given eeprom") 14 | .arg(Arg::with_name("INPUT") 15 | .help("Set the filename of the eeprom to use") 16 | .required(true) 17 | .index(1))) 18 | .get_matches(); 19 | 20 | match matches.subcommand() { 21 | ("info", Some(matches)) => info_subcommand(matches), 22 | _ => { 23 | match matches.subcommand_name() { 24 | Some(name) => eprintln!("Error: Unknown subcommand: \"{}\"", name), 25 | None => eprintln!("Error: No subcommand given"), 26 | } 27 | eprintln!("{}", matches.usage()); 28 | exit(1); 29 | } 30 | } 31 | } 32 | 33 | 34 | fn info_subcommand<'a>(matches: &ArgMatches<'a>) { 35 | let input_filename = matches.value_of("INPUT").unwrap(); 36 | 37 | let file = read_file_to_buffer(input_filename).unwrap(); 38 | 39 | let eeprom = xbox_sys::eeprom::Eeprom::from_buf(&file).unwrap(); 40 | 41 | println!("Serial Number: {}", eeprom.serial_number()); 42 | println!("MAC Address: {}", eeprom.mac_address()); 43 | println!("Online Key: {}", eeprom.online_key()); 44 | } 45 | 46 | fn read_file_to_buffer>(path: P) -> io::Result> { 47 | let mut buf = vec![]; 48 | let mut file = fs::File::open(path)?; 49 | file.read_to_end(&mut buf)?; 50 | 51 | Ok(buf) 52 | } 53 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/kdc_req.rs: -------------------------------------------------------------------------------- 1 | use red_asn1::{SequenceOf, Asn1Object}; 2 | use red_asn1_derive::Sequence; 3 | use crate::{Int32, PaData, KdcReqBody}; 4 | use crate::{AsReq, TgsReq}; 5 | 6 | /// (*KDC-REQ*) Base for AS-REQ and TGS-REQ 7 | /// ```asn1 8 | /// 9 | /// KDC-REQ ::= SEQUENCE { 10 | /// -- NOTE: first tag is [1], not [0] 11 | /// pvno [1] INTEGER (5) , 12 | /// msg-type [2] INTEGER (10 -- AS -- | 12 -- TGS --), 13 | /// padata [3] SEQUENCE OF PA-DATA OPTIONAL 14 | /// -- NOTE: not empty --, 15 | /// req-body [4] KDC-REQ-BODY 16 | /// } 17 | /// ``` 18 | 19 | #[derive(Sequence, Debug, PartialEq, Clone)] 20 | pub struct KdcReq { 21 | #[seq_field(context_tag = 1)] 22 | pub pvno: Int32, 23 | #[seq_field(context_tag = 2)] 24 | pub msg_type: Int32, 25 | #[seq_field(context_tag = 3)] 26 | pub padata: Option>, 27 | #[seq_field(context_tag = 4)] 28 | pub req_body: KdcReqBody, 29 | } 30 | 31 | impl Default for KdcReq { 32 | fn default() -> Self { 33 | return Self { 34 | pvno: 5, 35 | msg_type: Int32::default(), 36 | padata: Option::default(), 37 | req_body: KdcReqBody::default() 38 | } 39 | } 40 | } 41 | 42 | impl From for KdcReq { 43 | fn from(req: AsReq) -> Self { 44 | Self { 45 | pvno: req.pvno, 46 | msg_type: req.msg_type, 47 | padata: req.padata, 48 | req_body: req.req_body 49 | } 50 | } 51 | } 52 | 53 | impl From for KdcReq { 54 | fn from(req: TgsReq) -> Self { 55 | Self { 56 | pvno: req.pvno, 57 | msg_type: req.msg_type, 58 | padata: req.padata, 59 | req_body: req.req_body 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_ccache/src/mappers/ticket_flags_mapper.rs: -------------------------------------------------------------------------------- 1 | use kerberos_asn1::TicketFlags; 2 | 3 | pub fn ticket_flags_to_tktflags(ticket_flags: &TicketFlags) -> u32 { 4 | return **ticket_flags; 5 | } 6 | pub fn tktflags_to_ticket_flags(tktflags: u32) -> TicketFlags { 7 | return TicketFlags::from(tktflags); 8 | } 9 | 10 | #[cfg(test)] 11 | mod test { 12 | use super::*; 13 | use kerberos_constants::ticket_flags; 14 | 15 | #[test] 16 | fn test_ticket_flags_to_tktflags() { 17 | let ticket_flags = TicketFlags::from( 18 | ticket_flags::FORWARDABLE 19 | | ticket_flags::PROXIABLE 20 | | ticket_flags::RENEWABLE 21 | | ticket_flags::INITIAL 22 | | ticket_flags::PRE_AUTHENT, 23 | ); 24 | 25 | let tktflags = ticket_flags::FORWARDABLE 26 | | ticket_flags::PROXIABLE 27 | | ticket_flags::RENEWABLE 28 | | ticket_flags::INITIAL 29 | | ticket_flags::PRE_AUTHENT; 30 | 31 | assert_eq!( 32 | tktflags, 33 | ticket_flags_to_tktflags(&ticket_flags) 34 | ); 35 | } 36 | 37 | #[test] 38 | fn test_tktflags_to_ticket_flags() { 39 | let ticket_flags = TicketFlags::from( 40 | ticket_flags::FORWARDABLE 41 | | ticket_flags::PROXIABLE 42 | | ticket_flags::RENEWABLE 43 | | ticket_flags::INITIAL 44 | | ticket_flags::PRE_AUTHENT, 45 | ); 46 | 47 | let tktflags = ticket_flags::FORWARDABLE 48 | | ticket_flags::PROXIABLE 49 | | ticket_flags::RENEWABLE 50 | | ticket_flags::INITIAL 51 | | ticket_flags::PRE_AUTHENT; 52 | 53 | assert_eq!( 54 | ticket_flags, 55 | tktflags_to_ticket_flags(tktflags) 56 | ); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/last_req.rs: -------------------------------------------------------------------------------- 1 | use crate::{Int32, KerberosTime}; 2 | use red_asn1::{Asn1Object, SequenceOf}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*LastReq*) Register of time of a request to KDC. 6 | /// Defined in RFC4120, 5.4.2. 7 | /// ```asn1 8 | /// LastReq ::= SEQUENCE OF SEQUENCE { 9 | /// lr-type [0] Int32, 10 | /// lr-value [1] KerberosTime 11 | /// } 12 | /// ``` 13 | pub type LastReq = SequenceOf; 14 | 15 | 16 | /// Entry of *LastReq*. 17 | /// Pseudotype defined in this library. 18 | /// Defined in RFC4120, 5.4.2. 19 | /// ```asn1 20 | /// LastReq ::= SEQUENCE OF SEQUENCE { 21 | /// lr-type [0] Int32, 22 | /// lr-value [1] KerberosTime 23 | /// } 24 | /// ``` 25 | #[derive(Sequence, Default, Debug, PartialEq, Clone)] 26 | pub struct LastReqEntry { 27 | #[seq_field(context_tag = 0)] 28 | pub lr_type: Int32, 29 | #[seq_field(context_tag = 1)] 30 | pub lr_value: KerberosTime, 31 | } 32 | 33 | impl LastReqEntry { 34 | pub fn new(lr_type: Int32, lr_value: KerberosTime) -> Self { 35 | return Self { lr_type, lr_value }; 36 | } 37 | } 38 | 39 | #[cfg(test)] 40 | mod test { 41 | use super::*; 42 | use chrono::prelude::*; 43 | 44 | #[test] 45 | fn test_parse_last_req() { 46 | let raw: Vec = vec![ 47 | 0x30, 0x1a, 0x30, 0x18, 0xa0, 0x03, 0x02, 0x01, 0x00, 0xa1, 0x11, 48 | 0x18, 0x0f, 0x32, 0x30, 0x31, 0x39, 0x30, 0x34, 0x31, 0x38, 0x30, 49 | 0x36, 0x30, 0x30, 0x33, 0x31, 0x5a, 50 | ]; 51 | 52 | let last_req = vec![LastReqEntry { 53 | lr_type: 0, 54 | lr_value: KerberosTime::from( 55 | Utc.ymd(2019, 4, 18).and_hms(06, 00, 31), 56 | ), 57 | }]; 58 | 59 | assert_eq!(last_req, LastReq::parse(&raw).unwrap().1); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/kerb_pa_pac_request.rs: -------------------------------------------------------------------------------- 1 | use red_asn1::Asn1Object; 2 | use red_asn1_derive::Sequence; 3 | 4 | /// (*KERB-PA-PAC-REQUEST*) To indicate if PAC should be included in response. 5 | /// Defined in MS-KILE, section 2.2.3. 6 | /// ```asn1 7 | /// KERB-PA-PAC-REQUEST ::= SEQUENCE { 8 | /// include-pac[0] BOOLEAN --If TRUE, and no pac present, include PAC. 9 | /// --If FALSE, and PAC present, remove PAC 10 | /// } 11 | 12 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 13 | pub struct KerbPaPacRequest { 14 | #[seq_field(context_tag = 0)] 15 | pub include_pac: bool, 16 | } 17 | 18 | impl KerbPaPacRequest { 19 | pub fn new(include_pac: bool) -> Self { 20 | return Self { include_pac }; 21 | } 22 | } 23 | 24 | #[cfg(test)] 25 | mod test { 26 | use super::*; 27 | 28 | #[test] 29 | fn test_encode_pac_request_true() { 30 | assert_eq!( 31 | vec![0x30, 0x05, 0xa0, 0x03, 0x01, 0x01, 0xff], 32 | KerbPaPacRequest::new(true).build() 33 | ); 34 | } 35 | 36 | #[test] 37 | fn test_encode_pac_request_false() { 38 | assert_eq!( 39 | vec![0x30, 0x05, 0xa0, 0x03, 0x01, 0x01, 0x00], 40 | KerbPaPacRequest::new(false).build() 41 | ); 42 | } 43 | 44 | #[test] 45 | fn test_decode_pac_request_true() { 46 | assert_eq!( 47 | KerbPaPacRequest::new(true), 48 | KerbPaPacRequest::parse(&[0x30, 0x05, 0xa0, 0x03, 0x01, 0x01, 0xff]) 49 | .unwrap() 50 | .1 51 | ); 52 | } 53 | 54 | #[test] 55 | fn test_decode_pac_request_false() { 56 | assert_eq!( 57 | KerbPaPacRequest::new(false), 58 | KerbPaPacRequest::parse(&[0x30, 0x05, 0xa0, 0x03, 0x01, 0x01, 0x00]) 59 | .unwrap() 60 | .1 61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /libs/xbox-sys/src/eeprom.rs: -------------------------------------------------------------------------------- 1 | use crate::crypto::SYMMETRIC_KEY_LEN; 2 | use crate::std::convert::TryInto; 3 | 4 | use crate::config::*; 5 | use crate::crypto::SymmetricKey; 6 | 7 | pub const LEN: usize = 256; 8 | 9 | pub const SERIAL_NUBMER_OFFSET: usize = 0x34; 10 | pub const SERIAL_NUBMER_END: usize = SERIAL_NUBMER_OFFSET + SERIAL_NUBMER_LEN; 11 | 12 | pub const MAC_ADDRESS_OFFSET: usize = 0x40; 13 | pub const MAC_ADDRESS_END: usize = MAC_ADDRESS_OFFSET + MAC_ADDRESS_LEN; 14 | 15 | pub const ONLINE_KEY_OFFSET: usize = 0x48; 16 | pub const ONLINE_KEY_END: usize = ONLINE_KEY_OFFSET + SYMMETRIC_KEY_LEN; 17 | 18 | #[derive(Debug)] 19 | pub struct Eeprom { 20 | bytes: [u8;LEN], 21 | } 22 | 23 | #[derive(Debug, PartialEq)] 24 | pub enum EepromNewError { 25 | InccorectBufferSize 26 | } 27 | 28 | impl Eeprom { 29 | pub fn from_buf(buf: &[u8]) -> Result { 30 | if buf.len() != LEN { 31 | return Err(EepromNewError::InccorectBufferSize) 32 | } 33 | 34 | Ok(Eeprom { 35 | // Unwrap is ok because above len check 36 | bytes: buf.try_into().unwrap(), 37 | }) 38 | } 39 | 40 | pub fn mac_address(&self) -> MacAddress { 41 | MacAddress( 42 | // Unwrap ok, because fixed size buffer in src and dst 43 | self.bytes[MAC_ADDRESS_OFFSET..MAC_ADDRESS_END].try_into().unwrap(), 44 | ) 45 | } 46 | 47 | pub fn serial_number(&self) -> SerialNumber { 48 | SerialNumber( 49 | // Unwrap ok, because fixed size buffer in src and dst 50 | self.bytes[SERIAL_NUBMER_OFFSET..SERIAL_NUBMER_END].try_into().unwrap(), 51 | ) 52 | } 53 | 54 | pub fn online_key(&self) -> SymmetricKey { 55 | SymmetricKey( 56 | // Unwrap ok, because fixed size buffer in src and dst 57 | self.bytes[ONLINE_KEY_OFFSET..ONLINE_KEY_END].try_into().unwrap(), 58 | ) 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/utils.rs: -------------------------------------------------------------------------------- 1 | //! Useful internal functions 2 | 3 | use rand::RngCore; 4 | 5 | 6 | /// Generates an vector with random bytes 7 | pub fn random_bytes(size: usize) -> Vec { 8 | let mut rng = rand::thread_rng(); 9 | let mut bytes: Vec = vec![0; size]; 10 | rng.fill_bytes(&mut bytes); 11 | 12 | return bytes; 13 | } 14 | 15 | /// Helper to xorbytes of two arrays and produce a new one 16 | pub fn xorbytes(v1: &[u8], v2: &[u8]) -> Vec { 17 | let mut v_xored = Vec::with_capacity(v1.len()); 18 | 19 | for i in 0..v1.len() { 20 | v_xored.push(v1[i] ^ v2[i]) 21 | } 22 | 23 | return v_xored; 24 | } 25 | 26 | 27 | pub fn string_unicode_bytes(s: &str) -> Vec { 28 | let s_utf16: Vec = s.encode_utf16().collect(); 29 | return u16_array_to_le_bytes(&s_utf16); 30 | } 31 | 32 | pub fn u16_array_to_le_bytes(u16_array: &[u16]) -> Vec { 33 | let mut u8_vec: Vec = Vec::with_capacity(u16_array.len() * 2); 34 | 35 | for u16_item in u16_array.iter() { 36 | let u8_min = *u16_item as u8; 37 | let u8_max = (*u16_item >> 8) as u8; 38 | 39 | u8_vec.push(u8_min); 40 | u8_vec.push(u8_max); 41 | } 42 | 43 | return u8_vec; 44 | } 45 | 46 | #[cfg(test)] 47 | mod tests { 48 | use super::*; 49 | 50 | #[test] 51 | fn test_u16_array_to_le_bytes() { 52 | assert_eq!(vec![0, 0], u16_array_to_le_bytes(&[0])); 53 | assert_eq!(vec![1, 0], u16_array_to_le_bytes(&[1])); 54 | assert_eq!( 55 | vec![9, 0, 8, 0, 7, 0, 6, 0], 56 | u16_array_to_le_bytes(&[9, 8, 7, 6]) 57 | ); 58 | assert_eq!(vec![0x15, 0x03], u16_array_to_le_bytes(&[789])); 59 | assert_eq!(vec![0x00, 0x01], u16_array_to_le_bytes(&[256])); 60 | assert_eq!( 61 | vec![0xd2, 0x04, 0xa5, 0x03, 0xbe, 0x6c], 62 | u16_array_to_le_bytes(&[1234, 933, 27838]) 63 | ); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /libs/xblive/src/krb.rs: -------------------------------------------------------------------------------- 1 | use kerberos_asn1::PrincipalName; 2 | use kerberos_constants::*; 3 | 4 | pub mod service; 5 | 6 | pub const PA_MSKILE_COMPOUND_IDENTITY: i32 = 130; 7 | pub const PA_MSKILE_FOR_CHECK_DUPS: i32 = 131; 8 | pub const PA_XBOX_SERVICE_REQUEST: i32 = 201; 9 | pub const PA_XBOX_SERVICE_ADDRESS: i32 = 202; 10 | pub const PA_XBOX_ACCOUNT_CREATION: i32 = 203; 11 | pub const PA_XBOX_PPA: i32 = 204; 12 | pub const PA_XBOX_CLIENT_VERSION: i32 = 206; 13 | 14 | pub const ENC_NONCE_MACHINE_ACCOUNT: u32 = 1203; 15 | 16 | pub const MACS_DOMAIN: &str = "MACS.XBOX.COM"; 17 | pub const MACS_REALM: &str = "MACS.XBOX.COM"; 18 | 19 | pub fn macs_sname() -> PrincipalName { 20 | PrincipalName { 21 | name_type: principal_names::NT_SRV_INST, 22 | name_string: vec![ "krbtgt".to_owned(), MACS_DOMAIN.to_owned() ], 23 | } 24 | } 25 | 26 | pub const AS_TGS_DOMAIN: &str = "XBOX.COM"; 27 | pub const AS_TGS_REALM: &str = "XBOX.COM"; 28 | 29 | pub fn as_tgs_sname() -> PrincipalName { 30 | PrincipalName { 31 | name_type: principal_names::NT_SRV_INST, 32 | name_string: vec![ "krbtgt".to_owned(), AS_TGS_DOMAIN.to_owned() ], 33 | } 34 | } 35 | 36 | pub fn gamertag_from_cname(cname: &PrincipalName, domains: &[&'static str]) -> Option<(String, &'static str)> { 37 | if cname.name_type != principal_names::NT_ENTERPRISE { 38 | return None; 39 | } 40 | 41 | if cname.name_string.len() != 1 { 42 | return None; 43 | } 44 | 45 | let mut name = cname.name_string[0].clone(); 46 | 47 | let domain = domain_matches_name(&name, domains)?; 48 | 49 | for _ in 0..domain.len() { 50 | name.pop(); 51 | } 52 | 53 | Some((name, domain)) 54 | } 55 | 56 | fn domain_matches_name<'a>(name: &str, domains: &[&'a str]) -> Option<&'a str> { 57 | for domain in domains { 58 | if name.ends_with(domain) { 59 | return Some(domain) 60 | } 61 | } 62 | 63 | None 64 | } -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Kerberos client 2 | //! 3 | //! # Concepts 4 | //! * KDC (Key Distribution Center): Service that distributes the tickets. The host that provides this server is also called KDC. 5 | //! * TGS (Ticket Granting Server): Ticket used to authenticate the user against a specified service. 6 | //! * TGT (Ticket Granting Ticket): Ticket used to retrieve the TGS's from the KDC. 7 | //! 8 | //! # Examples 9 | //! 10 | //! Asking for a TGT: 11 | //! 12 | //! ```no_run 13 | //! use kerbeiros::*; 14 | //! use ascii::AsciiString; 15 | //! use std::net::*; 16 | //! use kerberos_crypto::Key; 17 | //! 18 | //! // Prepare the arguments 19 | //! let realm = AsciiString::from_ascii("CONTOSO.COM").unwrap(); 20 | //! let kdc_address = IpAddr::V4(Ipv4Addr::new(192, 168, 0, 1)); 21 | //! let username = AsciiString::from_ascii("Bob").unwrap(); 22 | //! let user_key = Key::Secret("S3cr3t".to_string()); 23 | //! 24 | //! // Request the TGT 25 | //! let tgt_requester = TgtRequester::new(realm, kdc_address); 26 | //! let credential = tgt_requester.request(&username, Some(&user_key)).unwrap(); 27 | //! 28 | //! // Save the ticket into a Windows format file 29 | //! credential.clone().save_into_krb_cred_file("bob_tgt.krb").unwrap(); 30 | //! 31 | //! // Save the ticket into a Linux format file 32 | //! credential.save_into_ccache_file("bob_tgt.ccache").unwrap(); 33 | //! ``` 34 | //! 35 | //! # Kerberos References 36 | //! * [RFC 4120: The Kerberos Network Authentication Service (V5)](https://tools.ietf.org/html/rfc4120) 37 | //! * [\[MS-KILE\]: Kerberos Protocol Extensions](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-kile) 38 | //! 39 | 40 | mod transporter; 41 | 42 | mod error; 43 | pub use error::{Result, Error}; 44 | 45 | pub mod messages; 46 | pub use messages::*; 47 | 48 | pub mod credentials; 49 | pub use credentials::*; 50 | 51 | pub mod requesters; 52 | pub use requesters::*; 53 | 54 | pub mod utils; 55 | pub use utils::*; 56 | 57 | mod mappers; 58 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/tgs_rep.rs: -------------------------------------------------------------------------------- 1 | use crate::{EncryptedData, Int32, PaData, PrincipalName, Realm, Ticket}; 2 | use red_asn1::{Asn1Object, SequenceOf}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*TGS-REP*) Message returned by KDC in response to TGS-REQ. 6 | /// ```asn1 7 | /// TGS-REP ::= [APPLICATION 13] KDC-REP 8 | /// 9 | /// KDC-REP ::= SEQUENCE { 10 | /// pvno [0] INTEGER (5), 11 | /// msg-type [1] INTEGER (11 -- AS -- | 13 -- TGS --), 12 | /// padata [2] SEQUENCE OF PA-DATA OPTIONAL 13 | /// -- NOTE: not empty --, 14 | /// crealm [3] Realm, 15 | /// cname [4] PrincipalName, 16 | /// ticket [5] Ticket, 17 | /// enc-part [6] EncryptedData 18 | /// -- EncASRepPart or EncTGSRepPart, 19 | /// -- as appropriate 20 | /// } 21 | /// ``` 22 | #[derive(Sequence, Debug, Clone, PartialEq)] 23 | #[seq(application_tag = 13)] 24 | pub struct TgsRep { 25 | #[seq_field(context_tag = 0)] 26 | pub pvno: Int32, 27 | #[seq_field(context_tag = 1)] 28 | pub msg_type: Int32, 29 | #[seq_field(context_tag = 2)] 30 | pub padata: Option>, 31 | #[seq_field(context_tag = 3)] 32 | pub crealm: Realm, 33 | #[seq_field(context_tag = 4)] 34 | pub cname: PrincipalName, 35 | #[seq_field(context_tag = 5)] 36 | pub ticket: Ticket, 37 | #[seq_field(context_tag = 6)] 38 | pub enc_part: EncryptedData, 39 | } 40 | 41 | impl Default for TgsRep { 42 | fn default() -> Self { 43 | return Self { 44 | pvno: 5, 45 | msg_type: 13, 46 | padata: Option::default(), 47 | crealm: Realm::default(), 48 | cname: PrincipalName::default(), 49 | ticket: Ticket::default(), 50 | enc_part: EncryptedData::default(), 51 | }; 52 | } 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/krb_cred_info.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | EncryptionKey, HostAddresses, KerberosTime, PrincipalName, Realm, 3 | TicketFlags, 4 | }; 5 | use red_asn1::Asn1Object; 6 | use red_asn1_derive::Sequence; 7 | 8 | /// (*KrbCredInfo*) Information of the ticket sent in *EncKrbCredPart*. 9 | /// Defined in RFC4120, section 5.8.1. 10 | /// ```asn1 11 | /// KrbCredInfo ::= SEQUENCE { 12 | /// key [0] EncryptionKey, 13 | /// prealm [1] Realm OPTIONAL, 14 | /// pname [2] PrincipalName OPTIONAL, 15 | /// flags [3] TicketFlags OPTIONAL, 16 | /// authtime [4] KerberosTime OPTIONAL, 17 | /// starttime [5] KerberosTime OPTIONAL, 18 | /// endtime [6] KerberosTime OPTIONAL, 19 | /// renew-till [7] KerberosTime OPTIONAL, 20 | /// srealm [8] Realm OPTIONAL, 21 | /// sname [9] PrincipalName OPTIONAL, 22 | /// caddr [10] HostAddresses OPTIONAL 23 | /// } 24 | /// ``` 25 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 26 | pub struct KrbCredInfo { 27 | #[seq_field(context_tag = 0)] 28 | pub key: EncryptionKey, 29 | #[seq_field(context_tag = 1)] 30 | pub prealm: Option, 31 | #[seq_field(context_tag = 2)] 32 | pub pname: Option, 33 | #[seq_field(context_tag = 3)] 34 | pub flags: Option, 35 | #[seq_field(context_tag = 4)] 36 | pub authtime: Option, 37 | #[seq_field(context_tag = 5)] 38 | pub starttime: Option, 39 | #[seq_field(context_tag = 6)] 40 | pub endtime: Option, 41 | #[seq_field(context_tag = 7)] 42 | pub renew_till: Option, 43 | #[seq_field(context_tag = 8)] 44 | pub srealm: Option, 45 | #[seq_field(context_tag = 9)] 46 | pub sname: Option, 47 | #[seq_field(context_tag = 10)] 48 | pub caddr: Option, 49 | } 50 | -------------------------------------------------------------------------------- /libs/xbox-sys/src/fatx.rs: -------------------------------------------------------------------------------- 1 | use bytes::BufMut; 2 | 3 | use nom::number::complete::le_u32; 4 | 5 | use crate::codec::{BufPut, Decode, decode_array_u8, decode_array_le_u16}; 6 | 7 | pub const SECTOR_SIZE: usize = 512; 8 | 9 | pub const VOLUME_HEADER_BASE_BLOCK: u64 = 0; 10 | pub const VOLUME_HEADER_NUM_BLOCKS: usize = 5; 11 | 12 | #[derive(Debug)] 13 | #[repr(C)] 14 | pub struct VolumeHeader { 15 | pub signature: u32, 16 | pub serial_number: u32, 17 | pub sectors_per_cluster: u32, 18 | pub root_directory_first_cluster: u32, 19 | pub volume_name: [u16;16], 20 | pub unknown_30: [u8;0x20], 21 | pub mu_online_account_buf: [u8;0x6c], 22 | pub unknown_bc: [u8;0x774], 23 | } 24 | 25 | impl Decode for VolumeHeader { 26 | fn decode<'a>(input: &'a [u8]) -> nom::IResult<&'a [u8], Self> { 27 | let (input, signature) = le_u32(input)?; 28 | let (input, serial_number) = le_u32(input)?; 29 | let (input, sectors_per_cluster) = le_u32(input)?; 30 | let (input, root_directory_first_cluster) = le_u32(input)?; 31 | let (input, volume_name) = decode_array_le_u16(input)?; 32 | let (input, unknown_30) = decode_array_u8(input)?; 33 | let (input, mu_online_account_buf) = decode_array_u8(input)?; 34 | let (input, unknown_bc) = decode_array_u8(input)?; 35 | 36 | Ok((input, VolumeHeader { 37 | signature, 38 | serial_number, 39 | sectors_per_cluster, 40 | root_directory_first_cluster, 41 | volume_name, 42 | unknown_30, 43 | mu_online_account_buf, 44 | unknown_bc, 45 | })) 46 | } 47 | } 48 | 49 | impl BufPut for VolumeHeader { 50 | fn put(&self, buf: &mut AnyBufMut) { 51 | buf.put_u32_le(self.signature); 52 | buf.put_u32_le(self.serial_number); 53 | buf.put_u32_le(self.sectors_per_cluster); 54 | buf.put_u32_le(self.root_directory_first_cluster); 55 | for c in self.volume_name { 56 | buf.put_u16_le(c) 57 | } 58 | buf.put_slice(&self.unknown_30); 59 | buf.put_slice(&self.mu_online_account_buf); 60 | buf.put_slice(&self.unknown_bc); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/mappers/ticket_flags_mapper.rs: -------------------------------------------------------------------------------- 1 | use kerberos_asn1::TicketFlags; 2 | 3 | pub struct TicketFlagsMapper {} 4 | 5 | impl TicketFlagsMapper { 6 | pub fn ticket_flags_to_tktflags(ticket_flags: &TicketFlags) -> u32 { 7 | return **ticket_flags; 8 | } 9 | pub fn tktflags_to_ticket_flags(tktflags: u32) -> TicketFlags { 10 | return TicketFlags::from(tktflags); 11 | } 12 | } 13 | 14 | #[cfg(test)] 15 | mod test { 16 | use super::*; 17 | use kerberos_constants::ticket_flags; 18 | 19 | #[test] 20 | fn ticket_flags_to_tktflags() { 21 | let ticket_flags = TicketFlags::from( 22 | ticket_flags::FORWARDABLE 23 | | ticket_flags::PROXIABLE 24 | | ticket_flags::RENEWABLE 25 | | ticket_flags::INITIAL 26 | | ticket_flags::PRE_AUTHENT, 27 | ); 28 | 29 | let tktflags = ticket_flags::FORWARDABLE 30 | | ticket_flags::PROXIABLE 31 | | ticket_flags::RENEWABLE 32 | | ticket_flags::INITIAL 33 | | ticket_flags::PRE_AUTHENT; 34 | 35 | assert_eq!( 36 | tktflags, 37 | TicketFlagsMapper::ticket_flags_to_tktflags(&ticket_flags) 38 | ); 39 | } 40 | 41 | #[test] 42 | fn test_tktflags_to_ticket_flags() { 43 | let ticket_flags = TicketFlags::from( 44 | ticket_flags::FORWARDABLE 45 | | ticket_flags::PROXIABLE 46 | | ticket_flags::RENEWABLE 47 | | ticket_flags::INITIAL 48 | | ticket_flags::PRE_AUTHENT, 49 | ); 50 | 51 | let tktflags = ticket_flags::FORWARDABLE 52 | | ticket_flags::PROXIABLE 53 | | ticket_flags::RENEWABLE 54 | | ticket_flags::INITIAL 55 | | ticket_flags::PRE_AUTHENT; 56 | 57 | assert_eq!( 58 | ticket_flags, 59 | TicketFlagsMapper::tktflags_to_ticket_flags(tktflags) 60 | ); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /libs/xblive/src/sg/seq.rs: -------------------------------------------------------------------------------- 1 | use std::sync::atomic::AtomicU32; 2 | 3 | use xbox_sys::crypto::DesIv; 4 | 5 | #[derive(Clone, Copy, Debug, PartialEq)] 6 | pub struct SeqNum(pub u32); 7 | 8 | impl SeqNum { 9 | pub fn new(i: u32) -> Self { 10 | SeqNum(i) 11 | } 12 | 13 | pub fn from_high_low(high: u16, low: &[u8]) -> Self { 14 | Self( 15 | low[0] as u32 | ((low[1] as u32) << 8) | ((high as u32) << 16) 16 | ) 17 | } 18 | 19 | pub fn high_word(&self) -> u16 { 20 | (self.0 >> 16) as u16 21 | } 22 | 23 | pub fn high_low(&self) -> ([u8;2], [u8;2]) { 24 | let bytes = self.0.to_le_bytes(); 25 | 26 | ([bytes[2], bytes[3]], [bytes[0], bytes[1]]) 27 | } 28 | 29 | pub fn permute_iv(&self, orig_iv: DesIv) -> DesIv { 30 | const LOW_WORD_MASK: u64 = 0x00000000_FFFFFFFF; 31 | 32 | let seq_64 = self.0 as u64; 33 | let orig_iv_64 = u64::from_le_bytes(orig_iv.0); 34 | let orig_iv_lo = orig_iv_64 & LOW_WORD_MASK; 35 | let orig_iv_hi = orig_iv_64 >> 32; 36 | 37 | let full_lo = orig_iv_lo * seq_64; 38 | let full_hi = orig_iv_hi * seq_64; 39 | 40 | let out_iv_lo = (full_lo ^ (full_hi >> 32)) & LOW_WORD_MASK; 41 | let out_iv_hi = (full_hi ^ (full_lo >> 32)) & LOW_WORD_MASK; 42 | 43 | let out_iv_word = out_iv_lo | (out_iv_hi << 32); 44 | 45 | DesIv(out_iv_word.to_le_bytes()) 46 | } 47 | } 48 | 49 | #[derive(Debug)] 50 | pub struct SeqNumGenerator { 51 | next: AtomicU32, 52 | } 53 | 54 | impl SeqNumGenerator { 55 | pub fn new() -> Self { 56 | SeqNumGenerator { 57 | next: AtomicU32::new(1), 58 | } 59 | } 60 | 61 | pub fn next(&self) -> SeqNum { 62 | let mut cur = self.next.fetch_add(1, std::sync::atomic::Ordering::AcqRel); 63 | 64 | // Skip SeqNum(0) as it permutes IV to [0u8;8] 65 | if cur == 0 { 66 | cur = self.next.fetch_add(1, std::sync::atomic::Ordering::AcqRel); 67 | } 68 | 69 | SeqNum(cur) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/pa_enc_ts_enc.rs: -------------------------------------------------------------------------------- 1 | use crate::{KerberosTime, Microseconds, MAX_MICROSECONDS, MIN_MICROSECONDS}; 2 | use chrono::prelude::*; 3 | use red_asn1::Asn1Object; 4 | use red_asn1_derive::Sequence; 5 | 6 | /// (*PA-ENC-TS-ENC*) Timestamp that is encrypted with client [Key](../../key/enum.Key.html). 7 | /// ```asn1 8 | /// PA-ENC-TS-ENC ::= SEQUENCE { 9 | /// patimestamp [0] KerberosTime -- client's time --, 10 | /// pausec [1] Microseconds OPTIONAL 11 | /// } 12 | /// ``` 13 | #[derive(Sequence, Default, Clone, Debug, PartialEq)] 14 | pub struct PaEncTsEnc { 15 | #[seq_field(context_tag = 0)] 16 | pub patimestamp: KerberosTime, 17 | #[seq_field(context_tag = 1)] 18 | pub pausec: Option, 19 | } 20 | 21 | impl PaEncTsEnc { 22 | pub fn new(patimestamp: KerberosTime, pausec: Option) -> Self { 23 | return Self { 24 | patimestamp, 25 | pausec, 26 | }; 27 | } 28 | } 29 | 30 | impl From> for PaEncTsEnc { 31 | fn from(datetime: DateTime) -> Self { 32 | let mut microseconds = datetime.timestamp_subsec_micros() as i32; 33 | if microseconds > MAX_MICROSECONDS { 34 | microseconds = MAX_MICROSECONDS; 35 | } 36 | else if microseconds < MIN_MICROSECONDS { 37 | microseconds = MIN_MICROSECONDS 38 | } 39 | 40 | return Self::new(KerberosTime::from(datetime), Some(microseconds)); 41 | } 42 | } 43 | 44 | #[cfg(test)] 45 | mod test { 46 | use super::*; 47 | 48 | #[test] 49 | fn encode_timestamp() { 50 | let datetime = Utc.ymd(2019, 6, 4).and_hms_micro(05, 22, 12, 143725); 51 | assert_eq!( 52 | vec![ 53 | 0x30, 0x1a, 0xa0, 0x11, 0x18, 0x0f, 0x32, 0x30, 0x31, 0x39, 0x30, 0x36, 0x30, 0x34, 54 | 0x30, 0x35, 0x32, 0x32, 0x31, 0x32, 0x5a, 0xa1, 0x05, 0x02, 0x03, 0x02, 0x31, 0x6d 55 | ], 56 | PaEncTsEnc::from(datetime).build() 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_constants/src/pa_data_types.rs: -------------------------------------------------------------------------------- 1 | //! Preauthentication data types used by Kerberos protocol. 2 | //! 3 | //! # References 4 | //! * RFC 4210, Section 7.5.2. 5 | //! * [MS-KILE], Section 3.1.5.1. 6 | 7 | pub const PA_TGS_REQ: i32 = 1; 8 | pub const PA_ENC_TIMESTAMP: i32 = 2; 9 | pub const PA_PW_SALT: i32 = 3; 10 | pub const PA_ENC_UNIX_TIME: i32 = 5; 11 | pub const PA_SANDIA_SECUREID: i32 = 6; 12 | pub const PA_SESAME: i32 = 7; 13 | pub const PA_OSF_DCE: i32 = 8; 14 | pub const PA_CYBERSAFE_SECUREID: i32 = 9; 15 | pub const PA_AFS3_SALT: i32 = 10; 16 | pub const PA_ETYPE_INFO: i32 = 11; 17 | pub const PA_SAM_CHALLENGE: i32 = 12; 18 | pub const PA_SAM_RESPONSE: i32 = 13; 19 | pub const PA_PK_AS_REQ_OLD: i32 = 14; 20 | pub const PA_PK_AS_REP_OLD: i32 = 15; 21 | pub const PA_PK_AS_REQ: i32 = 16; 22 | pub const PA_PK_AS_REP: i32 = 17; 23 | pub const PA_ETYPE_INFO2: i32 = 19; 24 | pub const PA_SVR_REFERRAL_INFO: i32 = 20; 25 | pub const PA_USE_SPECIFIED_KVNO: i32 = 20; 26 | pub const PA_SAM_REDIRECT: i32 = 21; 27 | pub const PA_GET_FROM_TYPED_DATA: i32 = 22; 28 | pub const TD_PADATA: i32 = 22; 29 | pub const PA_SAM_ETYPE_INFO: i32 = 23; 30 | pub const PA_ALT_PRINC: i32 = 24; 31 | pub const PA_SAM_CHALLENGE2: i32 = 30; 32 | pub const PA_SAM_RESPONSE2: i32 = 31; 33 | pub const PA_EXTRA_TGT: i32 = 41; 34 | pub const TD_PKINIT_CMS_CERTIFICATES: i32 = 101; 35 | pub const TD_KRB_PRINCIPAL: i32 = 102; 36 | pub const TD_KRB_REALM: i32 = 103; 37 | pub const TD_TRUSTED_CERTIFIERS: i32 = 104; 38 | pub const TD_CERTIFICATE_INDEX: i32 = 105; 39 | pub const TD_APP_DEFINED_ERROR: i32 = 106; 40 | pub const TD_REQ_NONCE: i32 = 107; 41 | pub const TD_REQ_SEQ: i32 = 108; 42 | pub const PA_PAC_REQUEST: i32 = 128; 43 | pub const PA_FOR_USER: i32 = 129; 44 | pub const PA_FX_COOKIE: i32 = 133; 45 | pub const PA_FX_FAST: i32 = 136; 46 | pub const PA_FX_ERROR: i32 = 137; 47 | pub const PA_ENCRYPTED_CHALLENGE: i32 = 138; 48 | pub const KERB_KEY_LIST_REQ: i32 = 161; 49 | pub const KERB_KEY_LIST_REP: i32 = 162; 50 | pub const PA_SUPPORTED_ENCTYPES: i32 = 165; 51 | pub const PA_PAC_OPTIONS: i32 = 167; 52 | 53 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/ciphers/cipher_trait.rs: -------------------------------------------------------------------------------- 1 | use crate::Result; 2 | 3 | /// Trait implemented by the ciphers of this library 4 | pub trait KerberosCipher { 5 | fn etype(&self) -> i32; 6 | fn generate_salt(&self, realm: &str, client_name: &str) -> Vec; 7 | fn generate_key(&self, raw_key: &[u8], salt: &[u8]) -> Vec; 8 | fn generate_key_from_string( 9 | &self, 10 | password: &str, 11 | salt: &[u8], 12 | ) -> Vec; 13 | fn decrypt( 14 | &self, 15 | key: &[u8], 16 | key_usage: i32, 17 | ciphertext: &[u8], 18 | ) -> Result>; 19 | 20 | fn generate_key_and_decrypt( 21 | &self, 22 | raw_key: &[u8], 23 | salt: &[u8], 24 | key_usage: i32, 25 | ciphertext: &[u8], 26 | ) -> Result> { 27 | let key = self.generate_key(raw_key, salt); 28 | return self.decrypt(&key, key_usage, ciphertext); 29 | } 30 | 31 | fn generate_key_from_string_and_decrypt( 32 | &self, 33 | password: &str, 34 | salt: &[u8], 35 | key_usage: i32, 36 | ciphertext: &[u8], 37 | ) -> Result> { 38 | let key = self.generate_key_from_string(password, salt); 39 | return self.decrypt(&key, key_usage, ciphertext); 40 | } 41 | 42 | fn encrypt(&self, key: &[u8], key_usage: i32, plaintext: &[u8]) -> Vec; 43 | 44 | fn generate_key_and_encrypt( 45 | &self, 46 | raw_key: &[u8], 47 | salt: &[u8], 48 | key_usage: i32, 49 | ciphertext: &[u8], 50 | ) -> Vec { 51 | let key = self.generate_key(raw_key, salt); 52 | return self.encrypt(&key, key_usage, ciphertext); 53 | } 54 | 55 | fn generate_key_from_string_and_encrypt( 56 | &self, 57 | password: &str, 58 | salt: &[u8], 59 | key_usage: i32, 60 | ciphertext: &[u8], 61 | ) -> Vec { 62 | let key = self.generate_key_from_string(password, salt); 63 | return self.encrypt(&key, key_usage, ciphertext); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/transporter/udp_transporter.rs: -------------------------------------------------------------------------------- 1 | use crate::{Result, Error}; 2 | use std::io; 3 | pub use std::net::IpAddr; 4 | use std::net::*; 5 | 6 | use super::transporter_trait::*; 7 | 8 | /// Send Kerberos messages over UDP 9 | #[derive(Debug)] 10 | pub struct UDPTransporter { 11 | dst_addr: SocketAddr, 12 | } 13 | 14 | impl UDPTransporter { 15 | pub fn new(dst_addr: SocketAddr) -> Self { 16 | return Self { dst_addr }; 17 | } 18 | 19 | fn request_and_response_udp(&self, raw_request: &[u8]) -> io::Result> { 20 | let udp_socket = UdpSocket::bind("0.0.0.0:0")?; 21 | udp_socket.connect(self.dst_addr)?; 22 | 23 | udp_socket.send(raw_request)?; 24 | 25 | let data_length = self.calculate_response_size(&udp_socket)?; 26 | 27 | let mut raw_response = vec![0; data_length as usize]; 28 | udp_socket.recv(&mut raw_response)?; 29 | 30 | return Ok(raw_response); 31 | } 32 | 33 | fn calculate_response_size(&self, udp_socket: &UdpSocket) -> io::Result { 34 | let mut raw_response = vec![0; 2048]; 35 | let mut data_length = udp_socket.peek(&mut raw_response)?; 36 | while data_length == raw_response.len() { 37 | raw_response.append(&mut raw_response.clone()); 38 | data_length = udp_socket.peek(&mut raw_response)?; 39 | } 40 | return Ok(data_length); 41 | } 42 | } 43 | 44 | impl Transporter for UDPTransporter { 45 | fn request_and_response(&self, raw_request: &[u8]) -> Result> { 46 | let raw_response = self 47 | .request_and_response_udp(raw_request) 48 | .map_err(|_| Error::NetworkError)?; 49 | return Ok(raw_response); 50 | } 51 | } 52 | 53 | #[cfg(test)] 54 | mod tests { 55 | use super::*; 56 | 57 | #[should_panic(expected = "NetworkError")] 58 | #[test] 59 | fn test_request_networks_error() { 60 | let requester = 61 | UDPTransporter::new(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 88)); 62 | requester.request_and_response(&vec![]).unwrap(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/enc_ticket_part.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | AuthorizationData, EncryptionKey, HostAddresses, KerberosTime, 3 | PrincipalName, Realm, TicketFlags, TransitedEncoding, 4 | }; 5 | use red_asn1::Asn1Object; 6 | use red_asn1_derive::Sequence; 7 | 8 | /// (*EncTicketPart*) Encrypted part of a *Ticket*. 9 | /// Defined in RFC4120, section 5.3. 10 | /// ```asn1 11 | /// -- Encrypted part of ticket 12 | /// EncTicketPart ::= [APPLICATION 3] SEQUENCE { 13 | /// flags [0] TicketFlags, 14 | /// key [1] EncryptionKey, 15 | /// crealm [2] Realm, 16 | /// cname [3] PrincipalName, 17 | /// transited [4] TransitedEncoding, 18 | /// authtime [5] KerberosTime, 19 | /// starttime [6] KerberosTime OPTIONAL, 20 | /// endtime [7] KerberosTime, 21 | /// renew-till [8] KerberosTime OPTIONAL, 22 | /// caddr [9] HostAddresses OPTIONAL, 23 | /// authorization-data [10] AuthorizationData OPTIONAL 24 | /// } 25 | /// ``` 26 | #[derive(Sequence, Default, Debug, Clone, PartialEq)] 27 | #[seq(application_tag = 3)] 28 | pub struct EncTicketPart { 29 | #[seq_field(context_tag = 0)] 30 | pub flags: TicketFlags, 31 | #[seq_field(context_tag = 1)] 32 | pub key: EncryptionKey, 33 | #[seq_field(context_tag = 2)] 34 | pub crealm: Realm, 35 | #[seq_field(context_tag = 3)] 36 | pub cname: PrincipalName, 37 | #[seq_field(context_tag = 4)] 38 | pub transited: TransitedEncoding, 39 | #[seq_field(context_tag = 5)] 40 | pub authtime: KerberosTime, 41 | #[seq_field(context_tag = 6)] 42 | pub starttime: Option, 43 | #[seq_field(context_tag = 7)] 44 | pub endtime: KerberosTime, 45 | #[seq_field(context_tag = 8)] 46 | pub renew_till: Option, 47 | #[seq_field(context_tag = 9)] 48 | pub caddr: Option, 49 | #[seq_field(context_tag = 10)] 50 | pub authorization_data: Option, 51 | } 52 | -------------------------------------------------------------------------------- /libs/block-device/src/partition.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::sync::{Arc, Mutex}; 3 | 4 | use crate::BlockDevice; 5 | 6 | pub struct PartitionBlockDevice { 7 | backing: Arc>>, 8 | base_block: u64, 9 | num_blocks: Option, 10 | } 11 | 12 | impl PartitionBlockDevice { 13 | pub fn new( 14 | backing: Arc>>, 15 | base_block: u64, 16 | num_blocks: Option, 17 | ) -> Self { 18 | PartitionBlockDevice { 19 | backing, 20 | base_block, 21 | num_blocks, 22 | } 23 | } 24 | 25 | fn translate_and_bounds_check(&self, block_num: u64) -> io::Result { 26 | let phys_block_num = block_num + self.base_block; 27 | 28 | let last_block_num = self.last_block_num() 29 | .unwrap_or(u64::MAX); 30 | 31 | if phys_block_num > last_block_num { 32 | return Err(io::Error::new( 33 | io::ErrorKind::Other, 34 | format!("Block {} out of bounds", block_num) 35 | )) 36 | } 37 | 38 | Ok(phys_block_num) 39 | } 40 | 41 | fn last_block_num(&self) -> Option { 42 | self.num_blocks.map(|num_blocks| self.base_block + num_blocks - 1 ) 43 | } 44 | } 45 | 46 | impl BlockDevice for PartitionBlockDevice { 47 | fn num_blocks(&mut self) -> u64 { 48 | todo!() 49 | } 50 | 51 | fn read_block(&mut self, block_num: u64) -> io::Result<[u8;BLOCK_SIZE]> { 52 | let phys_block_num = self.translate_and_bounds_check(block_num)?; 53 | 54 | self.backing 55 | .lock() 56 | .unwrap() 57 | .read_block(phys_block_num) 58 | } 59 | 60 | fn write_block(&mut self, block_num: u64, block: &[u8;BLOCK_SIZE]) -> io::Result<()> { 61 | let phys_block_num = self.translate_and_bounds_check(block_num)?; 62 | 63 | self.backing 64 | .lock() 65 | .unwrap() 66 | .write_block(phys_block_num, block) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerbeiros/src/transporter/tcp_transporter.rs: -------------------------------------------------------------------------------- 1 | use crate::{Result, Error}; 2 | use std::io; 3 | use std::io::{Read, Write}; 4 | use std::net::*; 5 | use std::time::Duration; 6 | 7 | use super::transporter_trait::*; 8 | 9 | /// Send Kerberos messages over TCP 10 | #[derive(Debug)] 11 | pub struct TCPTransporter { 12 | dst_addr: SocketAddr, 13 | } 14 | 15 | impl TCPTransporter { 16 | pub fn new(dst_addr: SocketAddr) -> Self { 17 | return Self { dst_addr }; 18 | } 19 | 20 | fn request_and_response_tcp(&self, raw_request: &[u8]) -> io::Result> { 21 | let mut tcp_stream = TcpStream::connect_timeout(&self.dst_addr, Duration::new(5, 0))?; 22 | 23 | let raw_sized_request = Self::set_size_header_to_request(raw_request); 24 | tcp_stream.write(&raw_sized_request)?; 25 | 26 | let mut len_data_bytes = [0 as u8; 4]; 27 | tcp_stream.read_exact(&mut len_data_bytes)?; 28 | let data_length = u32::from_be_bytes(len_data_bytes); 29 | 30 | let mut raw_response: Vec = vec![0; data_length as usize]; 31 | tcp_stream.read_exact(&mut raw_response)?; 32 | 33 | return Ok(raw_response); 34 | } 35 | 36 | fn set_size_header_to_request(raw_request: &[u8]) -> Vec { 37 | let request_length = raw_request.len() as u32; 38 | let mut raw_sized_request: Vec = request_length.to_be_bytes().to_vec(); 39 | raw_sized_request.append(&mut raw_request.to_vec()); 40 | 41 | return raw_sized_request; 42 | } 43 | } 44 | 45 | impl Transporter for TCPTransporter { 46 | fn request_and_response(&self, raw_request: &[u8]) -> Result> { 47 | let raw_response = self 48 | .request_and_response_tcp(raw_request) 49 | .map_err(|_| Error::NetworkError)?; 50 | return Ok(raw_response); 51 | } 52 | } 53 | 54 | #[cfg(test)] 55 | mod tests { 56 | use super::*; 57 | 58 | #[should_panic(expected = "NetworkError")] 59 | #[test] 60 | fn test_request_networks_error() { 61 | let requester = 62 | TCPTransporter::new(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 88)); 63 | requester.request_and_response(&vec![]).unwrap(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /libs/xbox-sys/src/config.rs: -------------------------------------------------------------------------------- 1 | use crate::std::fmt; 2 | 3 | pub const MAC_ADDRESS_LEN: usize = 6; 4 | 5 | #[derive(Debug)] 6 | pub struct MacAddress(pub [u8;MAC_ADDRESS_LEN]); 7 | 8 | impl fmt::Display for MacAddress { 9 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 10 | write!(f, "{:02x}-{:02x}-{:02x}-{:02x}-{:02x}-{:02x}", 11 | self.0[0], self.0[1], self.0[2], 12 | self.0[3], self.0[4], self.0[5]) 13 | } 14 | } 15 | 16 | pub const SERIAL_NUBMER_LEN: usize = 12; 17 | 18 | #[derive(Debug, PartialEq)] 19 | pub struct SerialNumber(pub [u8;SERIAL_NUBMER_LEN]); 20 | 21 | impl SerialNumber { 22 | pub fn is_format_valid(&self) -> bool { 23 | for byte in self.0 { 24 | if !(byte as char).is_ascii_digit() { 25 | return false 26 | } 27 | } 28 | 29 | true 30 | } 31 | 32 | pub fn as_str<'a>(&'a self) -> Option<&'a str> { 33 | if self.is_format_valid() { 34 | crate::std::str::from_utf8(&self.0).ok() 35 | } else { 36 | None 37 | } 38 | } 39 | 40 | pub fn parse(s: &str) -> Option { 41 | let mut serial_number = SerialNumber([0;SERIAL_NUBMER_LEN]); 42 | let mut highest_i = 0; 43 | for (i, c) in s.char_indices() { 44 | if i >= SERIAL_NUBMER_LEN { 45 | return None; 46 | } 47 | if !c.is_digit(10) { 48 | return None; 49 | } 50 | highest_i = i; 51 | serial_number.0[i] = c as u8; 52 | } 53 | 54 | if highest_i != (SERIAL_NUBMER_LEN - 1) { 55 | return None; 56 | } 57 | 58 | Some(serial_number) 59 | } 60 | } 61 | 62 | impl fmt::Display for SerialNumber { 63 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 64 | match self.as_str() { 65 | Some(s) => write!(f, "{}", s), 66 | None => write!(f, "{:02x?}", self) 67 | } 68 | } 69 | } 70 | 71 | #[cfg(test)] 72 | mod tests { 73 | use hex_literal::hex; 74 | 75 | use super::*; 76 | 77 | #[test] 78 | fn parse_serial() { 79 | assert_eq!(SerialNumber::parse("801735999216"), 80 | Some(SerialNumber(hex!["38 30 31 37 33 35 39 39 39 32 31 36"]))); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_crypto/src/algorithms/rc4_hmac_md5/key.rs: -------------------------------------------------------------------------------- 1 | use crate::cryptography::md4; 2 | use crate::utils::string_unicode_bytes; 3 | 4 | /// Derive the RC4 key used to encrypt/decrypt from the 5 | /// user secret (password) 6 | pub fn generate_key(secret: &[u8]) -> Vec { 7 | return md4(secret); 8 | } 9 | 10 | /// Derive the RC4 key used to encrypt/decrypt from the string 11 | /// representation of the user secret (password) 12 | pub fn generate_key_from_string(string: &str) -> Vec { 13 | let raw_key = string_unicode_bytes(string); 14 | return generate_key(&raw_key); 15 | } 16 | 17 | #[cfg(test)] 18 | mod test { 19 | use super::*; 20 | 21 | fn rc4_key_gen(password: &str) -> Vec { 22 | return generate_key_from_string(password); 23 | } 24 | 25 | #[test] 26 | fn generate_rc4_key() { 27 | assert_eq!( 28 | vec![ 29 | 0x20, 0x9c, 0x61, 0x74, 0xda, 0x49, 0x0c, 0xae, 0xb4, 0x22, 30 | 0xf3, 0xfa, 0x5a, 0x7a, 0xe6, 0x34 31 | ], 32 | rc4_key_gen("admin") 33 | ); 34 | assert_eq!( 35 | vec![ 36 | 0x0c, 0xb6, 0x94, 0x88, 0x05, 0xf7, 0x97, 0xbf, 0x2a, 0x82, 37 | 0x80, 0x79, 0x73, 0xb8, 0x95, 0x37 38 | ], 39 | rc4_key_gen("test") 40 | ); 41 | assert_eq!( 42 | vec![ 43 | 0x2f, 0xd6, 0xbd, 0xe7, 0xdb, 0x06, 0x81, 0x88, 0x74, 0x98, 44 | 0x91, 0x4c, 0xb2, 0xd2, 0x01, 0xef 45 | ], 46 | rc4_key_gen("1337") 47 | ); 48 | assert_eq!( 49 | vec![ 50 | 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, 0xb7, 0x3c, 51 | 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 52 | ], 53 | rc4_key_gen("") 54 | ); 55 | assert_eq!( 56 | vec![ 57 | 0x25, 0x97, 0x45, 0xcb, 0x12, 0x3a, 0x52, 0xaa, 0x2e, 0x69, 58 | 0x3a, 0xaa, 0xcc, 0xa2, 0xdb, 0x52 59 | ], 60 | rc4_key_gen("12345678") 61 | ); 62 | assert_eq!( 63 | vec![ 64 | 0xc2, 0x2b, 0x31, 0x5c, 0x04, 0x0a, 0xe6, 0xe0, 0xef, 0xee, 65 | 0x35, 0x18, 0xd8, 0x30, 0x36, 0x2b 66 | ], 67 | rc4_key_gen("123456789") 68 | ); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_ccache/src/header/delta_time.rs: -------------------------------------------------------------------------------- 1 | use nom::number::complete::be_u32; 2 | use nom::IResult; 3 | 4 | /// Type of [Header](./struct.Header.html). 5 | /// # Definition 6 | /// ```c 7 | /// DeltaTime { 8 | /// uint32_t time_offset; 9 | /// dbg!(uint32_t) usec_offset; 10 | /// }; 11 | /// ``` 12 | 13 | #[derive(Debug, PartialEq, Clone)] 14 | pub struct DeltaTime { 15 | pub time_offset: u32, 16 | pub usec_offset: u32, 17 | } 18 | 19 | impl DeltaTime { 20 | pub fn new(time_offset: u32, usec_offset: u32) -> Self { 21 | return Self { 22 | time_offset, 23 | usec_offset, 24 | }; 25 | } 26 | 27 | /// Build the binary representation 28 | pub fn build(&self) -> Vec { 29 | let mut bytes = Vec::with_capacity(8); 30 | bytes.append(&mut self.time_offset.to_be_bytes().to_vec()); 31 | bytes.append(&mut self.usec_offset.to_be_bytes().to_vec()); 32 | return bytes; 33 | } 34 | 35 | /// Creates a new instance from the binary representation. 36 | /// The common way of creation is from Header.tagdata value. 37 | /// `DeltaTime::parse(&header.tagdata)` 38 | /// # Error 39 | /// Returns error when the binary has not the expected format. 40 | pub fn parse(raw: &[u8]) -> IResult<&[u8], Self> { 41 | let (raw, time_offset) = be_u32(raw)?; 42 | let (raw, usec_offset) = be_u32(raw)?; 43 | 44 | return Ok((raw, Self::new(time_offset, usec_offset))); 45 | } 46 | } 47 | 48 | impl Default for DeltaTime { 49 | fn default() -> Self { 50 | return DeltaTime::new(u32::max_value(), 0); 51 | } 52 | } 53 | 54 | #[cfg(test)] 55 | mod test { 56 | use super::*; 57 | 58 | #[test] 59 | fn deltatime_to_bytes() { 60 | assert_eq!( 61 | vec![0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00], 62 | DeltaTime::default().build() 63 | ) 64 | } 65 | 66 | #[test] 67 | fn parse_deltatime_from_bytes() { 68 | assert_eq!( 69 | DeltaTime::default(), 70 | DeltaTime::parse(&[0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]) 71 | .unwrap() 72 | .1 73 | ) 74 | } 75 | 76 | #[test] 77 | #[should_panic(expected = "[0], Eof")] 78 | fn parse_deltatime_from_bytes_error() { 79 | DeltaTime::parse(&[0x0]).unwrap(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | api: 5 | image: xombie/userv 6 | command: /opt/xombie/bin/api 7 | networks: 8 | - frontend 9 | - backend 10 | depends_on: 11 | - db 12 | - redis 13 | 14 | faux_dns: 15 | image: xombie/userv 16 | command: /opt/xombie/bin/faux-dns --dns-port 5300 17 | ports: 18 | - "53:5300/udp" 19 | networks: 20 | - frontend 21 | - backend 22 | depends_on: 23 | - db 24 | - redis 25 | 26 | kdc: 27 | image: xombie/userv 28 | command: /opt/xombie/bin/kdc 29 | ports: 30 | - "88:88/udp" 31 | networks: 32 | - frontend 33 | - backend 34 | depends_on: 35 | - db 36 | - redis 37 | 38 | sg: 39 | image: xombie/userv 40 | command: /opt/xombie/bin/sg 41 | ports: 42 | - "3074:3074/udp" 43 | networks: 44 | - frontend 45 | - backend 46 | depends_on: 47 | - db 48 | - redis 49 | 50 | redis: 51 | image: redis:6.2.5-alpine 52 | volumes: 53 | - "./healthchecks:/healthchecks" 54 | healthcheck: 55 | test: /healthchecks/redis.sh 56 | interval: "5s" 57 | ports: 58 | - "6379:6379" 59 | networks: 60 | - backend 61 | 62 | db: 63 | image: postgres:14.0 64 | environment: 65 | POSTGRES_USER: "postgres" 66 | volumes: 67 | - "db-data:/var/lib/postgresql/data" 68 | - "./healthchecks:/healthchecks" 69 | healthcheck: 70 | test: /healthchecks/postgres.sh 71 | interval: "5s" 72 | ports: 73 | - "5432:5432" 74 | networks: 75 | - backend 76 | 77 | nginx: 78 | build: 79 | context: frontend 80 | dockerfile: Dockerfile 81 | args: 82 | REACT_APP_API_BASE_URL: http://127.0.0.1/api 83 | volumes: 84 | - ./nginx.conf:/etc/nginx/nginx.conf:ro 85 | ports: 86 | - "80:80" 87 | networks: 88 | - frontend 89 | depends_on: 90 | - api 91 | 92 | volumes: 93 | db-data: 94 | 95 | networks: 96 | frontend: 97 | backend: 98 | -------------------------------------------------------------------------------- /libs/xbox-sys/src/crypto.rs: -------------------------------------------------------------------------------- 1 | use bytes::BufMut; 2 | 3 | use crate::codec::{BufPut, Decode, decode_array_u8}; 4 | use crate::std::fmt; 5 | 6 | pub mod keys; 7 | 8 | pub const SYMMETRIC_KEY_LEN: usize = 16; 9 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] 10 | pub struct SymmetricKey(pub [u8;SYMMETRIC_KEY_LEN]); 11 | 12 | impl SymmetricKey { 13 | pub fn parse_str(s: &str) -> Option { 14 | let buf = parse_hex_buffer(s)?; 15 | Some(SymmetricKey(buf)) 16 | } 17 | } 18 | 19 | impl BufPut for SymmetricKey { 20 | fn put(&self, buf: &mut AnyBufMut) { 21 | buf.put_slice(&self.0) 22 | } 23 | } 24 | 25 | impl Decode for SymmetricKey { 26 | fn decode<'a>(input: &'a [u8]) -> nom::IResult<&'a [u8], Self> { 27 | let (input, val) = decode_array_u8(input)?; 28 | Ok((input, SymmetricKey(val))) 29 | } 30 | } 31 | 32 | impl fmt::Display for SymmetricKey { 33 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 34 | for byte in self.0 { 35 | write!(f, "{:02x}", byte)? 36 | } 37 | 38 | Ok(()) 39 | } 40 | } 41 | 42 | fn parse_hex_buffer(s: &str) -> Option<[u8;N]> { 43 | if s.len() != N * 2 { 44 | return None; 45 | } 46 | 47 | let mut buf = [0;N]; 48 | for (i, bytes) in s.as_bytes().chunks(2).enumerate() { 49 | let hi = nybble_str(bytes[0])?; 50 | let lo = nybble_str(bytes[1])?; 51 | 52 | buf[i] = (hi << 4) | lo; 53 | } 54 | 55 | Some(buf) 56 | } 57 | 58 | fn nybble_str(c: u8) -> Option { 59 | Some(match c { 60 | b'0'..=b'9' => c - b'0', 61 | b'a'..=b'f' => c - b'a' + 0xa, 62 | b'A'..=b'F' => c - b'A' + 0xA, 63 | _ => return None, 64 | }) 65 | } 66 | 67 | pub const DES_IV_LEN: usize = 8; 68 | 69 | #[derive(Clone, Copy, Debug, PartialEq)] 70 | pub struct DesIv(pub [u8;DES_IV_LEN]); 71 | 72 | impl Decode for DesIv { 73 | fn decode<'a>(input: &'a [u8]) -> nom::IResult<&'a [u8], Self> { 74 | let (input, arr) = decode_array_u8(input)?; 75 | 76 | Ok((input, DesIv(arr))) 77 | } 78 | } 79 | 80 | #[cfg(test)] 81 | mod tests { 82 | use hex_literal::hex; 83 | 84 | use super::*; 85 | 86 | #[test] 87 | fn parse_key_str() { 88 | assert_eq!(SymmetricKey::parse_str("f8d4863cac0eda58813b7a6d4a7eb4a3"), 89 | Some(SymmetricKey(hex!["f8d4863cac0eda58813b7a6d4a7eb4a3"]))) 90 | } 91 | } -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/authenticator.rs: -------------------------------------------------------------------------------- 1 | use crate::{ 2 | AuthorizationData, Checksum, EncryptionKey, Int32, KerberosTime, 3 | Microseconds, PrincipalName, Realm, UInt32, 4 | }; 5 | use chrono::{Timelike, Utc}; 6 | use red_asn1::Asn1Object; 7 | use red_asn1_derive::Sequence; 8 | 9 | /// (*Authenticator*) Included in *AP-REQ* to certified the knowledge of the session key. 10 | /// Defined in RFC4120, section 5.5.1. 11 | /// ```asn1 12 | /// -- Unencrypted authenticator 13 | /// Authenticator ::= [APPLICATION 2] SEQUENCE { 14 | /// authenticator-vno [0] INTEGER (5), 15 | /// crealm [1] Realm, 16 | /// cname [2] PrincipalName, 17 | /// cksum [3] Checksum OPTIONAL, 18 | /// cusec [4] Microseconds, 19 | /// ctime [5] KerberosTime, 20 | /// subkey [6] EncryptionKey OPTIONAL, 21 | /// seq-number [7] UInt32 OPTIONAL, 22 | /// authorization-data [8] AuthorizationData OPTIONAL 23 | /// } 24 | /// ``` 25 | #[derive(Sequence, Debug, Clone, PartialEq)] 26 | #[seq(application_tag = 2)] 27 | pub struct Authenticator { 28 | #[seq_field(context_tag = 0)] 29 | pub authenticator_vno: Int32, 30 | #[seq_field(context_tag = 1)] 31 | pub crealm: Realm, 32 | #[seq_field(context_tag = 2)] 33 | pub cname: PrincipalName, 34 | #[seq_field(context_tag = 3)] 35 | pub cksum: Option, 36 | #[seq_field(context_tag = 4)] 37 | pub cusec: Microseconds, 38 | #[seq_field(context_tag = 5)] 39 | pub ctime: KerberosTime, 40 | #[seq_field(context_tag = 6)] 41 | pub subkey: Option, 42 | #[seq_field(context_tag = 7)] 43 | pub seq_number: Option, 44 | #[seq_field(context_tag = 8)] 45 | pub authorization_data: Option, 46 | } 47 | 48 | impl Default for Authenticator { 49 | fn default() -> Authenticator { 50 | let now = Utc::now(); 51 | Self { 52 | authenticator_vno: 5, 53 | crealm: Realm::default(), 54 | cname: PrincipalName::default(), 55 | cksum: Option::default(), 56 | cusec: (now.nanosecond() / 1000) as i32, 57 | ctime: now.into(), 58 | subkey: Option::default(), 59 | seq_number: Option::default(), 60 | authorization_data: Option::default(), 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_asn1/src/pa_data/etype_info2_entry.rs: -------------------------------------------------------------------------------- 1 | use crate::{Int32, KerberosString}; 2 | use red_asn1::{Asn1Object, OctetString}; 3 | use red_asn1_derive::Sequence; 4 | 5 | /// (*ETYPE-INFO2-ENTRY*) Give information about an encryption algorithm. 6 | /// ```asn1 7 | /// ETYPE-INFO2-ENTRY ::= SEQUENCE { 8 | /// etype [0] Int32, 9 | /// salt [1] KerberosString OPTIONAL, 10 | /// s2kparams [2] OCTET STRING OPTIONAL 11 | /// } 12 | /// ``` 13 | 14 | #[derive(Sequence, Debug, Clone, PartialEq, Default)] 15 | pub struct EtypeInfo2Entry { 16 | #[seq_field(context_tag = 0)] 17 | pub etype: Int32, 18 | #[seq_field(context_tag = 1)] 19 | pub salt: Option, 20 | #[seq_field(context_tag = 2)] 21 | pub s2kparams: Option, 22 | } 23 | 24 | impl EtypeInfo2Entry { 25 | pub fn new(etype: Int32, salt: Option, s2kparams: Option) -> Self { 26 | return Self { 27 | etype, 28 | salt, 29 | s2kparams, 30 | }; 31 | } 32 | } 33 | 34 | #[cfg(test)] 35 | mod test { 36 | use super::*; 37 | use kerberos_constants::etypes::*; 38 | 39 | #[test] 40 | fn test_parse_etypeinfo2entry() { 41 | let mut entry = EtypeInfo2Entry::default(); 42 | entry.etype = AES256_CTS_HMAC_SHA1_96; 43 | entry.salt = Some(KerberosString::from("KINGDOM.HEARTSmickey")); 44 | 45 | assert_eq!( 46 | entry, 47 | EtypeInfo2Entry::parse(&[ 48 | 0x30, 0x1d, 0xa0, 0x03, 0x02, 0x01, 0x12, 0xa1, 0x16, 0x1b, 0x14, 0x4b, 0x49, 0x4e, 49 | 0x47, 0x44, 0x4f, 0x4d, 0x2e, 0x48, 0x45, 0x41, 0x52, 0x54, 0x53, 0x6d, 0x69, 0x63, 50 | 0x6b, 0x65, 0x79, 51 | ]) 52 | .unwrap() 53 | .1 54 | ); 55 | } 56 | 57 | 58 | #[test] 59 | fn test_build_etypeinfo2entry() { 60 | let mut entry = EtypeInfo2Entry::default(); 61 | entry.etype = AES256_CTS_HMAC_SHA1_96; 62 | entry.salt = Some(KerberosString::from("KINGDOM.HEARTSmickey")); 63 | 64 | assert_eq!( 65 | vec![ 66 | 0x30, 0x1d, 0xa0, 0x03, 0x02, 0x01, 0x12, 0xa1, 0x16, 0x1b, 0x14, 0x4b, 0x49, 0x4e, 67 | 0x47, 0x44, 0x4f, 0x4d, 0x2e, 0x48, 0x45, 0x41, 0x52, 0x54, 0x53, 0x6d, 0x69, 0x63, 68 | 0x6b, 0x65, 0x79, 69 | ], 70 | entry.build() 71 | ); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1/src/types/boolean.rs: -------------------------------------------------------------------------------- 1 | use crate::error as asn1err; 2 | use crate::tag::Tag; 3 | use crate::traits::Asn1Object; 4 | 5 | pub static BOOLEAN_TAG_NUMBER: u8 = 0x1; 6 | 7 | /// Class to build/parse Boolean ASN1 8 | pub type Boolean = bool; 9 | 10 | impl Asn1Object for bool { 11 | fn tag() -> Tag { 12 | return Tag::new_primitive_universal(BOOLEAN_TAG_NUMBER); 13 | } 14 | 15 | fn build_value(&self) -> Vec { 16 | return vec![(*self as u8) * 0xff]; 17 | } 18 | 19 | fn parse_value(&mut self, raw: &[u8]) -> asn1err::Result<()> { 20 | if raw.len() == 0 { 21 | return Err(asn1err::Error::IncorrectValue( 22 | format!("No octects for bool") 23 | ))?; 24 | } 25 | 26 | *self = raw[0] != 0; 27 | return Ok(()); 28 | } 29 | } 30 | 31 | #[cfg(test)] 32 | mod tests { 33 | use super::*; 34 | 35 | #[test] 36 | fn test_build() { 37 | assert_eq!(vec![0x1, 0x1, 0x0], false.build()); 38 | assert_eq!(vec![0x1, 0x1, 0xff], true.build()); 39 | } 40 | 41 | #[test] 42 | fn test_parse() { 43 | assert_eq!(false, bool::parse(&[0x1, 0x1, 0x0]).unwrap().1); 44 | assert_eq!(true, bool::parse(&[0x1, 0x1, 0xff]).unwrap().1); 45 | assert_eq!(true, bool::parse(&[0x1, 0x1, 0x01]).unwrap().1); 46 | assert_eq!(true, bool::parse(&[0x1, 0x1, 0x7b]).unwrap().1); 47 | } 48 | 49 | #[test] 50 | fn test_parse_with_excesive_bytes() { 51 | let x: &[u8] = &[0x1]; 52 | assert_eq!((x, false), bool::parse(&[0x1, 0x1, 0x0, 0x1]).unwrap()); 53 | assert_eq!( 54 | (x, true), 55 | bool::parse(&[0x1, 0x1, 0xff, 0x1]).unwrap() 56 | ); 57 | assert_eq!( 58 | (x, true), 59 | bool::parse(&[0x1, 0x1, 0x01, 0x1]).unwrap() 60 | ); 61 | assert_eq!( 62 | (x, true), 63 | bool::parse(&[0x1, 0x1, 0x7b, 0x1]).unwrap() 64 | ); 65 | 66 | let y: &[u8] = &[]; 67 | assert_eq!((y, false), bool::parse(&[0x1, 0x2, 0x0, 0x1]).unwrap()); 68 | } 69 | 70 | #[should_panic(expected = "UnmatchedTag")] 71 | #[test] 72 | fn test_parse_with_invalid_tag() { 73 | bool::parse(&[0x7, 0x1, 0x0]).unwrap(); 74 | } 75 | 76 | #[should_panic(expected = "IncorrectValue(\"No octects for bool\")")] 77 | #[test] 78 | fn test_parse_without_enough_value_octets() { 79 | bool::parse(&[0x1, 0x0]).unwrap(); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /third_party/red_asn1/red_asn1/src/types/generalstring.rs: -------------------------------------------------------------------------------- 1 | use crate::error as asn1err; 2 | use crate::tag::Tag; 3 | use crate::traits::Asn1Object; 4 | 5 | pub static GENERALSTRING_TAG_NUMBER: u8 = 0x1b; 6 | 7 | /// Class to build/parse GeneralString ASN1 8 | pub type GeneralString = String; 9 | 10 | impl Asn1Object for String { 11 | fn tag() -> Tag { 12 | return Tag::new_primitive_universal(GENERALSTRING_TAG_NUMBER); 13 | } 14 | 15 | fn build_value(&self) -> Vec { 16 | return self.as_bytes().to_vec(); 17 | } 18 | 19 | fn parse_value(&mut self, raw: &[u8]) -> asn1err::Result<()> { 20 | *self = String::from_utf8(raw.to_vec())?; 21 | return Ok(()); 22 | } 23 | } 24 | 25 | #[cfg(test)] 26 | mod tests { 27 | use super::*; 28 | 29 | #[test] 30 | fn test_build() { 31 | assert_eq!( 32 | vec![ 33 | 0x1b, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x31, 0x40, 0x72, 0x73, 34 | 0x61, 0x2e, 0x63, 0x6f, 0x6d 35 | ], 36 | GeneralString::from("test1@rsa.com").build() 37 | ); 38 | } 39 | 40 | #[test] 41 | fn test_parse() { 42 | assert_eq!( 43 | GeneralString::from("test1@rsa.com"), 44 | String::parse(&[ 45 | 0x1b, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x31, 0x40, 0x72, 0x73, 46 | 0x61, 0x2e, 0x63, 0x6f, 0x6d 47 | ]) 48 | .unwrap() 49 | .1 50 | ); 51 | } 52 | 53 | #[test] 54 | fn test_parse_empty_value() { 55 | assert_eq!( 56 | GeneralString::from("".to_string()), 57 | String::parse(&[0x1b, 0x00]).unwrap().1 58 | ); 59 | } 60 | 61 | #[test] 62 | fn test_parse_with_excesive_bytes() { 63 | let rest: &[u8] = &[0x22, 0x22, 0x22]; 64 | assert_eq!( 65 | (rest, GeneralString::from("test1@rsa.com".to_string())), 66 | String::parse(&[ 67 | 0x1b, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x31, 0x40, 0x72, 0x73, 68 | 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x22, 0x22 69 | ]) 70 | .unwrap() 71 | ); 72 | } 73 | 74 | #[should_panic(expected = "Utf8Error")] 75 | #[test] 76 | fn test_parse_non_ascii_characters() { 77 | String::parse(&[0x1b, 0x1, 0xff]).unwrap(); 78 | } 79 | 80 | #[should_panic(expected = "UnmatchedTag")] 81 | #[test] 82 | fn test_parse_with_invalid_tag() { 83 | String::parse(&[0x7, 0x1, 0x0]).unwrap(); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /frontend/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /third_party/kerbeiros/kerberos_ccache/src/header/header.rs: -------------------------------------------------------------------------------- 1 | use nom::number::complete::be_u16; 2 | use nom::IResult; 3 | use nom::{length_data, named}; 4 | use super::DeltaTime; 5 | 6 | named!(parse_length_u16_array, length_data!(be_u16)); 7 | 8 | /// Header of [CCache](./struct.CCache.html) 9 | /// # Definition 10 | /// ```c 11 | /// header { 12 | /// uint16_t tag; /* 1 = DeltaTime */ 13 | /// uint16_t taglen; 14 | /// uint8_t tagdata[taglen] 15 | /// }; 16 | /// ``` 17 | /// 18 | #[derive(Debug, PartialEq, Clone)] 19 | pub struct Header { 20 | pub tag: u16, 21 | pub tagdata: Vec, 22 | } 23 | 24 | impl Header { 25 | pub const DELTA_TIME: u16 = 1; 26 | 27 | pub fn new(tag: u16, tagdata: Vec) -> Self { 28 | return Self { tag, tagdata }; 29 | } 30 | 31 | /// Build the binary representation 32 | pub fn build(mut self) -> Vec { 33 | let mut bytes = self.tag.to_be_bytes().to_vec(); 34 | let raw_len = self.tagdata.len() as u16; 35 | bytes.append(&mut raw_len.to_be_bytes().to_vec()); 36 | bytes.append(&mut self.tagdata); 37 | return bytes; 38 | } 39 | 40 | /// Creates a new instance from the binary representation 41 | /// # Error 42 | /// Returns error when the binary has not the expected format. 43 | pub fn parse(raw: &[u8]) -> IResult<&[u8], Self> { 44 | let (raw, tag) = be_u16(raw)?; 45 | let (raw, tagdata) = parse_length_u16_array(raw)?; 46 | return Ok((raw, Self::new(tag, tagdata.to_vec()))); 47 | } 48 | } 49 | 50 | impl Default for Header { 51 | fn default() -> Self { 52 | return Header::new(Header::DELTA_TIME, DeltaTime::default().build()); 53 | } 54 | } 55 | 56 | #[cfg(test)] 57 | mod test { 58 | use super::*; 59 | 60 | #[test] 61 | fn header_to_bytes() { 62 | assert_eq!( 63 | vec![ 64 | 0x00, 0x01, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 65 | 0x00, 0x00 66 | ], 67 | Header::default().build() 68 | ) 69 | } 70 | 71 | #[test] 72 | fn test_parse_header() { 73 | assert_eq!( 74 | Header::default(), 75 | Header::parse(&[ 76 | 0x00, 0x01, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 77 | 0x00, 0x00 78 | ]) 79 | .unwrap() 80 | .1, 81 | ) 82 | } 83 | 84 | #[test] 85 | #[should_panic(expected = "[0], Eof")] 86 | fn test_parse_header_panic() { 87 | Header::parse(&[0x00]).unwrap(); 88 | } 89 | } 90 | --------------------------------------------------------------------------------