From 4456e3f449cca922bf1e4f9118b26316abfc01f5 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Wed, 13 Mar 2024 12:01:01 +0100 Subject: [PATCH 01/37] adding test files --- ca.crt | 21 +++ myserver.crt | 22 +++ myserver.key | 28 +++ pub_client.json5 | 431 +++++++++++++++++++++++++++++++++++++++++++++++ router.json5 | 431 +++++++++++++++++++++++++++++++++++++++++++++++ sub_client.json5 | 431 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 1364 insertions(+) create mode 100644 ca.crt create mode 100644 myserver.crt create mode 100644 myserver.key create mode 100644 pub_client.json5 create mode 100644 router.json5 create mode 100644 sub_client.json5 diff --git a/ca.crt b/ca.crt new file mode 100644 index 0000000000..50b4d876ca --- /dev/null +++ b/ca.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUO1x6LAlICgKs5+pYUTo4CughfKEwDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTExNDM0MjNaFw0yNTAzMTExNDM0MjNaMFQxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRgwFgYDVQQDDA96 +c190ZXN0X3Jvb3RfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3 +pFWM+IJNsRCYHt1v/TliecppwVZV+ZHfFw9JKN9ev4K/fWHUiAOwp91MOLxbaYKd +C6dxW28YVGltoGz3kUZJZcJRQVso1jXv24Op4muOsiYXukLc4TU2F6dG1XqkLt5t +svsYAQFf1uK3//QZFVRBosJEn+jjiJ4XCvt49mnPRolp1pNKX0z31mZO6bSly6c9 +OVlJMjWpDCYSOuf6qZZ36fa9eSut2bRJIPY0QCsgnqYBTnIEhksS+3jy6Qt+QpLz +95pFdLbW/MW4XKpaDltyYkO6QrBekF6uWRlvyAHU+NqvXZ4F/3Z5l26qLuBcsLPJ +kyawkO+yNIDxORmQgMczAgMBAAGjUzBRMB0GA1UdDgQWBBThgotd9ws2ryEEaKp2 ++RMOWV8D7jAfBgNVHSMEGDAWgBThgotd9ws2ryEEaKp2+RMOWV8D7jAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA9QoPv78hGmvmqF4GZeqrOBKQB +N/H5wL7f8H6BXU/wpNo2nnWOJn3u37lT+zivAdGEv+x+GeKekcugKBCSluhBLpVb +VNXe4WwMm5FBuO2NRBN2nblTMm1kEO00nVk1/yNo4hI8mj7d4YLU62d7324osNpF +wHqu6B0/c99JeKRvODGswyff1i8rJ1jpcgk/JmHg7UQBHEIkn0cRR0f9W3Mxv6b5 +ZeowRe81neWNkC6IMiMmzA0iHGkhoUMA15qG1ZKOr1XR364LH5BfNNpzAWYwkvJs +0JFrrdw+rm+cRJWs55yiyCCs7pyg1IJkY/o8bifdCOUgIyonzffwREk3+kZR +-----END CERTIFICATE----- diff --git a/myserver.crt b/myserver.crt new file mode 100644 index 0000000000..a68071aa18 --- /dev/null +++ b/myserver.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDmDCCAoCgAwIBAgIUFMs3tKqT0Cvz3r0aSN9KSVPCsfkwDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTExNDQ0MzZaFw0yNTAzMTExNDQ0MzZaMFQxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRgwFgYDVQQDDA90 +ZXN0X3Rsc19zZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCh +86dsAI7FzJxhKykW5uzHuz9NGbmzq8G9ndUdIwTHYmawTTgr3NCBAYEF1+iOo6y9 +8yUUsTyN3bqx3biFVQHWVP6iHI7WPBazFOZOyyjc3gcRD6M5LVPBIc5Ar+zcKNzL +b8ZTW4G1T4fye5XXPS+Zu2IHjIBAPoXQVhKZjWfmpPmloF+hphF5l8L7ilDfsj3o +1qo88XzGVUjkR5fF5UE/6iuiiipXsLRtEvsYSYMvvLuKWGN+e0t3JwvfH0JnAURK +/KKOixhqnbGcnrwVY1bzgFo3u9NSQjjYREvu6QBEthuLtPkc+PCR+DxjBmdh1der +7Bwwnfa3AgKbbtoZhlkPAgMBAAGjYjBgMB4GA1UdEQQXMBWCE25ld190ZXN0X3Rs +c19zZXJ2ZXIwHQYDVR0OBBYEFG2WT0EOXqPY2QiWTxtb/detOQUDMB8GA1UdIwQY +MBaAFOGCi133CzavIQRoqnb5Ew5ZXwPuMA0GCSqGSIb3DQEBCwUAA4IBAQBKvVh0 +uzdlPkGrkU56hVOvNe2QqKXHbz0xRVeNn/rXItUnV3YbzuiNpyjkHGPBMsDtgri2 +YUf0dKfVr8+Zyr0Yc/Nhbe2gWezGMnoOo9dw6An0r4vSYmJdSaO/s5hH7/orHQxS +zCRN+6iwURT6r1quJDxJLcsA6nzOvLdQnMxTKcak/V6A7eBpoUINdFVNhvPoXMDd +PVaju1U00SEbun8Qgeh/yWz4CPQYgQqKUORkPf0ToK5V3jrbIuW9VfQi8VcOzCn9 +YPihAEzkhh+PG8FYwK3vc6u2qKNlcbEuMu6rOQTUDWAi6+PJY5ClHQYdnb4/ThjT +vcP3w3j3YhSd/9iA +-----END CERTIFICATE----- diff --git a/myserver.key b/myserver.key new file mode 100644 index 0000000000..3cad67bdc9 --- /dev/null +++ b/myserver.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCh86dsAI7FzJxh +KykW5uzHuz9NGbmzq8G9ndUdIwTHYmawTTgr3NCBAYEF1+iOo6y98yUUsTyN3bqx +3biFVQHWVP6iHI7WPBazFOZOyyjc3gcRD6M5LVPBIc5Ar+zcKNzLb8ZTW4G1T4fy +e5XXPS+Zu2IHjIBAPoXQVhKZjWfmpPmloF+hphF5l8L7ilDfsj3o1qo88XzGVUjk +R5fF5UE/6iuiiipXsLRtEvsYSYMvvLuKWGN+e0t3JwvfH0JnAURK/KKOixhqnbGc +nrwVY1bzgFo3u9NSQjjYREvu6QBEthuLtPkc+PCR+DxjBmdh1der7Bwwnfa3AgKb +btoZhlkPAgMBAAECggEAP5vQA8L6UKUrPJzzoAumL1KTq8gxYGjTCRMvS6jf7SHw +fElwCQZLHIhHMVDahf+yTs7rnwN36a6Pb+HKYg//zzuF4Y0+6tUiA0dvp73yuEE6 +XFCchs4PSdlpxY1zhgtEoWCu8DmOKfTpS+uPcEEXa5WmDJn6G4GTFD9iQc5A410D +oBf0ONw7X8nE1ZBZr6dpJBdsP68pRJC8BfhTH/dS3d4I4JYb2BgLER1ZbMqfFeW/ +sAZ3FKKETdYvCgLb380/Xpb08FRAHlQ1MowEpfe2sNBqsnkHjESExMIP8Ne7O+ts +9IUIGHZkKIl9u/B/RHCve8Db3GM9F/lMjJ9p84FEXQKBgQDTzYX+9FyAZt5NGPwW +5mTqlh5EHLZzgnVGo2DySu0Zi7MN/YYKV1wAT3i6cTATMjjdSYu2u6L1VYhfIYYq +43MIcsHe7XMAQxbQ6l6oULUa77huMzC0Js0l08kV/ERkH0/nUS9JRp5FJUKR7mkH +Am2dz040MceQMITzCewwskf+jQKBgQDDvxgxBTNJYF3tN3uNLBPRcib0Kk+p2LfW +oDv43++MiyqkTejJJqMDHtYsXNivH6T7CE2U0Qf+2MonAzoVnNsEAfonS19okn8c +LqkMlTZmiT9Tld+h+pcAsf7lYYXSuZv10lgXSN2nj8LBm/EM130ShzyrM58vCGRC +/fDPu9ZNCwKBgQCnuWdVILlnzQ5ZS2HF2Kktw7cwBPTOwA6S46pP9NmRkzk16QAO +jGOEs2pNanjBmtHBGw6SpEBFu3gErY2LxRZBKG8yVCLvoDEfO5m9/DuOmysXyV3W +K6vlOrNQv7aA+vLRoU6q3ktTQlBXM87kCB46DAJH/uuj2WhO9hqd7XBpuQKBgFCG +/9vCyOuJ0noxVgmotWp3rKDL+0PjXRXVi3aCIZlO8zbuujJuS6eP+wn7FEVPHl8L +dmcfa0ujQd60zCNyCQPoEFI0BscNZW9hnrgHdn7OPZgUUxDe91oY38TbzuL26rtB +Um4Z0t4JHVTq40qmJ9UEf6fqr7T4nc6Vi4jaPHorAoGAL1hVy8oYAKtJCTlRQalw +apM3ZJUlTK7qfkjajPEvmhuHntplHDkGEe5ZROUu3zluDiS7MHzOYtunitoMaZbG +cRMO34aDO/UXoLdUWabuk81e3/AWgs6wHVFBOpRAYKAQzigrmXanMclwiL0V5T9K +IgP5i6aUi4zduiV1YLHj4UA= +-----END PRIVATE KEY----- diff --git a/pub_client.json5 b/pub_client.json5 new file mode 100644 index 0000000000..b75f75fa16 --- /dev/null +++ b/pub_client.json5 @@ -0,0 +1,431 @@ +/// This file attempts to list and document available configuration elements. +/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. +/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. +{ + /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) + /// that zenoh runtime will use. + /// If not set, a random unsigned 128bit integer will be used. + /// WARNING: this id must be unique in your zenoh network. + // id: "1234567890abcdef", + /// The node's mode (router, peer or client) + mode: "client", + /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ + metadata: { + name: "strawberry", + location: "Penny Lane" + }, + /// Which endpoints to connect to. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: + /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 + connect: { + endpoints: [ + // "/
" + "quic/127.0.0.1:7447" + + ], + }, + /// Which endpoints to listen on. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, + /// peers, or client can use to establish a zenoh session. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: + /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 + listen: { + endpoints: [ + // "/
" + ], + }, + /// Configure the scouting mechanisms and their behaviours + scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 3000, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 200, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: true, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: true, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: true, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + /// Configuration of data messages timestamps management. + timestamping: { + /// Whether data messages should be timestamped if not already. + /// Accepts a single boolean value or different values for router, peer and client. + enabled: { router: true, peer: false, client: false + }, + /// Whether data messages with timestamps in the future should be dropped or not. + /// If set to false (default), messages with timestamps in the future are retimestamped. + /// Timestamps are ignored if timestamping is disabled. + drop_future_timestamp: false, + }, + /// The default timeout to apply to queries in milliseconds. + queries_default_timeout: 10000, + /// The routing strategy to use and it's configuration. + routing: { + /// The routing strategy to use in routers and it's configuration. + router: { + /// When set to true a router will forward data between two peers + /// directly connected to it if it detects that those peers are not + /// connected to each other. + /// The failover brokering only works if gossip discovery is enabled. + peers_failover_brokering: true, + }, + /// The routing strategy to use in peers and it's configuration. + peer: { + /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). + mode: "peer_to_peer", + }, + }, + // /// The declarations aggregation strategy. + // aggregation: { + // /// A list of key-expressions for which all included subscribers will be aggregated into. + // subscribers: [ + // // key_expression + // ], + // /// A list of key-expressions for which all included publishers will be aggregated into. + // publishers: [ + // // key_expression + // ], + // }, + // /// The downsampling declaration. + // downsampling: [ + // { + // /// A list of network interfaces messages will be processed on, the rest will be passed as is. + // interfaces: [ "wlan0" ], + // /// Data flow messages will be processed on. ("egress" or "ingress") + // flow: "egress", + // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz + // rules: [ + // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, + // ], + // }, + // ], + /// Configure internal transport parameters + transport: { + unicast: { + /// Timeout in milliseconds when opening a link + accept_timeout: 10000, + /// Maximum number of zenoh session in pending state while accepting + accept_pending: 100, + /// Maximum number of sessions that can be simultaneously alive + max_sessions: 1000, + /// Maximum number of incoming links that are admitted per session + max_links: 1, + /// Enables the LowLatency transport + /// This option does not make LowLatency transport mandatory, the actual implementation of transport + /// used will depend on Establish procedure and other party's settings + /// + /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. + /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to + /// enable 'lowlatency' you need to explicitly disable 'qos'. + lowlatency: false, + /// Enables QoS on unicast communications. + qos: { + enabled: true, + }, + /// Enables compression on unicast communications. + /// Compression capabilities are negotiated during session establishment. + /// If both Zenoh nodes support compression, then compression is activated. + compression: { + enabled: false, + }, + }, + multicast: { + /// Enables QoS on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + qos: { + enabled: false, + }, + /// Enables compression on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + compression: { + enabled: false, + }, + }, + link: { + /// An optional whitelist of protocols to be used for accepting and opening sessions. + /// If not configured, all the supported protocols are automatically whitelisted. + /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + /// For example, to only enable "tls" and "quic": + // protocols: ["tls", "quic"], + /// Configure the zenoh TX parameters of a link + tx: { + /// The resolution in bits to be used for the message sequence numbers. + /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: "32bit", + /// Link lease duration in milliseconds to announce to other zenoh nodes + lease: 10000, + /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive + /// messages will be sent at the configured time interval. + /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, + /// set the actual keep_alive timeout to one fourth of the lease time. + /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity + /// check which considers a link as failed when no messages are received in 3.5 times the + /// target interval. + keep_alive: 4, + /// Batch size in bytes is expressed as a 16bit unsigned integer. + /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). + /// The default batch size value is the maximum batch size: 65535. + batch_size: 65535, + /// Each zenoh link has a transmission queue that can be configured + queue: { + /// The size of each priority queue indicates the number of batches a given queue can contain. + /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. + /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, + /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. + /// If qos is false, then only the DATA priority will be allocated. + size: { + control: 1, + real_time: 1, + interactive_high: 1, + interactive_low: 1, + data_high: 2, + data: 4, + data_low: 4, + background: 4, + }, + /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. + /// Higher values lead to a more aggressive batching but it will introduce additional latency. + backoff: 100, + }, + // Number of threads dedicated to transmission + // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) + // threads: 4, + }, + /// Configure the zenoh RX parameters of a link + rx: { + /// Receiving buffer size in bytes for each link + /// The default the rx_buffer_size value is the same as the default batch size: 65335. + /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate + /// more in-flight data. This is particularly relevant when dealing with large messages. + /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. + buffer_size: 65535, + /// Maximum size of the defragmentation buffer at receiver end. + /// Fragmented messages that are larger than the configured size will be dropped. + /// The default value is 1GiB. This would work in most scenarios. + /// NOTE: reduce the value if you are operating on a memory constrained device. + max_message_size: 1073741824, + }, + /// Configure TLS specific parameters + tls: { + root_ca_certificate: "ca.crt" + } + // tls: { + // /// Path to the certificate of the certificate authority used to validate either the server + // /// or the client's keys and certificates, depending on the node's mode. If not specified + // /// on router mode then the default WebPKI certificates are used instead. + // root_ca_certificate: null, + // /// Path to the TLS server private key + // server_private_key: null, + // /// Path to the TLS server public certificate + // server_certificate: null, + // /// Client authentication, if true enables mTLS (mutual authentication) + // client_auth: false, + // /// Path to the TLS client private key + // client_private_key: null, + // /// Path to the TLS client public certificate + // client_certificate: null, + // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + // server_name_verification: null, + // }, + }, + /// Shared memory configuration + shared_memory: { + enabled: false, + }, + /// Access control configuration + auth: { + /// The configuration of authentification. + /// A password implies a username is required. + usrpwd: { + user: null, + password: null, + /// The path to a file containing the user password dictionary + dictionary_file: null, + }, + pubkey: { + public_key_pem: null, + private_key_pem: null, + public_key_file: null, + private_key_file: null, + key_size: null, + known_keys_file: null, + }, + }, + }, + /// Configure the Admin Space + /// Unstable: this configuration part works as advertised, but may change in a future release + adminspace: { + // read and/or write permissions on the admin space + permissions: { + read: true, + write: false, + }, + }, + /// + /// Plugins configurations + /// + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // plugins_search_dirs: [], + // /// Plugins are only loaded if present in the configuration. When starting + // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. + // plugins: { + // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) + // + // /// Plugin settings may contain field `__config__` + // /// - If `__config__` is specified, it's content is merged into plugin configuration + // /// - Properties loaded from `__config__` file overrides existing properties + // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively + // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config + // /// + // /// See below exapmle of plugin configuration using `__config__` property + // + // /// Configure the REST API plugin + // rest: { + // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. + // __required__: true, // defaults to false + // /// load configuration from the file + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // /// http port to answer to rest requests + // http_port: 8000, + // }, + // + // /// Configure the storage manager plugin + // storage_manager: { + // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. + // __path__: [ + // "./target/release/libzenoh_plugin_storage_manager.so", + // "./target/release/libzenoh_plugin_storage_manager.dylib", + // ], + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // backend_search_dirs: [], + // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. + // volumes: { + // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb + // influxdb: { + // url: "https://myinfluxdb.example", + // /// Some plugins may need passwords in their configuration. + // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. + // /// any value held at the key "private" will not be shown in the adminspace. + // private: { + // username: "user1", + // password: "pw1", + // }, + // }, + // influxdb2: { + // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. + // backend: "influxdb", + // private: { + // username: "user2", + // password: "pw2", + // }, + // url: "https://localhost:8086", + // }, + // }, + // + // /// Configure the storages supported by the volumes + // storages: { + // demo: { + // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. + // key_expr: "demo/memory/**", + // /// Storages also need to know which volume will be used to actually store their key-value pairs. + // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. + // volume: "memory", + // }, + // demo2: { + // key_expr: "demo/memory2/**", + // volume: "memory", + // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. + // /// Metadata includes the set of wild card updates and deletions (tombstones). + // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. + // garbage_collection: { + // /// The garbage collection event will be periodic with this duration. + // /// The duration is specified in seconds. + // period: 30, + // /// Metadata older than this parameter will be garbage collected. + // /// The duration is specified in seconds. + // lifespan: 86400, + // }, + // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. + // /// In the absence of this configuration, a normal storage is initialized + // /// Note: all the samples to be stored in replicas should be timestamped + // replica_config: { + // /// Specifying the parameters is optional, by default the values provided will be used. + // /// Time interval between different synchronization attempts in seconds + // publication_interval: 5, + // /// Expected propagation delay of the network in milliseconds + // propagation_delay: 200, + // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. + // /// Higher the frequency of updates, lower the delta should be chosen + // /// To be efficient, delta should be the time containing no more than 100,000 samples + // delta: 1000, + // } + // }, + // demo3: { + // key_expr: "demo/memory3/**", + // volume: "memory", + // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. + // /// If not configured, complete defaults to false. + // complete: "true", + // }, + // influx_demo: { + // key_expr: "demo/influxdb/**", + // /// This prefix will be stripped of the received keys when storing. + // strip_prefix: "demo/influxdb", + // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: + // volume: { + // id: "influxdb", + // db: "example", + // }, + // }, + // influx_demo2: { + // key_expr: "demo/influxdb2/**", + // strip_prefix: "demo/influxdb2", + // volume: { + // id: "influxdb2", + // db: "example", + // }, + // }, + // }, + // }, + // }, + // /// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // } + // }, +} \ No newline at end of file diff --git a/router.json5 b/router.json5 new file mode 100644 index 0000000000..46817ee4b4 --- /dev/null +++ b/router.json5 @@ -0,0 +1,431 @@ +/// This file attempts to list and document available configuration elements. +/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. +/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. +{ + /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) + /// that zenoh runtime will use. + /// If not set, a random unsigned 128bit integer will be used. + /// WARNING: this id must be unique in your zenoh network. + // id: "1234567890abcdef", + /// The node's mode (router, peer or client) + mode: "router", + /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ + metadata: { + name: "strawberry", + location: "Penny Lane" + }, + /// Which endpoints to connect to. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: + /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 + connect: { + endpoints: [ + // "/
" + ], + }, + /// Which endpoints to listen on. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, + /// peers, or client can use to establish a zenoh session. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: + /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 + listen: { + endpoints: [ + // "/
" + "quic/127.0.0.1:7447" + ], + }, + /// Configure the scouting mechanisms and their behaviours + scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 3000, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 200, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: true, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: true, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: true, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + /// Configuration of data messages timestamps management. + timestamping: { + /// Whether data messages should be timestamped if not already. + /// Accepts a single boolean value or different values for router, peer and client. + enabled: { router: true, peer: false, client: false + }, + /// Whether data messages with timestamps in the future should be dropped or not. + /// If set to false (default), messages with timestamps in the future are retimestamped. + /// Timestamps are ignored if timestamping is disabled. + drop_future_timestamp: false, + }, + /// The default timeout to apply to queries in milliseconds. + queries_default_timeout: 10000, + /// The routing strategy to use and it's configuration. + routing: { + /// The routing strategy to use in routers and it's configuration. + router: { + /// When set to true a router will forward data between two peers + /// directly connected to it if it detects that those peers are not + /// connected to each other. + /// The failover brokering only works if gossip discovery is enabled. + peers_failover_brokering: true, + }, + /// The routing strategy to use in peers and it's configuration. + peer: { + /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). + mode: "peer_to_peer", + }, + }, + // /// The declarations aggregation strategy. + // aggregation: { + // /// A list of key-expressions for which all included subscribers will be aggregated into. + // subscribers: [ + // // key_expression + // ], + // /// A list of key-expressions for which all included publishers will be aggregated into. + // publishers: [ + // // key_expression + // ], + // }, + // /// The downsampling declaration. + // downsampling: [ + // { + // /// A list of network interfaces messages will be processed on, the rest will be passed as is. + // interfaces: [ "wlan0" ], + // /// Data flow messages will be processed on. ("egress" or "ingress") + // flow: "egress", + // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz + // rules: [ + // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, + // ], + // }, + // ], + /// Configure internal transport parameters + transport: { + unicast: { + /// Timeout in milliseconds when opening a link + accept_timeout: 10000, + /// Maximum number of zenoh session in pending state while accepting + accept_pending: 100, + /// Maximum number of sessions that can be simultaneously alive + max_sessions: 1000, + /// Maximum number of incoming links that are admitted per session + max_links: 1, + /// Enables the LowLatency transport + /// This option does not make LowLatency transport mandatory, the actual implementation of transport + /// used will depend on Establish procedure and other party's settings + /// + /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. + /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to + /// enable 'lowlatency' you need to explicitly disable 'qos'. + lowlatency: false, + /// Enables QoS on unicast communications. + qos: { + enabled: true, + }, + /// Enables compression on unicast communications. + /// Compression capabilities are negotiated during session establishment. + /// If both Zenoh nodes support compression, then compression is activated. + compression: { + enabled: false, + }, + }, + multicast: { + /// Enables QoS on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + qos: { + enabled: false, + }, + /// Enables compression on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + compression: { + enabled: false, + }, + }, + link: { + /// An optional whitelist of protocols to be used for accepting and opening sessions. + /// If not configured, all the supported protocols are automatically whitelisted. + /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + /// For example, to only enable "tls" and "quic": + // protocols: ["tls", "quic"], + /// Configure the zenoh TX parameters of a link + tx: { + /// The resolution in bits to be used for the message sequence numbers. + /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: "32bit", + /// Link lease duration in milliseconds to announce to other zenoh nodes + lease: 10000, + /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive + /// messages will be sent at the configured time interval. + /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, + /// set the actual keep_alive timeout to one fourth of the lease time. + /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity + /// check which considers a link as failed when no messages are received in 3.5 times the + /// target interval. + keep_alive: 4, + /// Batch size in bytes is expressed as a 16bit unsigned integer. + /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). + /// The default batch size value is the maximum batch size: 65535. + batch_size: 65535, + /// Each zenoh link has a transmission queue that can be configured + queue: { + /// The size of each priority queue indicates the number of batches a given queue can contain. + /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. + /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, + /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. + /// If qos is false, then only the DATA priority will be allocated. + size: { + control: 1, + real_time: 1, + interactive_high: 1, + interactive_low: 1, + data_high: 2, + data: 4, + data_low: 4, + background: 4, + }, + /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. + /// Higher values lead to a more aggressive batching but it will introduce additional latency. + backoff: 100, + }, + // Number of threads dedicated to transmission + // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) + // threads: 4, + }, + /// Configure the zenoh RX parameters of a link + rx: { + /// Receiving buffer size in bytes for each link + /// The default the rx_buffer_size value is the same as the default batch size: 65335. + /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate + /// more in-flight data. This is particularly relevant when dealing with large messages. + /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. + buffer_size: 65535, + /// Maximum size of the defragmentation buffer at receiver end. + /// Fragmented messages that are larger than the configured size will be dropped. + /// The default value is 1GiB. This would work in most scenarios. + /// NOTE: reduce the value if you are operating on a memory constrained device. + max_message_size: 1073741824, + }, + /// Configure TLS specific parameters + tls: { + server_private_key: "myserver.key", + server_certificate: "myserver.crt" + } + // tls: { + // /// Path to the certificate of the certificate authority used to validate either the server + // /// or the client's keys and certificates, depending on the node's mode. If not specified + // /// on router mode then the default WebPKI certificates are used instead. + // root_ca_certificate: null, + // /// Path to the TLS server private key + // server_private_key: null, + // /// Path to the TLS server public certificate + // server_certificate: null, + // /// Client authentication, if true enables mTLS (mutual authentication) + // client_auth: false, + // /// Path to the TLS client private key + // client_private_key: null, + // /// Path to the TLS client public certificate + // client_certificate: null, + // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + // server_name_verification: null, + // }, + }, + /// Shared memory configuration + shared_memory: { + enabled: false, + }, + /// Access control configuration + auth: { + /// The configuration of authentication. + /// A password implies a username is required. + usrpwd: { + user: null, + password: null, + /// The path to a file containing the user password dictionary + dictionary_file: null, + }, + pubkey: { + public_key_pem: null, + private_key_pem: null, + public_key_file: null, + private_key_file: null, + key_size: null, + known_keys_file: null, + }, + }, + }, + /// Configure the Admin Space + /// Unstable: this configuration part works as advertised, but may change in a future release + adminspace: { + // read and/or write permissions on the admin space + permissions: { + read: true, + write: false, + }, + }, + /// + /// Plugins configurations + /// + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // plugins_search_dirs: [], + // /// Plugins are only loaded if present in the configuration. When starting + // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. + // plugins: { + // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) + // + // /// Plugin settings may contain field `__config__` + // /// - If `__config__` is specified, it's content is merged into plugin configuration + // /// - Properties loaded from `__config__` file overrides existing properties + // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively + // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config + // /// + // /// See below exapmle of plugin configuration using `__config__` property + // + // /// Configure the REST API plugin + // rest: { + // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. + // __required__: true, // defaults to false + // /// load configuration from the file + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // /// http port to answer to rest requests + // http_port: 8000, + // }, + // + // /// Configure the storage manager plugin + // storage_manager: { + // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. + // __path__: [ + // "./target/release/libzenoh_plugin_storage_manager.so", + // "./target/release/libzenoh_plugin_storage_manager.dylib", + // ], + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // backend_search_dirs: [], + // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. + // volumes: { + // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb + // influxdb: { + // url: "https://myinfluxdb.example", + // /// Some plugins may need passwords in their configuration. + // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. + // /// any value held at the key "private" will not be shown in the adminspace. + // private: { + // username: "user1", + // password: "pw1", + // }, + // }, + // influxdb2: { + // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. + // backend: "influxdb", + // private: { + // username: "user2", + // password: "pw2", + // }, + // url: "https://localhost:8086", + // }, + // }, + // + // /// Configure the storages supported by the volumes + // storages: { + // demo: { + // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. + // key_expr: "demo/memory/**", + // /// Storages also need to know which volume will be used to actually store their key-value pairs. + // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. + // volume: "memory", + // }, + // demo2: { + // key_expr: "demo/memory2/**", + // volume: "memory", + // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. + // /// Metadata includes the set of wild card updates and deletions (tombstones). + // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. + // garbage_collection: { + // /// The garbage collection event will be periodic with this duration. + // /// The duration is specified in seconds. + // period: 30, + // /// Metadata older than this parameter will be garbage collected. + // /// The duration is specified in seconds. + // lifespan: 86400, + // }, + // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. + // /// In the absence of this configuration, a normal storage is initialized + // /// Note: all the samples to be stored in replicas should be timestamped + // replica_config: { + // /// Specifying the parameters is optional, by default the values provided will be used. + // /// Time interval between different synchronization attempts in seconds + // publication_interval: 5, + // /// Expected propagation delay of the network in milliseconds + // propagation_delay: 200, + // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. + // /// Higher the frequency of updates, lower the delta should be chosen + // /// To be efficient, delta should be the time containing no more than 100,000 samples + // delta: 1000, + // } + // }, + // demo3: { + // key_expr: "demo/memory3/**", + // volume: "memory", + // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. + // /// If not configured, complete defaults to false. + // complete: "true", + // }, + // influx_demo: { + // key_expr: "demo/influxdb/**", + // /// This prefix will be stripped of the received keys when storing. + // strip_prefix: "demo/influxdb", + // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: + // volume: { + // id: "influxdb", + // db: "example", + // }, + // }, + // influx_demo2: { + // key_expr: "demo/influxdb2/**", + // strip_prefix: "demo/influxdb2", + // volume: { + // id: "influxdb2", + // db: "example", + // }, + // }, + // }, + // }, + // }, + // /// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // } + // }, +} \ No newline at end of file diff --git a/sub_client.json5 b/sub_client.json5 new file mode 100644 index 0000000000..b75f75fa16 --- /dev/null +++ b/sub_client.json5 @@ -0,0 +1,431 @@ +/// This file attempts to list and document available configuration elements. +/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. +/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. +{ + /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) + /// that zenoh runtime will use. + /// If not set, a random unsigned 128bit integer will be used. + /// WARNING: this id must be unique in your zenoh network. + // id: "1234567890abcdef", + /// The node's mode (router, peer or client) + mode: "client", + /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ + metadata: { + name: "strawberry", + location: "Penny Lane" + }, + /// Which endpoints to connect to. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: + /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 + connect: { + endpoints: [ + // "/
" + "quic/127.0.0.1:7447" + + ], + }, + /// Which endpoints to listen on. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, + /// peers, or client can use to establish a zenoh session. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: + /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 + listen: { + endpoints: [ + // "/
" + ], + }, + /// Configure the scouting mechanisms and their behaviours + scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 3000, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 200, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: true, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: true, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: true, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + /// Configuration of data messages timestamps management. + timestamping: { + /// Whether data messages should be timestamped if not already. + /// Accepts a single boolean value or different values for router, peer and client. + enabled: { router: true, peer: false, client: false + }, + /// Whether data messages with timestamps in the future should be dropped or not. + /// If set to false (default), messages with timestamps in the future are retimestamped. + /// Timestamps are ignored if timestamping is disabled. + drop_future_timestamp: false, + }, + /// The default timeout to apply to queries in milliseconds. + queries_default_timeout: 10000, + /// The routing strategy to use and it's configuration. + routing: { + /// The routing strategy to use in routers and it's configuration. + router: { + /// When set to true a router will forward data between two peers + /// directly connected to it if it detects that those peers are not + /// connected to each other. + /// The failover brokering only works if gossip discovery is enabled. + peers_failover_brokering: true, + }, + /// The routing strategy to use in peers and it's configuration. + peer: { + /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). + mode: "peer_to_peer", + }, + }, + // /// The declarations aggregation strategy. + // aggregation: { + // /// A list of key-expressions for which all included subscribers will be aggregated into. + // subscribers: [ + // // key_expression + // ], + // /// A list of key-expressions for which all included publishers will be aggregated into. + // publishers: [ + // // key_expression + // ], + // }, + // /// The downsampling declaration. + // downsampling: [ + // { + // /// A list of network interfaces messages will be processed on, the rest will be passed as is. + // interfaces: [ "wlan0" ], + // /// Data flow messages will be processed on. ("egress" or "ingress") + // flow: "egress", + // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz + // rules: [ + // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, + // ], + // }, + // ], + /// Configure internal transport parameters + transport: { + unicast: { + /// Timeout in milliseconds when opening a link + accept_timeout: 10000, + /// Maximum number of zenoh session in pending state while accepting + accept_pending: 100, + /// Maximum number of sessions that can be simultaneously alive + max_sessions: 1000, + /// Maximum number of incoming links that are admitted per session + max_links: 1, + /// Enables the LowLatency transport + /// This option does not make LowLatency transport mandatory, the actual implementation of transport + /// used will depend on Establish procedure and other party's settings + /// + /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. + /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to + /// enable 'lowlatency' you need to explicitly disable 'qos'. + lowlatency: false, + /// Enables QoS on unicast communications. + qos: { + enabled: true, + }, + /// Enables compression on unicast communications. + /// Compression capabilities are negotiated during session establishment. + /// If both Zenoh nodes support compression, then compression is activated. + compression: { + enabled: false, + }, + }, + multicast: { + /// Enables QoS on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + qos: { + enabled: false, + }, + /// Enables compression on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + compression: { + enabled: false, + }, + }, + link: { + /// An optional whitelist of protocols to be used for accepting and opening sessions. + /// If not configured, all the supported protocols are automatically whitelisted. + /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + /// For example, to only enable "tls" and "quic": + // protocols: ["tls", "quic"], + /// Configure the zenoh TX parameters of a link + tx: { + /// The resolution in bits to be used for the message sequence numbers. + /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: "32bit", + /// Link lease duration in milliseconds to announce to other zenoh nodes + lease: 10000, + /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive + /// messages will be sent at the configured time interval. + /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, + /// set the actual keep_alive timeout to one fourth of the lease time. + /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity + /// check which considers a link as failed when no messages are received in 3.5 times the + /// target interval. + keep_alive: 4, + /// Batch size in bytes is expressed as a 16bit unsigned integer. + /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). + /// The default batch size value is the maximum batch size: 65535. + batch_size: 65535, + /// Each zenoh link has a transmission queue that can be configured + queue: { + /// The size of each priority queue indicates the number of batches a given queue can contain. + /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. + /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, + /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. + /// If qos is false, then only the DATA priority will be allocated. + size: { + control: 1, + real_time: 1, + interactive_high: 1, + interactive_low: 1, + data_high: 2, + data: 4, + data_low: 4, + background: 4, + }, + /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. + /// Higher values lead to a more aggressive batching but it will introduce additional latency. + backoff: 100, + }, + // Number of threads dedicated to transmission + // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) + // threads: 4, + }, + /// Configure the zenoh RX parameters of a link + rx: { + /// Receiving buffer size in bytes for each link + /// The default the rx_buffer_size value is the same as the default batch size: 65335. + /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate + /// more in-flight data. This is particularly relevant when dealing with large messages. + /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. + buffer_size: 65535, + /// Maximum size of the defragmentation buffer at receiver end. + /// Fragmented messages that are larger than the configured size will be dropped. + /// The default value is 1GiB. This would work in most scenarios. + /// NOTE: reduce the value if you are operating on a memory constrained device. + max_message_size: 1073741824, + }, + /// Configure TLS specific parameters + tls: { + root_ca_certificate: "ca.crt" + } + // tls: { + // /// Path to the certificate of the certificate authority used to validate either the server + // /// or the client's keys and certificates, depending on the node's mode. If not specified + // /// on router mode then the default WebPKI certificates are used instead. + // root_ca_certificate: null, + // /// Path to the TLS server private key + // server_private_key: null, + // /// Path to the TLS server public certificate + // server_certificate: null, + // /// Client authentication, if true enables mTLS (mutual authentication) + // client_auth: false, + // /// Path to the TLS client private key + // client_private_key: null, + // /// Path to the TLS client public certificate + // client_certificate: null, + // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + // server_name_verification: null, + // }, + }, + /// Shared memory configuration + shared_memory: { + enabled: false, + }, + /// Access control configuration + auth: { + /// The configuration of authentification. + /// A password implies a username is required. + usrpwd: { + user: null, + password: null, + /// The path to a file containing the user password dictionary + dictionary_file: null, + }, + pubkey: { + public_key_pem: null, + private_key_pem: null, + public_key_file: null, + private_key_file: null, + key_size: null, + known_keys_file: null, + }, + }, + }, + /// Configure the Admin Space + /// Unstable: this configuration part works as advertised, but may change in a future release + adminspace: { + // read and/or write permissions on the admin space + permissions: { + read: true, + write: false, + }, + }, + /// + /// Plugins configurations + /// + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // plugins_search_dirs: [], + // /// Plugins are only loaded if present in the configuration. When starting + // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. + // plugins: { + // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) + // + // /// Plugin settings may contain field `__config__` + // /// - If `__config__` is specified, it's content is merged into plugin configuration + // /// - Properties loaded from `__config__` file overrides existing properties + // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively + // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config + // /// + // /// See below exapmle of plugin configuration using `__config__` property + // + // /// Configure the REST API plugin + // rest: { + // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. + // __required__: true, // defaults to false + // /// load configuration from the file + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // /// http port to answer to rest requests + // http_port: 8000, + // }, + // + // /// Configure the storage manager plugin + // storage_manager: { + // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. + // __path__: [ + // "./target/release/libzenoh_plugin_storage_manager.so", + // "./target/release/libzenoh_plugin_storage_manager.dylib", + // ], + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // backend_search_dirs: [], + // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. + // volumes: { + // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb + // influxdb: { + // url: "https://myinfluxdb.example", + // /// Some plugins may need passwords in their configuration. + // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. + // /// any value held at the key "private" will not be shown in the adminspace. + // private: { + // username: "user1", + // password: "pw1", + // }, + // }, + // influxdb2: { + // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. + // backend: "influxdb", + // private: { + // username: "user2", + // password: "pw2", + // }, + // url: "https://localhost:8086", + // }, + // }, + // + // /// Configure the storages supported by the volumes + // storages: { + // demo: { + // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. + // key_expr: "demo/memory/**", + // /// Storages also need to know which volume will be used to actually store their key-value pairs. + // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. + // volume: "memory", + // }, + // demo2: { + // key_expr: "demo/memory2/**", + // volume: "memory", + // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. + // /// Metadata includes the set of wild card updates and deletions (tombstones). + // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. + // garbage_collection: { + // /// The garbage collection event will be periodic with this duration. + // /// The duration is specified in seconds. + // period: 30, + // /// Metadata older than this parameter will be garbage collected. + // /// The duration is specified in seconds. + // lifespan: 86400, + // }, + // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. + // /// In the absence of this configuration, a normal storage is initialized + // /// Note: all the samples to be stored in replicas should be timestamped + // replica_config: { + // /// Specifying the parameters is optional, by default the values provided will be used. + // /// Time interval between different synchronization attempts in seconds + // publication_interval: 5, + // /// Expected propagation delay of the network in milliseconds + // propagation_delay: 200, + // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. + // /// Higher the frequency of updates, lower the delta should be chosen + // /// To be efficient, delta should be the time containing no more than 100,000 samples + // delta: 1000, + // } + // }, + // demo3: { + // key_expr: "demo/memory3/**", + // volume: "memory", + // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. + // /// If not configured, complete defaults to false. + // complete: "true", + // }, + // influx_demo: { + // key_expr: "demo/influxdb/**", + // /// This prefix will be stripped of the received keys when storing. + // strip_prefix: "demo/influxdb", + // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: + // volume: { + // id: "influxdb", + // db: "example", + // }, + // }, + // influx_demo2: { + // key_expr: "demo/influxdb2/**", + // strip_prefix: "demo/influxdb2", + // volume: { + // id: "influxdb2", + // db: "example", + // }, + // }, + // }, + // }, + // }, + // /// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // } + // }, +} \ No newline at end of file From 3c84e5939315774135e8d0451723f8b738e86d59 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Wed, 13 Mar 2024 13:27:09 +0100 Subject: [PATCH 02/37] testing cert names --- Cargo.lock | 113 +++ ca.key | 28 + credentials.txt | 2 + io/zenoh-link-commons/src/unicast.rs | 6 + io/zenoh-links/zenoh-link-quic/Cargo.toml | 1 + .../zenoh-link-quic/src/unicast-modified.rs | 662 +++++++++++++ io/zenoh-links/zenoh-link-tls/Cargo.toml | 3 +- .../zenoh-link-tls/src/unicast-modified.rs | 916 ++++++++++++++++++ io/zenoh-links/zenoh-link-tls/src/unicast.rs | 46 +- mypub.crt | 22 + mypub.key | 28 + mysub.crt | 22 + mysub.csr | 16 + mysub.key | 28 + newmyserver.crt | 22 + newmyserver.key | 28 + pub_client.json5 | 3 +- router.json5 | 2 +- sub_client.json5 | 3 +- 19 files changed, 1944 insertions(+), 7 deletions(-) create mode 100644 ca.key create mode 100644 credentials.txt create mode 100644 io/zenoh-links/zenoh-link-quic/src/unicast-modified.rs create mode 100644 io/zenoh-links/zenoh-link-tls/src/unicast-modified.rs create mode 100644 mypub.crt create mode 100644 mypub.key create mode 100644 mysub.crt create mode 100644 mysub.csr create mode 100644 mysub.key create mode 100644 newmyserver.crt create mode 100644 newmyserver.key diff --git a/Cargo.lock b/Cargo.lock index 1d5fab2365..c41f9a9959 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,6 +235,45 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "asn1-rs" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ad1373757efa0f70ec53939aabc7152e1591cb485208052993070ac8d2429d" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom", + "num-traits", + "rusticata-macros", + "thiserror", + "time 0.3.28", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7378575ff571966e99a744addeff0bff98b8ada0dedf1956d59e634db95eaac1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.33", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.33", +] + [[package]] name = "async-attributes" version = "1.1.2" @@ -1011,6 +1050,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + [[package]] name = "deranged" version = "0.3.8" @@ -1089,6 +1142,17 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.33", +] + [[package]] name = "dyn-clone" version = "1.0.13" @@ -2137,6 +2201,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "oid-registry" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d" +dependencies = [ + "asn1-rs", +] + [[package]] name = "once_cell" version = "1.18.0" @@ -2775,6 +2848,15 @@ dependencies = [ "semver 1.0.18", ] +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom", +] + [[package]] name = "rustix" version = "0.37.25" @@ -3465,6 +3547,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.33", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -3539,6 +3632,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", + "itoa", "serde", "time-core", "time-macros 0.2.14", @@ -4283,6 +4377,23 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +[[package]] +name = "x509-parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "thiserror", + "time 0.3.28", +] + [[package]] name = "yasna" version = "0.5.2" @@ -4546,6 +4657,7 @@ dependencies = [ "rustls-native-certs 0.7.0", "rustls-pemfile 2.0.0", "secrecy", + "x509-parser", "zenoh-config", "zenoh-core", "zenoh-link-commons", @@ -4605,6 +4717,7 @@ dependencies = [ "rustls-webpki 0.102.0", "secrecy", "webpki-roots", + "x509-parser", "zenoh-config", "zenoh-core", "zenoh-link-commons", diff --git a/ca.key b/ca.key new file mode 100644 index 0000000000..19edffa35d --- /dev/null +++ b/ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3pFWM+IJNsRCY +Ht1v/TliecppwVZV+ZHfFw9JKN9ev4K/fWHUiAOwp91MOLxbaYKdC6dxW28YVGlt +oGz3kUZJZcJRQVso1jXv24Op4muOsiYXukLc4TU2F6dG1XqkLt5tsvsYAQFf1uK3 +//QZFVRBosJEn+jjiJ4XCvt49mnPRolp1pNKX0z31mZO6bSly6c9OVlJMjWpDCYS +Ouf6qZZ36fa9eSut2bRJIPY0QCsgnqYBTnIEhksS+3jy6Qt+QpLz95pFdLbW/MW4 +XKpaDltyYkO6QrBekF6uWRlvyAHU+NqvXZ4F/3Z5l26qLuBcsLPJkyawkO+yNIDx +ORmQgMczAgMBAAECggEAHo70g3hI6pe3zLB6JawMFARzN8Tp0nWsneRu8Twha1lP +7wB0upKFlqxgSVI5mbaFew+Y5eaSpohJYOosp8efXBBYVQAcpL98izTKhIb+Yejo +KNOgU7QQEDfAaKuWdGKuNa/uU5C7Q1D1OiwX2OKxOhjU3emELfSqZeg4b2kFs21f +KWSbgRbgKHGRavdastf9qVFBsTk3wi6tAyoBM0zy1PNm66yW1Bl4KuMXVIq4tjZp +0TOPCUwQKeOPTWQDoBq3enuyLCnSTH+jT6jOEHKMy4fCRIELYOst2KMPA2JOe/jl +d7qlgU52TNgRCs0tFV0CWNj6ShzmDm2DbMwnJbXbPQKBgQD2Wzft4ezBnkdHS5PX +Dh3DuJC5vA5KZrfCPydFAfsd1wAsJ9V1Hyt/r/sm3SfYFg73YqH4lhBrOhfCY6Ql +9s1TGHz9ulNB4TZMzBxihFgF9vjcze/GXjeLsQ6n9iCLqfWG4WFtOBGa7cAaKyBz +mxWMrXb5X5fz4XVSHw4zRNKbnwKBgQC+1KS0dlLZHO5fKvErFqvYqnFRPcCEX4iI +otkhPqe7H0U6JRFcqGDB1dWsy2XOsbUuh3Lf1IZXtWcYReF4bdnk2qo8xXD0LAmv +G0SAMN9ThSP+NZ2HugcvjaMXPbFq9tUMi4/Hx/Smo7e8d64ltcjXOtSWsNNrr8yC +EMuhS70r7QKBgQC5RZrHTRxn9Gf4p08U8enSktBMzrAUpjFWZXZcAIRhSZs4mfB/ +d6SYD7oa3UGk0doJlGTpdbn9WiAaMiN15ak+7/C4RNNufTgAA5TpRkyIl9dK/5lu +nta5OLwj9wc84eHjwUYrBHrBAEJzq7FpH93SAXazToARiqJX00Ezr3OQUwKBgQCG +clCcaCTUnGKBIEMLpYxrOSJfJ4+kc55BDeLGXltUJaLjZUxHKMYKqrpBZIgUyPUq +k/lmI1iHIOJCorFI5LQ4XarE6CI9lW05No/bdRNSx6HlLycOgg0f/r0h2bBO+Rp/ +HTCug30ljoEbwoIqRVn78ZHnnStHWnNOS8D7od3kvQKBgQCiCmFBdVYB5NxOY2KE +XlEOCdo23d/fWAen7MJlHfEsivcL5xbO4IKDIfO0szG6cEuVqEdgTotfmGZ3qYbQ +i5rDIBfho2YbHue5UfiZOv+cfCKw64wGnx0ZOfSRLjpbJh+XjeOW54nLrJTFLiW+ +/wNl+w1WfsllQiDPbK13DrW7dg== +-----END PRIVATE KEY----- diff --git a/credentials.txt b/credentials.txt new file mode 100644 index 0000000000..3045a4164c --- /dev/null +++ b/credentials.txt @@ -0,0 +1,2 @@ +clientusername:92df0d4f39c218607e3200bf93ccac87a80cb910e811d84b286bebe0a8860724 + \ No newline at end of file diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs index 1237024ca9..8aa40103cc 100644 --- a/io/zenoh-link-commons/src/unicast.rs +++ b/io/zenoh-link-commons/src/unicast.rs @@ -114,3 +114,9 @@ pub fn get_ip_interface_names(addr: &SocketAddr) -> Vec { } } } + +#[derive(Debug)] +pub struct AuthIdentifier { + pub username: Option, + pub tls_cert_name: Option, +} diff --git a/io/zenoh-links/zenoh-link-quic/Cargo.toml b/io/zenoh-links/zenoh-link-quic/Cargo.toml index 09debbaa54..ec6f5a2794 100644 --- a/io/zenoh-links/zenoh-link-quic/Cargo.toml +++ b/io/zenoh-links/zenoh-link-quic/Cargo.toml @@ -43,3 +43,4 @@ zenoh-sync = { workspace = true } zenoh-util = { workspace = true } base64 = { workspace = true } secrecy = { workspace = true } +x509-parser = "0.16.0" diff --git a/io/zenoh-links/zenoh-link-quic/src/unicast-modified.rs b/io/zenoh-links/zenoh-link-quic/src/unicast-modified.rs new file mode 100644 index 0000000000..88e3befe6c --- /dev/null +++ b/io/zenoh-links/zenoh-link-quic/src/unicast-modified.rs @@ -0,0 +1,662 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// + +use x509_parser::prelude::*; + +use crate::base64_decode; +use crate::{ + config::*, get_quic_addr, verify::WebPkiVerifierAnyServerName, ALPN_QUIC_HTTP, + QUIC_ACCEPT_THROTTLE_TIME, QUIC_DEFAULT_MTU, QUIC_LOCATOR_PREFIX, +}; +use async_std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; +use async_std::prelude::FutureExt; +use async_std::sync::Mutex as AsyncMutex; +use async_std::task; +use async_std::task::JoinHandle; +use async_trait::async_trait; +use rustls::{Certificate, PrivateKey}; +use rustls_pemfile::Item; +use std::collections::HashMap; +use std::fmt; +use std::io::BufReader; +use std::net::IpAddr; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, RwLock}; +use std::time::Duration; +use zenoh_core::{zasynclock, zread, zwrite}; +use zenoh_link_commons::{ + AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, +}; +use zenoh_protocol::core::{EndPoint, Locator}; +use zenoh_result::{bail, zerror, ZError, ZResult}; +use zenoh_sync::Signal; + +pub struct LinkUnicastQuic { + connection: quinn::Connection, + src_addr: SocketAddr, + src_locator: Locator, + dst_locator: Locator, + send: AsyncMutex, + recv: AsyncMutex, +} + +impl LinkUnicastQuic { + fn new( + connection: quinn::Connection, + src_addr: SocketAddr, + dst_locator: Locator, + send: quinn::SendStream, + recv: quinn::RecvStream, + ) -> LinkUnicastQuic { + // Build the Quic object + LinkUnicastQuic { + connection, + src_addr, + src_locator: Locator::new(QUIC_LOCATOR_PREFIX, src_addr.to_string(), "").unwrap(), + dst_locator, + send: AsyncMutex::new(send), + recv: AsyncMutex::new(recv), + } + } +} + +#[async_trait] +impl LinkUnicastTrait for LinkUnicastQuic { + async fn close(&self) -> ZResult<()> { + log::trace!("Closing QUIC link: {}", self); + // Flush the QUIC stream + let mut guard = zasynclock!(self.send); + if let Err(e) = guard.finish().await { + log::trace!("Error closing QUIC stream {}: {}", self, e); + } + self.connection.close(quinn::VarInt::from_u32(0), &[0]); + Ok(()) + } + + async fn write(&self, buffer: &[u8]) -> ZResult { + let mut guard = zasynclock!(self.send); + guard.write(buffer).await.map_err(|e| { + log::trace!("Write error on QUIC link {}: {}", self, e); + zerror!(e).into() + }) + } + + async fn write_all(&self, buffer: &[u8]) -> ZResult<()> { + let mut guard = zasynclock!(self.send); + guard.write_all(buffer).await.map_err(|e| { + log::trace!("Write error on QUIC link {}: {}", self, e); + zerror!(e).into() + }) + } + + async fn read(&self, buffer: &mut [u8]) -> ZResult { + let mut guard = zasynclock!(self.recv); + guard + .read(buffer) + .await + .map_err(|e| { + let e = zerror!("Read error on QUIC link {}: {}", self, e); + log::trace!("{}", &e); + e + })? + .ok_or_else(|| { + let e = zerror!( + "Read error on QUIC link {}: stream {} has been closed", + self, + guard.id() + ); + log::trace!("{}", &e); + e.into() + }) + } + + async fn read_exact(&self, buffer: &mut [u8]) -> ZResult<()> { + let mut guard = zasynclock!(self.recv); + guard.read_exact(buffer).await.map_err(|e| { + let e = zerror!("Read error on QUIC link {}: {}", self, e); + log::trace!("{}", &e); + e.into() + }) + } + + #[inline(always)] + fn get_src(&self) -> &Locator { + &self.src_locator + } + + #[inline(always)] + fn get_dst(&self) -> &Locator { + &self.dst_locator + } + + #[inline(always)] + fn get_mtu(&self) -> u16 { + *QUIC_DEFAULT_MTU + } + + #[inline(always)] + fn get_interface_names(&self) -> Vec { + // @TODO: Not supported for now + log::debug!("The get_interface_names for LinkUnicastQuic is not supported"); + vec![] + } + + #[inline(always)] + fn is_reliable(&self) -> bool { + true + } + + #[inline(always)] + fn is_streamed(&self) -> bool { + true + } +} + +impl Drop for LinkUnicastQuic { + fn drop(&mut self) { + self.connection.close(quinn::VarInt::from_u32(0), &[0]); + } +} + +impl fmt::Display for LinkUnicastQuic { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{} => {}", + self.src_addr, + self.connection.remote_address() + )?; + Ok(()) + } +} + +impl fmt::Debug for LinkUnicastQuic { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Quic") + .field("src", &self.src_addr) + .field("dst", &self.connection.remote_address()) + .finish() + } +} + +/*************************************/ +/* LISTENER */ +/*************************************/ +struct ListenerUnicastQuic { + endpoint: EndPoint, + active: Arc, + signal: Signal, + handle: JoinHandle>, +} + +impl ListenerUnicastQuic { + fn new( + endpoint: EndPoint, + active: Arc, + signal: Signal, + handle: JoinHandle>, + ) -> ListenerUnicastQuic { + ListenerUnicastQuic { + endpoint, + active, + signal, + handle, + } + } +} + +pub struct LinkManagerUnicastQuic { + manager: NewLinkChannelSender, + listeners: Arc>>, +} + +impl LinkManagerUnicastQuic { + pub fn new(manager: NewLinkChannelSender) -> Self { + Self { + manager, + listeners: Arc::new(RwLock::new(HashMap::new())), + } + } +} + +#[async_trait] +impl LinkManagerUnicastTrait for LinkManagerUnicastQuic { + async fn new_link(&self, endpoint: EndPoint) -> ZResult { + println!("this is called when connecting via quic"); + let epaddr = endpoint.address(); + let host = epaddr + .as_str() + .split(':') + .next() + .ok_or("Endpoints must be of the form quic/
:")?; + let epconf = endpoint.config(); + + let addr = get_quic_addr(&epaddr).await?; + + let server_name_verification: bool = epconf + .get(TLS_SERVER_NAME_VERIFICATION) + .unwrap_or(TLS_SERVER_NAME_VERIFICATION_DEFAULT) + .parse()?; + + if !server_name_verification { + log::warn!("Skipping name verification of servers"); + } + + // Initialize the QUIC connection + let mut root_cert_store = rustls::RootCertStore::empty(); + + // Read the certificates + let f = if let Some(value) = epconf.get(TLS_ROOT_CA_CERTIFICATE_RAW) { + value.as_bytes().to_vec() + } else if let Some(b64_certificate) = epconf.get(TLS_ROOT_CA_CERTIFICATE_BASE64) { + base64_decode(b64_certificate)? + } else if let Some(value) = epconf.get(TLS_ROOT_CA_CERTIFICATE_FILE) { + async_std::fs::read(value) + .await + .map_err(|e| zerror!("Invalid QUIC CA certificate file: {}", e))? + } else { + vec![] + }; + + let certificates = if f.is_empty() { + rustls_native_certs::load_native_certs() + .map_err(|e| zerror!("Invalid QUIC CA certificate file: {}", e))? + .drain(..) + .map(|x| rustls::Certificate(x.to_vec())) + .collect::>() + } else { + rustls_pemfile::certs(&mut BufReader::new(f.as_slice())) + .map(|result| { + result + .map_err(|err| zerror!("Invalid QUIC CA certificate file: {}", err)) + .map(|der| Certificate(der.to_vec())) + }) + .collect::, ZError>>()? + }; + for c in certificates.iter() { + root_cert_store.add(c).map_err(|e| zerror!("{}", e))?; + } + + let client_crypto = rustls::ClientConfig::builder().with_safe_defaults(); + + let mut client_crypto = if server_name_verification { + client_crypto + .with_root_certificates(root_cert_store) + .with_no_client_auth() + } else { + client_crypto + .with_custom_certificate_verifier(Arc::new(WebPkiVerifierAnyServerName::new( + root_cert_store, + ))) + .with_no_client_auth() + }; + + client_crypto.alpn_protocols = ALPN_QUIC_HTTP.iter().map(|&x| x.into()).collect(); + + let ip_addr: IpAddr = if addr.is_ipv4() { + Ipv4Addr::UNSPECIFIED.into() + } else { + Ipv6Addr::UNSPECIFIED.into() + }; + + let mut quic_endpoint = quinn::Endpoint::client(SocketAddr::new(ip_addr, 0)) + .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))?; + + quic_endpoint.set_default_client_config(quinn::ClientConfig::new(Arc::new(client_crypto))); + + let src_addr = quic_endpoint + .local_addr() + .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))?; + println!("tried to make quic_connection"); + + let quic_conn = quic_endpoint + .connect(addr, host) + .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))? + .await + .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))?; + println!("was able to make quic_connection"); + + let (send, recv) = quic_conn + .open_bi() + .await + .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))?; + + // let pi = &quic_conn.peer_identity().unwrap(); + // match pi.downcast_ref::>() { + // Some(serv_certs) => { + // println!("the server certs were found"); + // for item in serv_certs { + // let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); + // let subject_name = &cert + // .subject + // .iter_common_name() + // .next() + // .and_then(|cn| cn.as_str().ok()) + // .unwrap(); + // let auth_identifier = AuthIdentifier { + // username: None, + // tls_cert_name: Some(subject_name.to_string()), + // }; + + // println!("auth_identifier: {:?}", auth_identifier); + // } + // } + // None => { + // println!("no server certs found"); + // } + // } + + let link = Arc::new(LinkUnicastQuic::new( + quic_conn, + src_addr, + endpoint.into(), + send, + recv, + )); + + Ok(LinkUnicast(link)) + } + + async fn new_listener(&self, mut endpoint: EndPoint) -> ZResult { + let epaddr = endpoint.address(); + let epconf = endpoint.config(); + + if epconf.is_empty() { + bail!("No QUIC configuration provided"); + }; + + let addr = get_quic_addr(&epaddr).await?; + + let f = if let Some(value) = epconf.get(TLS_SERVER_CERTIFICATE_RAW) { + value.as_bytes().to_vec() + } else if let Some(b64_certificate) = epconf.get(TLS_SERVER_CERTIFICATE_BASE64) { + base64_decode(b64_certificate)? + } else if let Some(value) = epconf.get(TLS_SERVER_CERTIFICATE_FILE) { + async_std::fs::read(value) + .await + .map_err(|e| zerror!("Invalid QUIC CA certificate file: {}", e))? + } else { + bail!("No QUIC CA certificate has been provided."); + }; + let certificates = rustls_pemfile::certs(&mut BufReader::new(f.as_slice())) + .map(|result| { + result + .map_err(|err| zerror!("Invalid QUIC CA certificate file: {}", err)) + .map(|der| Certificate(der.to_vec())) + }) + .collect::, ZError>>()?; + + // Private keys + let f = if let Some(value) = epconf.get(TLS_SERVER_PRIVATE_KEY_RAW) { + value.as_bytes().to_vec() + } else if let Some(b64_key) = epconf.get(TLS_SERVER_PRIVATE_KEY_BASE64) { + base64_decode(b64_key)? + } else if let Some(value) = epconf.get(TLS_SERVER_PRIVATE_KEY_FILE) { + async_std::fs::read(value) + .await + .map_err(|e| zerror!("Invalid QUIC CA certificate file: {}", e))? + } else { + bail!("No QUIC CA private key has been provided."); + }; + let items: Vec = rustls_pemfile::read_all(&mut BufReader::new(f.as_slice())) + .map(|result| { + result.map_err(|err| zerror!("Invalid QUIC CA private key file: {}", err)) + }) + .collect::, ZError>>()?; + + let private_key = items + .into_iter() + .filter_map(|x| match x { + rustls_pemfile::Item::Pkcs1Key(k) => Some(k.secret_pkcs1_der().to_vec()), + rustls_pemfile::Item::Pkcs8Key(k) => Some(k.secret_pkcs8_der().to_vec()), + rustls_pemfile::Item::Sec1Key(k) => Some(k.secret_sec1_der().to_vec()), + _ => None, + }) + .take(1) + .next() + .ok_or_else(|| zerror!("No QUIC CA private key has been provided.")) + .map(PrivateKey)?; + + // Server config + let mut server_crypto = rustls::ServerConfig::builder() + .with_safe_defaults() + .with_no_client_auth() + .with_single_cert(certificates, private_key)?; + server_crypto.alpn_protocols = ALPN_QUIC_HTTP.iter().map(|&x| x.into()).collect(); + let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(server_crypto)); + + // We do not accept unidireactional streams. + Arc::get_mut(&mut server_config.transport) + .unwrap() + .max_concurrent_uni_streams(0_u8.into()); + // For the time being we only allow one bidirectional stream + Arc::get_mut(&mut server_config.transport) + .unwrap() + .max_concurrent_bidi_streams(1_u8.into()); + + // Initialize the Endpoint + let quic_endpoint = quinn::Endpoint::server(server_config, addr) + .map_err(|e| zerror!("Can not create a new QUIC listener on {}: {}", addr, e))?; + + let local_addr = quic_endpoint + .local_addr() + .map_err(|e| zerror!("Can not create a new QUIC listener on {}: {}", addr, e))?; + + // Update the endpoint locator address + endpoint = EndPoint::new( + endpoint.protocol(), + local_addr.to_string(), + endpoint.metadata(), + endpoint.config(), + )?; + + // Spawn the accept loop for the listener + let active = Arc::new(AtomicBool::new(true)); + let signal = Signal::new(); + let mut listeners = zwrite!(self.listeners); + + let c_active = active.clone(); + let c_signal = signal.clone(); + let c_manager = self.manager.clone(); + let c_listeners = self.listeners.clone(); + let c_addr = local_addr; + let handle = task::spawn(async move { + // Wait for the accept loop to terminate + let res = accept_task(quic_endpoint, c_active, c_signal, c_manager).await; + zwrite!(c_listeners).remove(&c_addr); + res + }); + + // Initialize the QuicAcceptor + let locator = endpoint.to_locator(); + let listener = ListenerUnicastQuic::new(endpoint, active, signal, handle); + // Update the list of active listeners on the manager + listeners.insert(local_addr, listener); + + Ok(locator) + } + + async fn del_listener(&self, endpoint: &EndPoint) -> ZResult<()> { + let epaddr = endpoint.address(); + + let addr = get_quic_addr(&epaddr).await?; + + // Stop the listener + let listener = zwrite!(self.listeners).remove(&addr).ok_or_else(|| { + let e = zerror!( + "Can not delete the QUIC listener because it has not been found: {}", + addr + ); + log::trace!("{}", e); + e + })?; + + // Send the stop signal + listener.active.store(false, Ordering::Release); + listener.signal.trigger(); + listener.handle.await + } + + fn get_listeners(&self) -> Vec { + zread!(self.listeners) + .values() + .map(|x| x.endpoint.clone()) + .collect() + } + + fn get_locators(&self) -> Vec { + let mut locators = vec![]; + + let guard = zread!(self.listeners); + for (key, value) in guard.iter() { + let (kip, kpt) = (key.ip(), key.port()); + + // Either ipv4/0.0.0.0 or ipv6/[::] + if kip.is_unspecified() { + let mut addrs = match kip { + IpAddr::V4(_) => zenoh_util::net::get_ipv4_ipaddrs(), + IpAddr::V6(_) => zenoh_util::net::get_ipv6_ipaddrs(), + }; + let iter = addrs.drain(..).map(|x| { + Locator::new( + value.endpoint.protocol(), + SocketAddr::new(x, kpt).to_string(), + value.endpoint.metadata(), + ) + .unwrap() + }); + locators.extend(iter); + } else { + locators.push(value.endpoint.to_locator()); + } + } + + locators + } +} + +async fn accept_task( + endpoint: quinn::Endpoint, + active: Arc, + signal: Signal, + manager: NewLinkChannelSender, +) -> ZResult<()> { + enum Action { + Accept(quinn::Connection), + Stop, + } + + async fn accept(acceptor: quinn::Accept<'_>) -> ZResult { + let qc = acceptor + .await + .ok_or_else(|| zerror!("Can not accept QUIC connections: acceptor closed"))?; + + let conn = qc.await.map_err(|e| { + let e = zerror!("QUIC acceptor failed: {:?}", e); + log::warn!("{}", e); + e + })?; + + Ok(Action::Accept(conn)) + } + + async fn stop(signal: Signal) -> ZResult { + signal.wait().await; + Ok(Action::Stop) + } + + let src_addr = endpoint + .local_addr() + .map_err(|e| zerror!("Can not accept QUIC connections: {}", e))?; + + // The accept future + log::trace!("Ready to accept QUIC connections on: {:?}", src_addr); + while active.load(Ordering::Acquire) { + // Wait for incoming connections + let quic_conn = match accept(endpoint.accept()).race(stop(signal.clone())).await { + Ok(action) => match action { + Action::Accept(qc) => qc, + Action::Stop => break, + }, + Err(e) => { + log::warn!("{} Hint: increase the system open file limit.", e); + // Throttle the accept loop upon an error + // NOTE: This might be due to various factors. However, the most common case is that + // the process has reached the maximum number of open files in the system. On + // Linux systems this limit can be changed by using the "ulimit" command line + // tool. In case of systemd-based systems, this can be changed by using the + // "sysctl" command line tool. + task::sleep(Duration::from_micros(*QUIC_ACCEPT_THROTTLE_TIME)).await; + continue; + } + }; + + // Get the bideractional streams. Note that we don't allow unidirectional streams. + let (send, recv) = match quic_conn.accept_bi().await { + Ok(stream) => stream, + Err(e) => { + log::warn!("QUIC connection has no streams: {:?}", e); + continue; + } + }; + + // Create the new link object + // let pi = &quic_conn.peer_identity().unwrap(); + //println!("the accept function is also called before check"); + + // match quic_conn + // .peer_identity() + // .unwrap() + // .downcast_ref::>() + // { + // Some(serv_certs) => { + // println!("the client certs were found"); + // for item in serv_certs { + // let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); + // let subject_name = &cert + // .subject + // .iter_common_name() + // .next() + // .and_then(|cn| cn.as_str().ok()) + // .unwrap(); + // let auth_identifier = AuthIdentifier { + // username: None, + // tls_cert_name: Some(subject_name.to_string()), + // }; + + // println!("auth_identifier: {:?}", auth_identifier); + // } + // } + // None => { + // println!("no client certs found"); + // } + // } + let dst_addr = quic_conn.remote_address(); + log::debug!("Accepted QUIC connection on {:?}: {:?}", src_addr, dst_addr); + let link = Arc::new(LinkUnicastQuic::new( + quic_conn, + src_addr, + Locator::new(QUIC_LOCATOR_PREFIX, dst_addr.to_string(), "")?, + send, + recv, + )); + + // Communicate the new link to the initial transport manager + if let Err(e) = manager.send_async(LinkUnicast(link)).await { + log::error!("{}-{}: {}", file!(), line!(), e) + } + } + + Ok(()) +} diff --git a/io/zenoh-links/zenoh-link-tls/Cargo.toml b/io/zenoh-links/zenoh-link-tls/Cargo.toml index 5d047b1160..667cc88b2a 100644 --- a/io/zenoh-links/zenoh-link-tls/Cargo.toml +++ b/io/zenoh-links/zenoh-link-tls/Cargo.toml @@ -42,4 +42,5 @@ zenoh-result = { workspace = true } zenoh-sync = { workspace = true } zenoh-util = { workspace = true } base64 = { workspace = true } -secrecy = {workspace = true } \ No newline at end of file +secrecy = { workspace = true } +x509-parser = "0.16.0" diff --git a/io/zenoh-links/zenoh-link-tls/src/unicast-modified.rs b/io/zenoh-links/zenoh-link-tls/src/unicast-modified.rs new file mode 100644 index 0000000000..4d6f316fbd --- /dev/null +++ b/io/zenoh-links/zenoh-link-tls/src/unicast-modified.rs @@ -0,0 +1,916 @@ +// +// Copyright (c) 2023 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +use x509_parser::prelude::*; + +use crate::{ + base64_decode, config::*, get_tls_addr, get_tls_host, get_tls_server_name, + verify::WebPkiVerifierAnyServerName, TLS_ACCEPT_THROTTLE_TIME, TLS_DEFAULT_MTU, + TLS_LINGER_TIMEOUT, TLS_LOCATOR_PREFIX, +}; +use async_rustls::{ + rustls::{ + server::AllowAnyAuthenticatedClient, version::TLS13, Certificate, ClientConfig, + OwnedTrustAnchor, PrivateKey, RootCertStore, ServerConfig, + }, + TlsAcceptor, TlsConnector, TlsStream, +}; +use async_std::fs; +use async_std::net::{SocketAddr, TcpListener, TcpStream}; +use async_std::prelude::FutureExt; +use async_std::sync::Mutex as AsyncMutex; +use async_std::task; +use async_std::task::JoinHandle; +use async_trait::async_trait; +use futures::io::AsyncReadExt; +use futures::io::AsyncWriteExt; +use std::collections::HashMap; +use std::convert::TryInto; +use std::fmt; +use std::fs::File; +use std::io::{BufReader, Cursor}; +use std::net::{IpAddr, Shutdown}; +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, RwLock}; +use std::time::Duration; +use std::{cell::UnsafeCell, io}; +use webpki::{ + anchor_from_trusted_cert, + types::{CertificateDer, TrustAnchor}, +}; +use zenoh_core::{zasynclock, zread, zwrite}; +use zenoh_link_commons::{ + AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, +}; +use zenoh_protocol::core::endpoint::Config; +use zenoh_protocol::core::{EndPoint, Locator}; +use zenoh_result::{bail, zerror, ZError, ZResult}; +use zenoh_sync::Signal; + +pub struct LinkUnicastTls { + // The underlying socket as returned from the async-rustls library + // NOTE: TlsStream requires &mut for read and write operations. This means + // that concurrent reads and writes are not possible. To achieve that, + // we use an UnsafeCell for interior mutability. Using an UnsafeCell + // is safe in our case since the transmission and reception logic + // already ensures that no concurrent reads or writes can happen on + // the same stream: there is only one task at the time that writes on + // the stream and only one task at the time that reads from the stream. + inner: UnsafeCell>, + // The source socket address of this link (address used on the local host) + src_addr: SocketAddr, + src_locator: Locator, + // The destination socket address of this link (address used on the local host) + dst_addr: SocketAddr, + dst_locator: Locator, + // Make sure there are no concurrent read or writes + write_mtx: AsyncMutex<()>, + read_mtx: AsyncMutex<()>, +} + +unsafe impl Send for LinkUnicastTls {} +unsafe impl Sync for LinkUnicastTls {} + +impl LinkUnicastTls { + fn new( + socket: TlsStream, + src_addr: SocketAddr, + dst_addr: SocketAddr, + ) -> LinkUnicastTls { + let (tcp_stream, _) = socket.get_ref(); + // Set the TLS nodelay option + if let Err(err) = tcp_stream.set_nodelay(true) { + log::warn!( + "Unable to set NODEALY option on TLS link {} => {}: {}", + src_addr, + dst_addr, + err + ); + } + + // Set the TLS linger option + if let Err(err) = zenoh_util::net::set_linger( + tcp_stream, + Some(Duration::from_secs( + (*TLS_LINGER_TIMEOUT).try_into().unwrap(), + )), + ) { + log::warn!( + "Unable to set LINGER option on TLS link {} => {}: {}", + src_addr, + dst_addr, + err + ); + } + + // Build the Tls object + LinkUnicastTls { + inner: UnsafeCell::new(socket), + src_addr, + src_locator: Locator::new(TLS_LOCATOR_PREFIX, src_addr.to_string(), "").unwrap(), + dst_addr, + dst_locator: Locator::new(TLS_LOCATOR_PREFIX, dst_addr.to_string(), "").unwrap(), + write_mtx: AsyncMutex::new(()), + read_mtx: AsyncMutex::new(()), + } + } + + // NOTE: It is safe to suppress Clippy warning since no concurrent reads + // or concurrent writes will ever happen. The read_mtx and write_mtx + // are respectively acquired in any read and write operation. + #[allow(clippy::mut_from_ref)] + fn get_sock_mut(&self) -> &mut TlsStream { + unsafe { &mut *self.inner.get() } + } +} + +#[async_trait] +impl LinkUnicastTrait for LinkUnicastTls { + async fn close(&self) -> ZResult<()> { + log::trace!("Closing TLS link: {}", self); + // Flush the TLS stream + let _guard = zasynclock!(self.write_mtx); + let tls_stream = self.get_sock_mut(); + let res = tls_stream.flush().await; + log::trace!("TLS link flush {}: {:?}", self, res); + // Close the underlying TCP stream + let (tcp_stream, _) = tls_stream.get_ref(); + let res = tcp_stream.shutdown(Shutdown::Both); + log::trace!("TLS link shutdown {}: {:?}", self, res); + res.map_err(|e| zerror!(e).into()) + } + + async fn write(&self, buffer: &[u8]) -> ZResult { + let _guard = zasynclock!(self.write_mtx); + self.get_sock_mut().write(buffer).await.map_err(|e| { + log::trace!("Write error on TLS link {}: {}", self, e); + zerror!(e).into() + }) + } + + async fn write_all(&self, buffer: &[u8]) -> ZResult<()> { + let _guard = zasynclock!(self.write_mtx); + self.get_sock_mut().write_all(buffer).await.map_err(|e| { + log::trace!("Write error on TLS link {}: {}", self, e); + zerror!(e).into() + }) + } + + async fn read(&self, buffer: &mut [u8]) -> ZResult { + let _guard = zasynclock!(self.read_mtx); + self.get_sock_mut().read(buffer).await.map_err(|e| { + log::trace!("Read error on TLS link {}: {}", self, e); + zerror!(e).into() + }) + } + + async fn read_exact(&self, buffer: &mut [u8]) -> ZResult<()> { + let _guard = zasynclock!(self.read_mtx); + self.get_sock_mut().read_exact(buffer).await.map_err(|e| { + log::trace!("Read error on TLS link {}: {}", self, e); + zerror!(e).into() + }) + } + + #[inline(always)] + fn get_src(&self) -> &Locator { + &self.src_locator + } + + #[inline(always)] + fn get_dst(&self) -> &Locator { + &self.dst_locator + } + + #[inline(always)] + fn get_mtu(&self) -> u16 { + *TLS_DEFAULT_MTU + } + + #[inline(always)] + fn get_interface_names(&self) -> Vec { + // @TODO: Not supported for now + log::debug!("The get_interface_names for LinkUnicastTls is not supported"); + vec![] + } + + #[inline(always)] + fn is_reliable(&self) -> bool { + true + } + + #[inline(always)] + fn is_streamed(&self) -> bool { + true + } +} + +impl Drop for LinkUnicastTls { + fn drop(&mut self) { + // Close the underlying TCP stream + let (tcp_stream, _) = self.get_sock_mut().get_ref(); + let _ = tcp_stream.shutdown(Shutdown::Both); + } +} + +impl fmt::Display for LinkUnicastTls { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} => {}", self.src_addr, self.dst_addr)?; + Ok(()) + } +} + +impl fmt::Debug for LinkUnicastTls { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Tls") + .field("src", &self.src_addr) + .field("dst", &self.dst_addr) + .finish() + } +} + +/*************************************/ +/* LISTENER */ +/*************************************/ +struct ListenerUnicastTls { + endpoint: EndPoint, + active: Arc, + signal: Signal, + handle: JoinHandle>, +} + +impl ListenerUnicastTls { + fn new( + endpoint: EndPoint, + active: Arc, + signal: Signal, + handle: JoinHandle>, + ) -> ListenerUnicastTls { + ListenerUnicastTls { + endpoint, + active, + signal, + handle, + } + } +} + +pub struct LinkManagerUnicastTls { + manager: NewLinkChannelSender, + listeners: Arc>>, +} + +impl LinkManagerUnicastTls { + pub fn new(manager: NewLinkChannelSender) -> Self { + Self { + manager, + listeners: Arc::new(RwLock::new(HashMap::new())), + } + } +} + +#[async_trait] +impl LinkManagerUnicastTrait for LinkManagerUnicastTls { + async fn new_link(&self, endpoint: EndPoint) -> ZResult { + let epaddr = endpoint.address(); + let epconf = endpoint.config(); + + let server_name = get_tls_server_name(&epaddr)?; + let addr = get_tls_addr(&epaddr).await?; + + // Initialize the TLS Config + let client_config = TlsClientConfig::new(&epconf) + .await + .map_err(|e| zerror!("Cannot create a new TLS listener to {endpoint}: {e}"))?; + let config = Arc::new(client_config.client_config); + let connector = TlsConnector::from(config); + + // Initialize the TcpStream + let tcp_stream = TcpStream::connect(addr).await.map_err(|e| { + zerror!( + "Can not create a new TLS link bound to {:?}: {}", + server_name, + e + ) + })?; + + let src_addr = tcp_stream.local_addr().map_err(|e| { + zerror!( + "Can not create a new TLS link bound to {:?}: {}", + server_name, + e + ) + })?; + + let dst_addr = tcp_stream.peer_addr().map_err(|e| { + zerror!( + "Can not create a new TLS link bound to {:?}: {}", + server_name, + e + ) + })?; + + // Initialize the TlsStream + let tls_stream = connector + .connect(server_name.to_owned(), tcp_stream) + .await + .map_err(|e| { + zerror!( + "Can not create a new TLS link bound to {:?}: {}", + server_name, + e + ) + })?; + let (_, tls_conn) = tls_stream.get_ref(); + + let serv_certs = tls_conn.peer_certificates().unwrap(); + + for item in serv_certs { + let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); + let subject_name = &cert + .subject + .iter_common_name() + .next() + .and_then(|cn| cn.as_str().ok()) + .unwrap(); + let auth_identifier = AuthIdentifier { + username: None, + tls_cert_name: Some(subject_name.to_string()), + }; + + println!("auth_identifier: {:?}", auth_identifier); + } + let tls_stream = TlsStream::Client(tls_stream); + let link = Arc::new(LinkUnicastTls::new(tls_stream, src_addr, dst_addr)); + + Ok(LinkUnicast(link)) + } + + async fn new_listener(&self, endpoint: EndPoint) -> ZResult { + let epaddr = endpoint.address(); + let epconf = endpoint.config(); + + let addr = get_tls_addr(&epaddr).await?; + let host = get_tls_host(&epaddr)?; + + // Initialize TlsConfig + let tls_server_config = TlsServerConfig::new(&epconf) + .await + .map_err(|e| zerror!("Cannot create a new TLS listener on {addr}. {e}"))?; + + // Initialize the TcpListener + let socket = TcpListener::bind(addr) + .await + .map_err(|e| zerror!("Can not create a new TLS listener on {}: {}", addr, e))?; + + let local_addr = socket + .local_addr() + .map_err(|e| zerror!("Can not create a new TLS listener on {}: {}", addr, e))?; + let local_port = local_addr.port(); + + // Initialize the TlsAcceptor + let acceptor = TlsAcceptor::from(Arc::new(tls_server_config.server_config)); + let active = Arc::new(AtomicBool::new(true)); + let signal = Signal::new(); + + // Spawn the accept loop for the listener + let c_active = active.clone(); + let c_signal = signal.clone(); + let c_manager = self.manager.clone(); + let c_listeners = self.listeners.clone(); + let c_addr = local_addr; + let handle = task::spawn(async move { + // Wait for the accept loop to terminate + let res = accept_task(socket, acceptor, c_active, c_signal, c_manager).await; + zwrite!(c_listeners).remove(&c_addr); + res + }); + + // Update the endpoint locator address + let locator = Locator::new( + endpoint.protocol(), + format!("{host}:{local_port}"), + endpoint.metadata(), + )?; + + let listener = ListenerUnicastTls::new(endpoint, active, signal, handle); + // Update the list of active listeners on the manager + zwrite!(self.listeners).insert(local_addr, listener); + + Ok(locator) + } + + async fn del_listener(&self, endpoint: &EndPoint) -> ZResult<()> { + let epaddr = endpoint.address(); + + let addr = get_tls_addr(&epaddr).await?; + + // Stop the listener + let listener = zwrite!(self.listeners).remove(&addr).ok_or_else(|| { + let e = zerror!( + "Can not delete the TLS listener because it has not been found: {}", + addr + ); + log::trace!("{}", e); + e + })?; + + // Send the stop signal + listener.active.store(false, Ordering::Release); + listener.signal.trigger(); + listener.handle.await + } + + fn get_listeners(&self) -> Vec { + zread!(self.listeners) + .values() + .map(|x| x.endpoint.clone()) + .collect() + } + + fn get_locators(&self) -> Vec { + let mut locators = vec![]; + + let guard = zread!(self.listeners); + for (key, value) in guard.iter() { + let (kip, kpt) = (key.ip(), key.port()); + + // Either ipv4/0.0.0.0 or ipv6/[::] + if kip.is_unspecified() { + let mut addrs = match kip { + IpAddr::V4(_) => zenoh_util::net::get_ipv4_ipaddrs(), + IpAddr::V6(_) => zenoh_util::net::get_ipv6_ipaddrs(), + }; + let iter = addrs.drain(..).map(|x| { + Locator::new( + value.endpoint.protocol(), + SocketAddr::new(x, kpt).to_string(), + value.endpoint.metadata(), + ) + .unwrap() + }); + locators.extend(iter); + } else { + locators.push(value.endpoint.to_locator()); + } + } + + locators + } +} + +async fn accept_task( + socket: TcpListener, + acceptor: TlsAcceptor, + active: Arc, + signal: Signal, + manager: NewLinkChannelSender, +) -> ZResult<()> { + enum Action { + Accept((TcpStream, SocketAddr)), + Stop, + } + + async fn accept(socket: &TcpListener) -> ZResult { + let res = socket.accept().await.map_err(|e| zerror!(e))?; + Ok(Action::Accept(res)) + } + + async fn stop(signal: Signal) -> ZResult { + signal.wait().await; + Ok(Action::Stop) + } + + let src_addr = socket.local_addr().map_err(|e| { + let e = zerror!("Can not accept TLS connections: {}", e); + log::warn!("{}", e); + e + })?; + + log::trace!("Ready to accept TLS connections on: {:?}", src_addr); + while active.load(Ordering::Acquire) { + // Wait for incoming connections + let (tcp_stream, dst_addr) = match accept(&socket).race(stop(signal.clone())).await { + Ok(action) => match action { + Action::Accept((tcp_stream, dst_addr)) => (tcp_stream, dst_addr), + Action::Stop => break, + }, + Err(e) => { + log::warn!("{}. Hint: increase the system open file limit.", e); + // Throttle the accept loop upon an error + // NOTE: This might be due to various factors. However, the most common case is that + // the process has reached the maximum number of open files in the system. On + // Linux systems this limit can be changed by using the "ulimit" command line + // tool. In case of systemd-based systems, this can be changed by using the + // "sysctl" command line tool. + task::sleep(Duration::from_micros(*TLS_ACCEPT_THROTTLE_TIME)).await; + continue; + } + }; + // Accept the TLS connection + let tls_stream = match acceptor.accept(tcp_stream).await { + Ok(stream) => TlsStream::Server(stream), + Err(e) => { + let e = format!("Can not accept TLS connection: {e}"); + log::warn!("{}", e); + continue; + } + }; + let (_, tls_conn) = tls_stream.get_ref(); + let auth_identifier = get_tls_cert_name(tls_conn); + match auth_identifier { + Some(auth_id) => println!("client's ID: {:?}", auth_id), + None => println!("no client ID found"), + } + + log::debug!("Accepted TLS connection on {:?}: {:?}", src_addr, dst_addr); + // Create the new link object + let link = Arc::new(LinkUnicastTls::new(tls_stream, src_addr, dst_addr)); + + // Communicate the new link to the initial transport manager + if let Err(e) = manager.send_async(LinkUnicast(link)).await { + log::error!("{}-{}: {}", file!(), line!(), e) + } + } + + Ok(()) +} +fn get_tls_cert_name(tls_conn: &rustls::CommonState) -> Option { + let serv_certs = tls_conn.peer_certificates()?; + let (_, cert) = X509Certificate::from_der(serv_certs[0].as_ref()).unwrap(); + let subject_name = &cert + .subject + .iter_common_name() + .next() + .and_then(|cn| cn.as_str().ok()) + .unwrap(); + + Some(AuthIdentifier { + username: None, + tls_cert_name: Some(subject_name.to_string()), + }) +} +struct TlsServerConfig { + server_config: ServerConfig, +} + +impl TlsServerConfig { + pub async fn new(config: &Config<'_>) -> ZResult { + let tls_server_client_auth: bool = match config.get(TLS_CLIENT_AUTH) { + Some(s) => s + .parse() + .map_err(|_| zerror!("Unknown client auth argument: {}", s))?, + None => false, + }; + let tls_server_private_key = TlsServerConfig::load_tls_private_key(config).await?; + let tls_server_certificate = TlsServerConfig::load_tls_certificate(config).await?; + + let certs: Vec = + rustls_pemfile::certs(&mut Cursor::new(&tls_server_certificate)) + .map(|result| { + result + .map_err(|err| zerror!("Error processing server certificate: {err}.")) + .map(|der| Certificate(der.to_vec())) + }) + .collect::, ZError>>()?; + + let mut keys: Vec = + rustls_pemfile::rsa_private_keys(&mut Cursor::new(&tls_server_private_key)) + .map(|result| { + result + .map_err(|err| zerror!("Error processing server key: {err}.")) + .map(|key| PrivateKey(key.secret_pkcs1_der().to_vec())) + }) + .collect::, ZError>>()?; + + if keys.is_empty() { + keys = rustls_pemfile::pkcs8_private_keys(&mut Cursor::new(&tls_server_private_key)) + .map(|result| { + result + .map_err(|err| zerror!("Error processing server key: {err}.")) + .map(|key| PrivateKey(key.secret_pkcs8_der().to_vec())) + }) + .collect::, ZError>>()?; + } + + if keys.is_empty() { + keys = rustls_pemfile::ec_private_keys(&mut Cursor::new(&tls_server_private_key)) + .map(|result| { + result + .map_err(|err| zerror!("Error processing server key: {err}.")) + .map(|key| PrivateKey(key.secret_sec1_der().to_vec())) + }) + .collect::, ZError>>()?; + } + + if keys.is_empty() { + bail!("No private key found for TLS server."); + } + + let sc = if tls_server_client_auth { + let root_cert_store = load_trust_anchors(config)?.map_or_else( + || { + Err(zerror!( + "Missing root certificates while client authentication is enabled." + )) + }, + Ok, + )?; + ServerConfig::builder() + .with_safe_default_cipher_suites() + .with_safe_default_kx_groups() + .with_protocol_versions(&[&TLS13]) // Force TLS 1.3 + .map_err(|e| zerror!(e))? + .with_client_cert_verifier(Arc::new(AllowAnyAuthenticatedClient::new(root_cert_store))) + .with_single_cert(certs, keys.remove(0)) + .map_err(|e| zerror!(e))? + } else { + ServerConfig::builder() + .with_safe_defaults() + .with_no_client_auth() + .with_single_cert(certs, keys.remove(0)) + .map_err(|e| zerror!(e))? + }; + Ok(TlsServerConfig { server_config: sc }) + } + + async fn load_tls_private_key(config: &Config<'_>) -> ZResult> { + load_tls_key( + config, + TLS_SERVER_PRIVATE_KEY_RAW, + TLS_SERVER_PRIVATE_KEY_FILE, + TLS_SERVER_PRIVATE_KEY_BASE_64, + ) + .await + } + + async fn load_tls_certificate(config: &Config<'_>) -> ZResult> { + load_tls_certificate( + config, + TLS_SERVER_CERTIFICATE_RAW, + TLS_SERVER_CERTIFICATE_FILE, + TLS_SERVER_CERTIFICATE_BASE64, + ) + .await + } +} + +struct TlsClientConfig { + client_config: ClientConfig, +} + +impl TlsClientConfig { + pub async fn new(config: &Config<'_>) -> ZResult { + let tls_client_server_auth: bool = match config.get(TLS_CLIENT_AUTH) { + Some(s) => s + .parse() + .map_err(|_| zerror!("Unknown client auth argument: {}", s))?, + None => false, + }; + + let tls_server_name_verification: bool = match config.get(TLS_SERVER_NAME_VERIFICATION) { + Some(s) => { + let s: bool = s + .parse() + .map_err(|_| zerror!("Unknown server name verification argument: {}", s))?; + if s { + log::warn!("Skipping name verification of servers"); + } + s + } + None => false, + }; + + // Allows mixed user-generated CA and webPKI CA + log::debug!("Loading default Web PKI certificates."); + let mut root_cert_store: RootCertStore = RootCertStore { + roots: load_default_webpki_certs().roots, + }; + + if let Some(custom_root_cert) = load_trust_anchors(config)? { + log::debug!("Loading user-generated certificates."); + root_cert_store.add_trust_anchors(custom_root_cert.roots.into_iter()); + } + + let cc = if tls_client_server_auth { + log::debug!("Loading client authentication key and certificate..."); + let tls_client_private_key = TlsClientConfig::load_tls_private_key(config).await?; + let tls_client_certificate = TlsClientConfig::load_tls_certificate(config).await?; + + let certs: Vec = + rustls_pemfile::certs(&mut Cursor::new(&tls_client_certificate)) + .map(|result| { + result + .map_err(|err| zerror!("Error processing client certificate: {err}.")) + .map(|der| Certificate(der.to_vec())) + }) + .collect::, ZError>>()?; + + let mut keys: Vec = + rustls_pemfile::rsa_private_keys(&mut Cursor::new(&tls_client_private_key)) + .map(|result| { + result + .map_err(|err| zerror!("Error processing client key: {err}.")) + .map(|key| PrivateKey(key.secret_pkcs1_der().to_vec())) + }) + .collect::, ZError>>()?; + + if keys.is_empty() { + keys = + rustls_pemfile::pkcs8_private_keys(&mut Cursor::new(&tls_client_private_key)) + .map(|result| { + result + .map_err(|err| zerror!("Error processing client key: {err}.")) + .map(|key| PrivateKey(key.secret_pkcs8_der().to_vec())) + }) + .collect::, ZError>>()?; + } + + if keys.is_empty() { + keys = rustls_pemfile::ec_private_keys(&mut Cursor::new(&tls_client_private_key)) + .map(|result| { + result + .map_err(|err| zerror!("Error processing client key: {err}.")) + .map(|key| PrivateKey(key.secret_sec1_der().to_vec())) + }) + .collect::, ZError>>()?; + } + + if keys.is_empty() { + bail!("No private key found for TLS client."); + } + + let builder = ClientConfig::builder() + .with_safe_default_cipher_suites() + .with_safe_default_kx_groups() + .with_protocol_versions(&[&TLS13]) + .map_err(|e| zerror!("Config parameters should be valid: {}", e))?; + + if tls_server_name_verification { + builder + .with_root_certificates(root_cert_store) + .with_client_auth_cert(certs, keys.remove(0)) + } else { + builder + .with_custom_certificate_verifier(Arc::new(WebPkiVerifierAnyServerName::new( + root_cert_store, + ))) + .with_client_auth_cert(certs, keys.remove(0)) + } + .map_err(|e| zerror!("Bad certificate/key: {}", e))? + } else { + let builder = ClientConfig::builder().with_safe_defaults(); + if tls_server_name_verification { + builder + .with_root_certificates(root_cert_store) + .with_no_client_auth() + } else { + builder + .with_custom_certificate_verifier(Arc::new(WebPkiVerifierAnyServerName::new( + root_cert_store, + ))) + .with_no_client_auth() + } + }; + Ok(TlsClientConfig { client_config: cc }) + } + + async fn load_tls_private_key(config: &Config<'_>) -> ZResult> { + load_tls_key( + config, + TLS_CLIENT_PRIVATE_KEY_RAW, + TLS_CLIENT_PRIVATE_KEY_FILE, + TLS_CLIENT_PRIVATE_KEY_BASE64, + ) + .await + } + + async fn load_tls_certificate(config: &Config<'_>) -> ZResult> { + load_tls_certificate( + config, + TLS_CLIENT_CERTIFICATE_RAW, + TLS_CLIENT_CERTIFICATE_FILE, + TLS_CLIENT_CERTIFICATE_BASE64, + ) + .await + } +} + +async fn load_tls_key( + config: &Config<'_>, + tls_private_key_raw_config_key: &str, + tls_private_key_file_config_key: &str, + tls_private_key_base64_config_key: &str, +) -> ZResult> { + if let Some(value) = config.get(tls_private_key_raw_config_key) { + return Ok(value.as_bytes().to_vec()); + } else if let Some(b64_key) = config.get(tls_private_key_base64_config_key) { + return base64_decode(b64_key); + } else if let Some(value) = config.get(tls_private_key_file_config_key) { + return Ok(fs::read(value) + .await + .map_err(|e| zerror!("Invalid TLS private key file: {}", e))?) + .and_then(|result| { + if result.is_empty() { + Err(zerror!("Empty TLS key.").into()) + } else { + Ok(result) + } + }); + } + Err(zerror!("Missing TLS private key.").into()) +} + +async fn load_tls_certificate( + config: &Config<'_>, + tls_certificate_raw_config_key: &str, + tls_certificate_file_config_key: &str, + tls_certificate_base64_config_key: &str, +) -> ZResult> { + if let Some(value) = config.get(tls_certificate_raw_config_key) { + return Ok(value.as_bytes().to_vec()); + } else if let Some(b64_certificate) = config.get(tls_certificate_base64_config_key) { + return base64_decode(b64_certificate); + } else if let Some(value) = config.get(tls_certificate_file_config_key) { + return Ok(fs::read(value) + .await + .map_err(|e| zerror!("Invalid TLS certificate file: {}", e))?); + } + Err(zerror!("Missing tls certificates.").into()) +} + +fn load_trust_anchors(config: &Config<'_>) -> ZResult> { + let mut root_cert_store = RootCertStore::empty(); + if let Some(value) = config.get(TLS_ROOT_CA_CERTIFICATE_RAW) { + let mut pem = BufReader::new(value.as_bytes()); + let trust_anchors = process_pem(&mut pem)?; + root_cert_store.add_trust_anchors(trust_anchors.into_iter()); + return Ok(Some(root_cert_store)); + } + + if let Some(b64_certificate) = config.get(TLS_ROOT_CA_CERTIFICATE_BASE64) { + let certificate_pem = base64_decode(b64_certificate)?; + let mut pem = BufReader::new(certificate_pem.as_slice()); + let trust_anchors = process_pem(&mut pem)?; + root_cert_store.add_trust_anchors(trust_anchors.into_iter()); + return Ok(Some(root_cert_store)); + } + + if let Some(filename) = config.get(TLS_ROOT_CA_CERTIFICATE_FILE) { + let mut pem = BufReader::new(File::open(filename)?); + let trust_anchors = process_pem(&mut pem)?; + root_cert_store.add_trust_anchors(trust_anchors.into_iter()); + return Ok(Some(root_cert_store)); + } + Ok(None) +} + +fn process_pem(pem: &mut dyn io::BufRead) -> ZResult> { + let certs: Vec = rustls_pemfile::certs(pem) + .map(|result| result.map_err(|err| zerror!("Error processing PEM certificates: {err}."))) + .collect::, ZError>>()?; + + let trust_anchors: Vec = certs + .into_iter() + .map(|cert| { + anchor_from_trusted_cert(&cert) + .map_err(|err| zerror!("Error processing trust anchor: {err}.")) + .map(|trust_anchor| trust_anchor.to_owned()) + }) + .collect::, ZError>>()?; + + let owned_trust_anchors: Vec = trust_anchors + .into_iter() + .map(|ta| { + OwnedTrustAnchor::from_subject_spki_name_constraints( + ta.subject.to_vec(), + ta.subject_public_key_info.to_vec(), + ta.name_constraints.map(|x| x.to_vec()), + ) + }) + .collect(); + + Ok(owned_trust_anchors) +} + +fn load_default_webpki_certs() -> RootCertStore { + let mut root_cert_store = RootCertStore::empty(); + root_cert_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { + OwnedTrustAnchor::from_subject_spki_name_constraints( + ta.subject.to_vec(), + ta.subject_public_key_info.to_vec(), + ta.name_constraints.clone().map(|x| x.to_vec()), + ) + })); + root_cert_store +} diff --git a/io/zenoh-links/zenoh-link-tls/src/unicast.rs b/io/zenoh-links/zenoh-link-tls/src/unicast.rs index e3adea2dff..8cb2d32698 100644 --- a/io/zenoh-links/zenoh-link-tls/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-tls/src/unicast.rs @@ -44,9 +44,10 @@ use webpki::{ anchor_from_trusted_cert, types::{CertificateDer, TrustAnchor}, }; +use x509_parser::prelude::*; use zenoh_core::zasynclock; use zenoh_link_commons::{ - get_ip_interface_names, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, + get_ip_interface_names, AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, }; use zenoh_protocol::core::endpoint::Config; @@ -300,6 +301,26 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastTls { e ) })?; + + let (_, tls_conn) = tls_stream.get_ref(); + + let serv_certs = tls_conn.peer_certificates().unwrap(); + + for item in serv_certs { + let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); + let subject_name = &cert + .subject + .iter_common_name() + .next() + .and_then(|cn| cn.as_str().ok()) + .unwrap(); + let auth_identifier = AuthIdentifier { + username: None, + tls_cert_name: Some(subject_name.to_string()), + }; + + println!("auth_identifier: {:?}", auth_identifier); + } let tls_stream = TlsStream::Client(tls_stream); let link = Arc::new(LinkUnicastTls::new(tls_stream, src_addr, dst_addr)); @@ -429,6 +450,13 @@ async fn accept_task( } }; + let (_, tls_conn) = tls_stream.get_ref(); + let auth_identifier = get_tls_cert_name(tls_conn); + match auth_identifier { + Some(auth_id) => println!("client's ID: {:?}", auth_id), + None => println!("no client ID found"), + } + log::debug!("Accepted TLS connection on {:?}: {:?}", src_addr, dst_addr); // Create the new link object let link = Arc::new(LinkUnicastTls::new(tls_stream, src_addr, dst_addr)); @@ -442,6 +470,22 @@ async fn accept_task( Ok(()) } +fn get_tls_cert_name(tls_conn: &rustls::CommonState) -> Option { + let serv_certs = tls_conn.peer_certificates()?; + let (_, cert) = X509Certificate::from_der(serv_certs[0].as_ref()).unwrap(); + let subject_name = &cert + .subject + .iter_common_name() + .next() + .and_then(|cn| cn.as_str().ok()) + .unwrap(); + + Some(AuthIdentifier { + username: None, + tls_cert_name: Some(subject_name.to_string()), + }) +} + struct TlsServerConfig { server_config: ServerConfig, } diff --git a/mypub.crt b/mypub.crt new file mode 100644 index 0000000000..1f94e5d243 --- /dev/null +++ b/mypub.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIUFMs3tKqT0Cvz3r0aSN9KSVPCsfwwDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTIxMjM5MzlaFw0yNTAzMTIxMjM5MzlaMFMxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRcwFQYDVQQDDA5w +dWJfdGxzX2NsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALFj +0iNYAXqGniTo9R7qMHu6a0p9mQkuXn4Cppb6ovj3JozaSBxjgbrTVbxCZqJ6WCkk +0cRU+flcmQ2Sae6pHnRIB/PZ54s18jhhC80g9svgHf6+bSuqFqUZRRh+R0WZI5UV +YxbOJbMpG3ScyFgQ/iMlD9UpZqMGh+Rs/BCBfV8HB5+KcFNkPA45VOeyRcZf3PDp +eL9mP13uyNAEq4D5KSxV8lTvJqgTMpGpQmrJctGQ4+bQJ5mqAnVofMaShl7MqBSU +0U3CO9voe55sUQ/lYBYMK9oZKwfF6pfN4lShZSRWoYS8MsnK38U14wme2sNCeQEL +eRYm+UT7nzX/W6pw8DMCAwEAAaNdMFswGQYDVR0RBBIwEIIOcHViX3Rsc19jbGll +bnQwHQYDVR0OBBYEFMB042sagkaONASSTUQjMRTq3qi0MB8GA1UdIwQYMBaAFOGC +i133CzavIQRoqnb5Ew5ZXwPuMA0GCSqGSIb3DQEBCwUAA4IBAQCcuTc1POPJvYrT +NQYhPDj/Y+B2542+dVZzGQGqab95tngAGQC/n9bN+it35VaCadSSy2WHszp2GCmE +A3icXsL3UVvItDbdt/Uczb+VxjLrMtmUiZIlSXxQ1J1GTnjvJpdfRwc5YC6/RAav +Caqiazxuo4TS4cueUgbB4ry/8g/r/CPC4h0JLe3pNb4EGBo3MoJ4y5wcDIoD/0ns +9SLZSbrOtTKiPRonoEOws7a3IxprPfZZ3BP+lrm/ArkBMPOtfvcNKsfT8UBM4rsq +hvEkuCcig7A54z/xgY1u6fdwDLn6D+otzmKkw19o9JCYzfx1vWZFft5v+Y1mnXQF +fs26RWOK +-----END CERTIFICATE----- diff --git a/mypub.key b/mypub.key new file mode 100644 index 0000000000..ffcba548d0 --- /dev/null +++ b/mypub.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCxY9IjWAF6hp4k +6PUe6jB7umtKfZkJLl5+AqaW+qL49yaM2kgcY4G601W8QmaielgpJNHEVPn5XJkN +kmnuqR50SAfz2eeLNfI4YQvNIPbL4B3+vm0rqhalGUUYfkdFmSOVFWMWziWzKRt0 +nMhYEP4jJQ/VKWajBofkbPwQgX1fBwefinBTZDwOOVTnskXGX9zw6Xi/Zj9d7sjQ +BKuA+SksVfJU7yaoEzKRqUJqyXLRkOPm0CeZqgJ1aHzGkoZezKgUlNFNwjvb6Hue +bFEP5WAWDCvaGSsHxeqXzeJUoWUkVqGEvDLJyt/FNeMJntrDQnkBC3kWJvlE+581 +/1uqcPAzAgMBAAECggEACdVfw8fQJSurPp6PYAxZbbJy2ilGP4ULhe69r2bre+Ov +hmVfU/uMKIAoo4wGxoEDvBwnaLvRM6qXbXItXyaO4qFPl4v/0u7Fo6x1jASEyd59 +qy6BPMdsA/D3rJjreIc5urz5xjzdSCZCOF+sl30xqV8Xlph58RWemOIVwxB6k7bn +a9fK1cZuiCHNZda6RBTceihL+p+lS5qNs5MMMJeWEyQiMw5govdbVNDjw+g2yEtr +ooU7GlQg2Ss3cKAyQnux3BkQOUmqzBlZJu0MZ0Taqo0odlXH9Zc9JJq/eFCBaNwD +sQsZ1oMzdo0OQtzaS9g7bXDPIoeO2oyVJe++sS1c8QKBgQDV7jaQ+/SyQpid0h7O +ayyvwOCWf1sxBHWcWxFkSLFaiUsQEZXVmkK5GLOOGxrRYeev+iypDZNgP7W5qv67 +zRtLbiMhBRZGVTPYLzwRQlJBpWp+ZNdMRRa6iQPhsh8smcUl3XJZjscf2ulOHTtN +J01T7HSKScilPmNLTxLghT3CKwKBgQDURhCHyKeJVTkGB9OVCRlYzeSDnvx5uIqg +pRiAHFJUeC9cXamHE5fMrgEmMoLSudizin14PIRV4AIQIySI6wu+nIOQaKur1goG +RxRkbCx0qSgx083vJxVPfww8CFUkgOJ6qbLrpjB/LNoo1ecHrR0mXzIOe9kxR2Rq +jiUpRS/uGQKBgQCv0svIFzwCcleKhlJJZq5geI5dQqjJPZgH/JTrrg8NkP8/YqSZ +3OHvzMxuA/rjkarg6CVif8TbeyE5Sr93zFgdg5Sdo9et0IL+r7uXl8GRMIm4/dox +Visa/ldRXJrghjURLNK5pm4j0UCkscO2YpHcYt9ZdNDSdtcW4xNpsjiS5wKBgQCa +sAwvxus/ytjpKh7nhl/wNOoHeH4n/XEYK/c0tG7Sm1p4BtEZXA/M2iiAO2LWSRQ/ +kfZo/kC5i6o1NEbVd+NxHgFJ5NzlNe7MMFQN8j5bLUHbPaveUS7YZY722GOjXECu +fqehzdOdeYPpKidXkrGhWtHReDMIFCx68ebmskKBUQKBgEwizz/5ibXTrtiU+1vQ +P+mQC0WeY+awGnlPTkqDIz2RjaWZ53ZaOLwM9jJgMOdvL7NxwtLNpo0Zlkyonrmz +rEnXgh6VPzebZ7HXV1cpxh7/V/KKq6DlOgfz/uIO2b7jJgDZKgt74DVgheJEEnMG +N5XoKGfFvlqT27jqWsooqWma +-----END PRIVATE KEY----- diff --git a/mysub.crt b/mysub.crt new file mode 100644 index 0000000000..741949a7ba --- /dev/null +++ b/mysub.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIUFMs3tKqT0Cvz3r0aSN9KSVPCsf4wDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTIxMjQzNDZaFw0yNTAzMTIxMjQzNDZaMFMxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRcwFQYDVQQDDA5z +dWJfdGxzX2NsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJvD +EsuI9bllKHm7nTrTvF1IJzjsrzW80XyEuapK1bk2EW43zvKSMGq4uGT8aTd1Us0R +XCr+vxGT/qjSEwHp/vMY/ft58DpQ93hAtsfCMNKMNO6To66X/FXpc9nkFnpEmndW +KVan14EmcvUBbeezbYbffRBN1IQSj5K7wK45tuEty8GrPOntlumdoSJX4wRcbK87 +DCIrWbfQKOc6d2XWldJKKjkiZnQJlbnDQUdjiJQNvCv+jEMxsC4M/YNjpaT1xq7f +x1ochYdVZvWu3c1eYYsV9gvzKVmGUOsPWoXXK9fPQ+3ZpE0AfcUsYmufcvq6G0Dz +GIEZrw6SZcrqvjRaRZ8CAwEAAaNdMFswGQYDVR0RBBIwEIIOc3ViX3Rsc19jbGll +bnQwHQYDVR0OBBYEFMoXVCYQ/vmz5gHtw/9XCteQFn72MB8GA1UdIwQYMBaAFOGC +i133CzavIQRoqnb5Ew5ZXwPuMA0GCSqGSIb3DQEBCwUAA4IBAQASWyALPl3y5lnD +7QQrolp3ytKzsrhR7ly8RuCUQsaTqTQ4RnS+AyHCcY1MRiElHP0KxeO44fTPqZvW +4yg93a7ec75RPYCTuAbUPhpR4Njui7oEYkVl5dSYdm/+P1G2BAIH6neOlBuECjcH +lfwjX9aJEsE8sD5447WY+1VQIb+rsHAovg0S3UoYYXBmAjxMIKRq25ut2FoADO/J +dh6wz6zTIZOB53wJ1PPU3w16Mdy2mACr2kYw2l9J0PuKLgge/FFCHEzkJleZZqgc +H7qlZPbTRLcZRqFSqfZfneTF0RFCGR0i2vxxW3hNZCZn0nDw0Dtkx9Xbp7lo+ObE +L1qTQTjw +-----END CERTIFICATE----- diff --git a/mysub.csr b/mysub.csr new file mode 100644 index 0000000000..dbe6d89071 --- /dev/null +++ b/mysub.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICmDCCAYACAQAwUzELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQH +DAJQUjERMA8GA1UECgwIenMsIEluYy4xFzAVBgNVBAMMDnN1Yl90bHNfY2xpZW50 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm8MSy4j1uWUoebudOtO8 +XUgnOOyvNbzRfIS5qkrVuTYRbjfO8pIwari4ZPxpN3VSzRFcKv6/EZP+qNITAen+ +8xj9+3nwOlD3eEC2x8Iw0ow07pOjrpf8Velz2eQWekSad1YpVqfXgSZy9QFt57Nt +ht99EE3UhBKPkrvArjm24S3Lwas86e2W6Z2hIlfjBFxsrzsMIitZt9Ao5zp3ZdaV +0koqOSJmdAmVucNBR2OIlA28K/6MQzGwLgz9g2OlpPXGrt/HWhyFh1Vm9a7dzV5h +ixX2C/MpWYZQ6w9ahdcr189D7dmkTQB9xSxia59y+robQPMYgRmvDpJlyuq+NFpF +nwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAIBa6ccode0L5STQm7npmTVJmx+w +doTDcM7dAUdc4iaDkQLKiEsUl7pClsbroZCVB/CctxkthukgZS5w8PSt1nJPqe7Q +lUrv88ARDPOBS6+XTIJZyXBxvz01DtvHxsLUmedPfVDGqQYCWGudcX+KWkJEApTz +pw888FneR+aKe2QatyoGfF3C0zSeZY2el/f6CHV9RFEBIBuPGZO05wfHPcDo92Kb +VScgQi/eMD81x3nKPD208CyyK3o96tUAQjzpXivHSnJmdDc4H6pKs3ufy0T0R3T/ +RwcY34MHhu5BxJ9gC0YQD0PlObFBL2MuQi/OlnmWcQ2R3UIKyw0jaSG42Ak= +-----END CERTIFICATE REQUEST----- diff --git a/mysub.key b/mysub.key new file mode 100644 index 0000000000..0d9f6a2dae --- /dev/null +++ b/mysub.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQCbwxLLiPW5ZSh5 +u50607xdSCc47K81vNF8hLmqStW5NhFuN87ykjBquLhk/Gk3dVLNEVwq/r8Rk/6o +0hMB6f7zGP37efA6UPd4QLbHwjDSjDTuk6Oul/xV6XPZ5BZ6RJp3VilWp9eBJnL1 +AW3ns22G330QTdSEEo+Su8CuObbhLcvBqzzp7ZbpnaEiV+MEXGyvOwwiK1m30Cjn +Ondl1pXSSio5ImZ0CZW5w0FHY4iUDbwr/oxDMbAuDP2DY6Wk9cau38daHIWHVWb1 +rt3NXmGLFfYL8ylZhlDrD1qF1yvXz0Pt2aRNAH3FLGJrn3L6uhtA8xiBGa8OkmXK +6r40WkWfAgMBAAECgf84yOh8J5xQcll2FLiyDdaN1xrjqRGiDb+IhUJOWwbgm+J6 +12kMPPtpuPfHskQUcixi1zilkTZxymiBZC6TfZRAywXTZ20mVxOtNNPPHKUKpUnQ +7egzDD9c8lDLlqyoGlqXDQ/knkirRLPhtPSz4bX1pjnONjbfQFmsRTstUtnd/71/ +QpVVX/oKNPXHT5UtwmKA/nC+YtCJ1iuiQWCYH41GlZkpMt0G0FLa4vXpOEFTgwnd +X5w638BPaUBm7fbV5pMIS10qu7qISUlU/wDihJBa5UT3NwbTfB6AkBkp5YSMbsbY +a7kMgALlhMRRqNkAfVvZ5JCdII2bChTL9XRVdFECgYEA0IzIjjDZRzAUTIdWzffw +OebeKG3CjoS8ek7AF5cmmb1PSjCPvXOdplWKSN1fM9rqrHsyJJnKPS9tniGBPU00 +5/PxANjmCxEwkKM7ejHoP9EaIIm7ncBKJcgTdn4f2b1kGVY5LESSQdU7Mz0wjBSl +3SkxffunEH1/DVPT9v7TSOkCgYEAvzOZlPamijQVxznFRftfrkI8yUW+Io6n+gEs +2Id0hehNTUVWJMo9PxUkH18AcAtWEsEz2yf0QshBTKi9ZZ6BCgC8PsOKneCpn0tS +WgnMpD7IQun9X5kmwblDBPeD8GRNa7IZIQ16kZ4tnqpdQf+cgaDXEOKmqPymEZAD +X9/ghUcCgYEAxTSbYXnnvF1GlKdV+iZ+TwJ1CR3hYAs8fxuAoc4YfkB5fdo10hxF +80foH8bVg597UeadH+cdSoZSzbk5ENK1OLGAMCDqR4TVu6/fSklvKQl9/06+zwlK +FDgBz4asb6Wbxim2npmpA/+yn105Tv0nat7NIiiZbgp93ghq46FMAiECgYAgtqZn +W1AhQ0oanSLIl3rGaOTXlwwyA3BwEPVoUry4EIfxWZSklMmn2mkkyO9dPENM0Cuc +KpjbOEIb6J8HHPh9CqUqo/A6lO7Qp2V+rECMNYW0FS7ZxW1hJd52oha78Z1heMZd +5l17PrIVfJaaLS7M6wUBCZZ0QU30oUxCgh57DwKBgHK8W/do25qyIz5dXQKCzayN +Tv4cU/9dA34wi2+QA3TMj92oqVrbXzrt6hPdYSm8u9No7B8CVX3lEEkHwreuwi3n +U45wP/GlAl8KpjbjEZDrl2gsXlwoxIu/V21S5fsHwD4OAqldLgtc+Kbj4U6bfC4S +VuQ4MTpTKj+nVbzjOIMF +-----END PRIVATE KEY----- diff --git a/newmyserver.crt b/newmyserver.crt new file mode 100644 index 0000000000..3459120a9e --- /dev/null +++ b/newmyserver.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDnDCCAoSgAwIBAgIUFMs3tKqT0Cvz3r0aSN9KSVPCsfswDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTExNjI0MzBaFw0yNTAzMTExNjI0MzBaMFgxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRwwGgYDVQQDDBNu +ZXdfdGVzdF90bHNfc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtSmanq4rho3EkYpTVro/gOcrZnG+n5VY+d9maWDb4Fc+DP8Fki4jWtl5Vc7A +wtRUy3SAXkrKJCKcC0opUMZvFSCr+43B3CKJcrEJb5Eu3k90HyiOVL/ZAFHIRO2f +2cOWYNu/WEHrBPz8Bj1qualKTuo5mjgLSuGWYb8On03qdXRdD9lpYpyWvL8vYHQ0 +m0ljR/kcVaUaI7XhTu6Ea8gIaxJVxs2P99mhjIfoJgVIoc5mP/+jWNJP4y1Bm4I5 +3p5iArBHWYOvMaumlkMYoZm97MsA5+8iXOImIPFxj+d14VmvqMq9J0iLandU4Uvw +FUXnLHi+QQyeFmlgO/2BAaRw9QIDAQABo2IwYDAeBgNVHREEFzAVghNuZXdfdGVz +dF90bHNfc2VydmVyMB0GA1UdDgQWBBQebkuD+avdhGdqrPLWgT+p8lcB6TAfBgNV +HSMEGDAWgBThgotd9ws2ryEEaKp2+RMOWV8D7jANBgkqhkiG9w0BAQsFAAOCAQEA +UCVixHvWTjhc7bB9fuTbIDUP9GwTf0t2qojbG7WY9m+iSTLCOO5HOHy4jvtm7hHa +hdF/6ohSLP/LRwoWzeEQQi7oAzSVck3w0SlRrdV97FEdIBAjRRK3IICsIagLtKKS +qBoHx7gbyNsaocn1yxkQPbqrh4GE3TpcoHFlAjpHKJI42YkDsNCshSSRO7WIhyQP +0ty3uPss20t6iH8TuZQnqRKKvz6/NCGKi8wu3C750vdmbd4Y7eyEjeNbG3+P5D8f +i99Kjsevk0e5YLEp1d1ydO5DssS/9TzwIeLOH6/q0tFK9lQln6MvSJ3EMQjOrLVb +80O7goMvO+wd5Q2D7JBjVQ== +-----END CERTIFICATE----- diff --git a/newmyserver.key b/newmyserver.key new file mode 100644 index 0000000000..fb5f4aa6e2 --- /dev/null +++ b/newmyserver.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC1KZqeriuGjcSR +ilNWuj+A5ytmcb6flVj532ZpYNvgVz4M/wWSLiNa2XlVzsDC1FTLdIBeSsokIpwL +SilQxm8VIKv7jcHcIolysQlvkS7eT3QfKI5Uv9kAUchE7Z/Zw5Zg279YQesE/PwG +PWq5qUpO6jmaOAtK4ZZhvw6fTep1dF0P2WlinJa8vy9gdDSbSWNH+RxVpRojteFO +7oRryAhrElXGzY/32aGMh+gmBUihzmY//6NY0k/jLUGbgjnenmICsEdZg68xq6aW +Qxihmb3sywDn7yJc4iYg8XGP53XhWa+oyr0nSItqd1ThS/AVRecseL5BDJ4WaWA7 +/YEBpHD1AgMBAAECggEAV/anBoRgSvmcJ+Tn2VUez4qvdpMlMVx1cwJnuiQXLyN9 +VBchz9xKO2scMK9uxksODyn2yJH8+7W4Wfz8+aUYO8R87Wxj5Gz6my9d+weeH8Cp +jBWHopvylGahXOKaesSuyEH68zIymN3zy13X6+VI2O9+36R1yzqk57o6sdxFyxhN +jgjroWV0WXaquN1X61WQsQDOVKPGyYnp7y7+R3nUwROipl/H6LcRQHiCWbuoZwuo +ykoMczn0YrguC0t1smj0yiF6mllsMNcWSknjPmCSUHyWKCcyDx0J/pu0Q4JYa0NZ +PMwL5Rv8BQhLFDUrHpHKlt3CcL3ZNdEr2bV4YTW/cwKBgQD3cM8lMeGteq+NwiIj +EWHR1uZxeIswveCKDot/mMZhYH3MiMXy9GNfEbgnwfQ8bbwojmEOHsdhy/L7+lY5 +LdkYmX5osy+iiFhZStMPc76DolWCAD/CxbLwO6YuDo+aM7eZI5zZdCAHZafUF3Y8 +ArFGWxnVGtWkwYh5dNzI8zr1SwKBgQC7bd/Bg9AZcYijBqqGDiJgPymb1hbY4hW4 +XERS7JSJuwZ8ZQH5wkdOWHpZO8gk191Ke0gaREKtFSz3uSQ9TTjdqkqxv6Y8TyHP +DjTn4A9UK7ZWFVlU7bnzms8Vgs99cZibaZAcn8ZtcdowlsvNMubOKVnIn7O9AG+6 +lZOr5ieKvwKBgQCqk8cJUiDMkeYR6IHWAPaZTPdhxALYYB05rxs1pCEmIfm3FZa4 +jQcwE6wLJGb1fYSXxMddj5RNc+aXFJV6J4QgtDfzf4tYFXwqWi2z2ku8vR0LWJab +8+QOPmCqIXmXiQ2JcYaAVdB6qPaQfHgSmJyS7tyZDz22rYAikpBdq2e6jwKBgCNc +1qO/R+sVBa+kmVXTot6/7AzP9t2SwoBXQDjZFClsVQvxTs8dvbBldygQ5HE3HTRp +UDBMgrv/S82ta835HOqNr6wbubSVRY64YnkBSEMcQDm7q3Afrj7tDXdEh/tmDGH+ +J8eOybRqj70tJmSf3vY0zRDSOOpHA82TXRpIwVsnAoGBAM/uA2XSyxMb4Ld91WMr +xPL5vWnLf8tbgrN1KoJvx+q1zJvEcZKeIFYrgQr/A4c7VW7jzEuQnO0bsAkxz/If +W+n4FY4MT7EswsMG9U/itW0FU8CBR0RhuJPzOtH8+tnDLjDIDuRPkQt0jDdWGlzO +RhmR9FoLOICtr03U7el+9mh+ +-----END PRIVATE KEY----- diff --git a/pub_client.json5 b/pub_client.json5 index b75f75fa16..f04cc43b6d 100644 --- a/pub_client.json5 +++ b/pub_client.json5 @@ -21,8 +21,7 @@ connect: { endpoints: [ // "/
" - "quic/127.0.0.1:7447" - + "tls/127.0.0.1:7447" ], }, /// Which endpoints to listen on. E.g. tcp/localhost:7447. diff --git a/router.json5 b/router.json5 index 46817ee4b4..7a9b52fccd 100644 --- a/router.json5 +++ b/router.json5 @@ -31,7 +31,7 @@ listen: { endpoints: [ // "/
" - "quic/127.0.0.1:7447" + "tls/127.0.0.1:7447" ], }, /// Configure the scouting mechanisms and their behaviours diff --git a/sub_client.json5 b/sub_client.json5 index b75f75fa16..f04cc43b6d 100644 --- a/sub_client.json5 +++ b/sub_client.json5 @@ -21,8 +21,7 @@ connect: { endpoints: [ // "/
" - "quic/127.0.0.1:7447" - + "tls/127.0.0.1:7447" ], }, /// Which endpoints to listen on. E.g. tcp/localhost:7447. From 7c8ee21c4f5265707e3e7030335c4e45ddbf2246 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Wed, 13 Mar 2024 13:31:05 +0100 Subject: [PATCH 03/37] testing cert authn --- pub_client.json5 | 44 ++++++++++++++++++++++---------------------- router.json5 | 44 ++++++++++++++++++++++---------------------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/pub_client.json5 b/pub_client.json5 index f04cc43b6d..c33f5de2e4 100644 --- a/pub_client.json5 +++ b/pub_client.json5 @@ -234,29 +234,29 @@ max_message_size: 1073741824, }, /// Configure TLS specific parameters - tls: { - root_ca_certificate: "ca.crt" - } // tls: { - // /// Path to the certificate of the certificate authority used to validate either the server - // /// or the client's keys and certificates, depending on the node's mode. If not specified - // /// on router mode then the default WebPKI certificates are used instead. - // root_ca_certificate: null, - // /// Path to the TLS server private key - // server_private_key: null, - // /// Path to the TLS server public certificate - // server_certificate: null, - // /// Client authentication, if true enables mTLS (mutual authentication) - // client_auth: false, - // /// Path to the TLS client private key - // client_private_key: null, - // /// Path to the TLS client public certificate - // client_certificate: null, - // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. - // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your - // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). - // server_name_verification: null, - // }, + // root_ca_certificate: "ca.crt" + // } + tls: { + /// Path to the certificate of the certificate authority used to validate either the server + /// or the client's keys and certificates, depending on the node's mode. If not specified + /// on router mode then the default WebPKI certificates are used instead. + root_ca_certificate: "ca.crt", + /// Path to the TLS server private key + server_private_key: null, + /// Path to the TLS server public certificate + server_certificate: null, + /// Client authentication, if true enables mTLS (mutual authentication) + client_auth: true, + /// Path to the TLS client private key + client_private_key: "mypub.key", + /// Path to the TLS client public certificate + client_certificate: "mypub.crt", + // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + server_name_verification: false, + }, }, /// Shared memory configuration shared_memory: { diff --git a/router.json5 b/router.json5 index 7a9b52fccd..82afaf8f20 100644 --- a/router.json5 +++ b/router.json5 @@ -234,30 +234,30 @@ max_message_size: 1073741824, }, /// Configure TLS specific parameters + // tls: { + // server_private_key: "myserver.key", + // server_certificate: "myserver.crt" + // } tls: { + /// Path to the certificate of the certificate authority used to validate either the server + /// or the client's keys and certificates, depending on the node's mode. If not specified + /// on router mode then the default WebPKI certificates are used instead. + root_ca_certificate: "ca.crt", + /// Path to the TLS server private key server_private_key: "myserver.key", - server_certificate: "myserver.crt" - } - // tls: { - // /// Path to the certificate of the certificate authority used to validate either the server - // /// or the client's keys and certificates, depending on the node's mode. If not specified - // /// on router mode then the default WebPKI certificates are used instead. - // root_ca_certificate: null, - // /// Path to the TLS server private key - // server_private_key: null, - // /// Path to the TLS server public certificate - // server_certificate: null, - // /// Client authentication, if true enables mTLS (mutual authentication) - // client_auth: false, - // /// Path to the TLS client private key - // client_private_key: null, - // /// Path to the TLS client public certificate - // client_certificate: null, - // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. - // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your - // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). - // server_name_verification: null, - // }, + /// Path to the TLS server public certificate + server_certificate: "myserver.crt", + /// Client authentication, if true enables mTLS (mutual authentication) + client_auth: true, + /// Path to the TLS client private key + client_private_key: null, + /// Path to the TLS client public certificate + client_certificate: null, + // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + server_name_verification: null, + }, }, /// Shared memory configuration shared_memory: { From a067a77ea0fcb79af65e8c142f33f9e4f0ea044c Mon Sep 17 00:00:00 2001 From: snehilzs Date: Mon, 18 Mar 2024 11:27:57 +0100 Subject: [PATCH 04/37] adding basic authID functionality --- .gitignore | 9 +- Cargo.toml | 14 +- ca2.crt | 21 + client.json5 | 433 +++++++++ client_ca.pem | 20 + client_cert.pem | 20 + client_key.pem | 27 + client_quic.json5 | 56 ++ io/zenoh-link-commons/src/lib.rs | 6 + io/zenoh-link-commons/src/unicast.rs | 5 +- .../zenoh-link-quic/src/unicast-modified.rs | 662 ------------- io/zenoh-links/zenoh-link-quic/src/unicast.rs | 91 +- .../zenoh-link-serial/src/unicast.rs | 10 +- io/zenoh-links/zenoh-link-tcp/src/unicast.rs | 8 +- .../zenoh-link-tls/src/unicast-modified.rs | 916 ------------------ io/zenoh-links/zenoh-link-tls/src/unicast.rs | 41 +- io/zenoh-links/zenoh-link-udp/src/unicast.rs | 11 +- .../zenoh-link-unixpipe/src/unix/unicast.rs | 10 +- .../zenoh-link-unixsock_stream/src/unicast.rs | 8 +- io/zenoh-links/zenoh-link-ws/src/unicast.rs | 7 + myed25519.key | 3 + myedserver.crt | 12 + mypub2.crt | 22 + mypub2.key | 28 + mysub.csr | 16 - peer_pub.json5 | 12 + peer_sub.json5 | 12 + pub_client.json5 | 5 +- router.json5 | 4 +- router_quic.json5 | 56 ++ server_ca.pem | 20 + server_cert.pem | 20 + server_key.pem | 27 + sub_client.json5 | 44 +- zenoh/src/net/routing/interceptor/mod.rs | 4 +- .../interceptor/testing_interceptor.rs | 87 ++ 36 files changed, 1103 insertions(+), 1644 deletions(-) create mode 100644 ca2.crt create mode 100644 client.json5 create mode 100644 client_ca.pem create mode 100644 client_cert.pem create mode 100644 client_key.pem create mode 100644 client_quic.json5 delete mode 100644 io/zenoh-links/zenoh-link-quic/src/unicast-modified.rs delete mode 100644 io/zenoh-links/zenoh-link-tls/src/unicast-modified.rs create mode 100644 myed25519.key create mode 100644 myedserver.crt create mode 100644 mypub2.crt create mode 100644 mypub2.key delete mode 100644 mysub.csr create mode 100644 peer_pub.json5 create mode 100644 peer_sub.json5 create mode 100644 router_quic.json5 create mode 100644 server_ca.pem create mode 100644 server_cert.pem create mode 100644 server_key.pem create mode 100644 zenoh/src/net/routing/interceptor/testing_interceptor.rs diff --git a/.gitignore b/.gitignore index 83421ea1ae..9240486e57 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,11 @@ .vscode -cargo-timing*.html \ No newline at end of file +cargo-timing*.html + +# remove secret files + +*.pem +*.crt +*.key +*.json5 \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index d82d8ae7a5..854d68cd8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,14 +71,16 @@ description = "Zenoh: Zero Overhead Pub/sub, Store/Query and Compute." # DEFAULT-FEATURES NOTE: Be careful with default-features and additivity! # (https://github.com/rust-lang/cargo/issues/11329) [workspace.dependencies] + +rustls = { version = "0.21.5", features = ["dangerous_configuration"] } aes = "0.8.2" ahash = "0.8.7" -anyhow = { version = "1.0.69", default-features = false } # Default features are disabled due to usage in no_std crates +anyhow = { version = "1.0.69", default-features = false } # Default features are disabled due to usage in no_std crates async-executor = "1.5.0" async-global-executor = "2.3.1" async-io = "1.13.0" async-rustls = "0.4.0" -async-std = { version = "=1.12.0", default-features = false } # Default features are disabled due to some crates' requirements +async-std = { version = "=1.12.0", default-features = false } # Default features are disabled due to some crates' requirements async-trait = "0.1.60" base64 = "0.21.4" bincode = "1.3.3" @@ -93,10 +95,10 @@ event-listener = "4.0.0" flume = "0.11" form_urlencoded = "1.1.0" futures = "0.3.25" -futures-util = { version = "0.3.25", default-features = false } # Default features are disabled due to some crates' requirements +futures-util = { version = "0.3.25", default-features = false } # Default features are disabled due to some crates' requirements git-version = "0.3.5" hashbrown = "0.14" -hex = { version = "0.4.3", default-features = false } # Default features are disabled due to usage in no_std crates +hex = { version = "0.4.3", default-features = false } # Default features are disabled due to usage in no_std crates hmac = { version = "0.12.1", features = ["std"] } home = "0.5.4" http-types = "2.12.0" @@ -120,14 +122,14 @@ pnet_datalink = "0.34" proc-macro2 = "1.0.51" quinn = "0.10.1" quote = "1.0.23" -rand = { version = "0.8.5", default-features = false } # Default features are disabled due to usage in no_std crates +rand = { version = "0.8.5", default-features = false } # Default features are disabled due to usage in no_std crates rand_chacha = "0.3.1" rcgen = "0.11" regex = "1.7.1" ringbuffer-spsc = "0.1.9" rsa = "0.9" rustc_version = "0.4.0" -rustls = { version = "0.21.5", features = ["dangerous_configuration"] } +#rustls = "0.21.5" rustls-native-certs = "0.7.0" rustls-pemfile = "2.0.0" rustls-webpki = "0.102.0" diff --git a/ca2.crt b/ca2.crt new file mode 100644 index 0000000000..e3a7d77fbd --- /dev/null +++ b/ca2.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDizCCAnOgAwIBAgIULpNcDIKDOM7YxmzXHSjXrlFZ6+kwDQYJKoZIhvcNAQEL +BQAwVTELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGTAXBgNVBAMMEHpzX3Rlc3Rfcm9vdF9jYTIwHhcNMjQw +MzEzMTMxNTM5WhcNMjUwMzEzMTMxNTM5WjBVMQswCQYDVQQGEwJGUjELMAkGA1UE +CAwCSUYxCzAJBgNVBAcMAlBSMREwDwYDVQQKDAh6cywgSW5jLjEZMBcGA1UEAwwQ +enNfdGVzdF9yb290X2NhMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKoQonePPKy4/uEzzF6t0+JYgT+Z1amlAf0Tc/Az2zA9gc0JdSCfYnZL0ie23dXk +wUvmQMPXh6nmQJO+mw1CG/DAGnj2g/u3PxWKdbxj77wyVJI0BIuEKakv6dmugyhP +I7/PKl/H2XGqQvoHFScegIdFhSkk1V9eg5CZZMqkpwI0bLb/yx73Ed5syWFbMtYK +LvGBNZmG1UT7vBo/gkOq7viLMrWpqkSPv+8/DbZCe0FYYWz0sUp8iWi6SmxMCLsT +S5Plm9f8VQErQnoVBUfWIJYvL2FCIx8klJykWQPssH372wupaXDX9EgBV0eedGIH +4PEpP3ovRGia6vM12Lvl4y0CAwEAAaNTMFEwHQYDVR0OBBYEFNs7TdMPDd3HIdTp +hMQ4vmaB0FWsMB8GA1UdIwQYMBaAFNs7TdMPDd3HIdTphMQ4vmaB0FWsMA8GA1Ud +EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJwtREvIwVZZNeaeseHWtaYe +vIYX0G2ONC7tAVO+RajjllisRlsKYvw2bXWBgMADdlDs9sqbKYSfz/A79SHhaEqF +QnPisSHVkTMnYWkeEaeXfxx/GEa1aXt9lEeDaDHCy2cW1cff9gJAXEE96INVAPv1 +8+w9x1AyjicbgkI/+Ldtf5g9we3wdJQXbbxop92R55+MGB73UN2Bru8pESFX+FpK +Z8Bxc9ruYBUfPl1CCmapDp6lHGtGCE6gnZoMjqTZJGWYz8tBdf2zITPkOKAueuX8 +5UVVtJTzpvPziktp0NZSmPzwotjH0glwL7aGIR/+5bS/cP5Je1FfKAIdH31AJmA= +-----END CERTIFICATE----- diff --git a/client.json5 b/client.json5 new file mode 100644 index 0000000000..69cd0f3169 --- /dev/null +++ b/client.json5 @@ -0,0 +1,433 @@ +/// This file attempts to list and document available configuration elements. +/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. +/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. +{ + /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) + /// that zenoh runtime will use. + /// If not set, a random unsigned 128bit integer will be used. + /// WARNING: this id must be unique in your zenoh network. + // id: "1234567890abcdef", + /// The node's mode (router, peer or client) + mode: "client", + /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ + metadata: { + name: "strawberry", + location: "Penny Lane" + }, + /// Which endpoints to connect to. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: + /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 + connect: { + endpoints: [ + // "/
" + "tls/127.0.0.1:7447" + ], + }, + /// Which endpoints to listen on. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, + /// peers, or client can use to establish a zenoh session. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: + /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 + listen: { + endpoints: [ + // "/
" + ], + }, + /// Configure the scouting mechanisms and their behaviours + scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 3000, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 200, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: true, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: true, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: true, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + /// Configuration of data messages timestamps management. + timestamping: { + /// Whether data messages should be timestamped if not already. + /// Accepts a single boolean value or different values for router, peer and client. + enabled: { router: true, peer: false, client: false + }, + /// Whether data messages with timestamps in the future should be dropped or not. + /// If set to false (default), messages with timestamps in the future are retimestamped. + /// Timestamps are ignored if timestamping is disabled. + drop_future_timestamp: false, + }, + /// The default timeout to apply to queries in milliseconds. + queries_default_timeout: 10000, + /// The routing strategy to use and it's configuration. + routing: { + /// The routing strategy to use in routers and it's configuration. + router: { + /// When set to true a router will forward data between two peers + /// directly connected to it if it detects that those peers are not + /// connected to each other. + /// The failover brokering only works if gossip discovery is enabled. + peers_failover_brokering: true, + }, + /// The routing strategy to use in peers and it's configuration. + peer: { + /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). + mode: "peer_to_peer", + }, + }, + // /// The declarations aggregation strategy. + // aggregation: { + // /// A list of key-expressions for which all included subscribers will be aggregated into. + // subscribers: [ + // // key_expression + // ], + // /// A list of key-expressions for which all included publishers will be aggregated into. + // publishers: [ + // // key_expression + // ], + // }, + // /// The downsampling declaration. + // downsampling: [ + // { + // /// A list of network interfaces messages will be processed on, the rest will be passed as is. + // interfaces: [ "wlan0" ], + // /// Data flow messages will be processed on. ("egress" or "ingress") + // flow: "egress", + // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz + // rules: [ + // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, + // ], + // }, + // ], + /// Configure internal transport parameters + transport: { + unicast: { + /// Timeout in milliseconds when opening a link + accept_timeout: 10000, + /// Maximum number of zenoh session in pending state while accepting + accept_pending: 100, + /// Maximum number of sessions that can be simultaneously alive + max_sessions: 1000, + /// Maximum number of incoming links that are admitted per session + max_links: 1, + /// Enables the LowLatency transport + /// This option does not make LowLatency transport mandatory, the actual implementation of transport + /// used will depend on Establish procedure and other party's settings + /// + /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. + /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to + /// enable 'lowlatency' you need to explicitly disable 'qos'. + lowlatency: false, + /// Enables QoS on unicast communications. + qos: { + enabled: true, + }, + /// Enables compression on unicast communications. + /// Compression capabilities are negotiated during session establishment. + /// If both Zenoh nodes support compression, then compression is activated. + compression: { + enabled: false, + }, + }, + multicast: { + /// Enables QoS on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + qos: { + enabled: false, + }, + /// Enables compression on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + compression: { + enabled: false, + }, + }, + link: { + /// An optional whitelist of protocols to be used for accepting and opening sessions. + /// If not configured, all the supported protocols are automatically whitelisted. + /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + /// For example, to only enable "tls" and "quic": + protocols: [ + "tls" + ], + /// Configure the zenoh TX parameters of a link + tx: { + /// The resolution in bits to be used for the message sequence numbers. + /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: "32bit", + /// Link lease duration in milliseconds to announce to other zenoh nodes + lease: 10000, + /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive + /// messages will be sent at the configured time interval. + /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, + /// set the actual keep_alive timeout to one fourth of the lease time. + /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity + /// check which considers a link as failed when no messages are received in 3.5 times the + /// target interval. + keep_alive: 4, + /// Batch size in bytes is expressed as a 16bit unsigned integer. + /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). + /// The default batch size value is the maximum batch size: 65535. + batch_size: 65535, + /// Each zenoh link has a transmission queue that can be configured + queue: { + /// The size of each priority queue indicates the number of batches a given queue can contain. + /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. + /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, + /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. + /// If qos is false, then only the DATA priority will be allocated. + size: { + control: 1, + real_time: 1, + interactive_high: 1, + interactive_low: 1, + data_high: 2, + data: 4, + data_low: 4, + background: 4, + }, + /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. + /// Higher values lead to a more aggressive batching but it will introduce additional latency. + backoff: 100, + }, + // Number of threads dedicated to transmission + // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) + // threads: 4, + }, + /// Configure the zenoh RX parameters of a link + rx: { + /// Receiving buffer size in bytes for each link + /// The default the rx_buffer_size value is the same as the default batch size: 65335. + /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate + /// more in-flight data. This is particularly relevant when dealing with large messages. + /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. + buffer_size: 65535, + /// Maximum size of the defragmentation buffer at receiver end. + /// Fragmented messages that are larger than the configured size will be dropped. + /// The default value is 1GiB. This would work in most scenarios. + /// NOTE: reduce the value if you are operating on a memory constrained device. + max_message_size: 1073741824, + }, + /// Configure TLS specific parameters + // tls: { + // server_private_key: "myserver.key", + // server_certificate: "myserver.crt" + // } + tls: { + /// Path to the certificate of the certificate authority used to validate either the server + /// or the client's keys and certificates, depending on the node's mode. If not specified + /// on router mode then the default WebPKI certificates are used instead. + root_ca_certificate: "ca.crt", + /// Path to the TLS server private key + server_private_key: null, + /// Path to the TLS server public certificate + server_certificate: null, + /// Client authentication, if true enables mTLS (mutual authentication) + client_auth: true, + /// Path to the TLS client private key + client_private_key: "newmyserver.key", + /// Path to the TLS client public certificate + client_certificate: "newmyserver.crt", + // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + server_name_verification: null, + }, + }, + /// Shared memory configuration + shared_memory: { + enabled: false, + }, + /// Access control configuration + auth: { + /// The configuration of authentication. + /// A password implies a username is required. + usrpwd: { + user: null, + password: null, + /// The path to a file containing the user password dictionary + dictionary_file: null, + }, + pubkey: { + public_key_pem: null, + private_key_pem: null, + public_key_file: null, + private_key_file: null, + key_size: null, + known_keys_file: null, + }, + }, + }, + /// Configure the Admin Space + /// Unstable: this configuration part works as advertised, but may change in a future release + adminspace: { + // read and/or write permissions on the admin space + permissions: { + read: true, + write: false, + }, + }, + /// + /// Plugins configurations + /// + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // plugins_search_dirs: [], + // /// Plugins are only loaded if present in the configuration. When starting + // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. + // plugins: { + // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) + // + // /// Plugin settings may contain field `__config__` + // /// - If `__config__` is specified, it's content is merged into plugin configuration + // /// - Properties loaded from `__config__` file overrides existing properties + // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively + // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config + // /// + // /// See below exapmle of plugin configuration using `__config__` property + // + // /// Configure the REST API plugin + // rest: { + // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. + // __required__: true, // defaults to false + // /// load configuration from the file + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // /// http port to answer to rest requests + // http_port: 8000, + // }, + // + // /// Configure the storage manager plugin + // storage_manager: { + // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. + // __path__: [ + // "./target/release/libzenoh_plugin_storage_manager.so", + // "./target/release/libzenoh_plugin_storage_manager.dylib", + // ], + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // backend_search_dirs: [], + // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. + // volumes: { + // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb + // influxdb: { + // url: "https://myinfluxdb.example", + // /// Some plugins may need passwords in their configuration. + // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. + // /// any value held at the key "private" will not be shown in the adminspace. + // private: { + // username: "user1", + // password: "pw1", + // }, + // }, + // influxdb2: { + // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. + // backend: "influxdb", + // private: { + // username: "user2", + // password: "pw2", + // }, + // url: "https://localhost:8086", + // }, + // }, + // + // /// Configure the storages supported by the volumes + // storages: { + // demo: { + // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. + // key_expr: "demo/memory/**", + // /// Storages also need to know which volume will be used to actually store their key-value pairs. + // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. + // volume: "memory", + // }, + // demo2: { + // key_expr: "demo/memory2/**", + // volume: "memory", + // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. + // /// Metadata includes the set of wild card updates and deletions (tombstones). + // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. + // garbage_collection: { + // /// The garbage collection event will be periodic with this duration. + // /// The duration is specified in seconds. + // period: 30, + // /// Metadata older than this parameter will be garbage collected. + // /// The duration is specified in seconds. + // lifespan: 86400, + // }, + // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. + // /// In the absence of this configuration, a normal storage is initialized + // /// Note: all the samples to be stored in replicas should be timestamped + // replica_config: { + // /// Specifying the parameters is optional, by default the values provided will be used. + // /// Time interval between different synchronization attempts in seconds + // publication_interval: 5, + // /// Expected propagation delay of the network in milliseconds + // propagation_delay: 200, + // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. + // /// Higher the frequency of updates, lower the delta should be chosen + // /// To be efficient, delta should be the time containing no more than 100,000 samples + // delta: 1000, + // } + // }, + // demo3: { + // key_expr: "demo/memory3/**", + // volume: "memory", + // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. + // /// If not configured, complete defaults to false. + // complete: "true", + // }, + // influx_demo: { + // key_expr: "demo/influxdb/**", + // /// This prefix will be stripped of the received keys when storing. + // strip_prefix: "demo/influxdb", + // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: + // volume: { + // id: "influxdb", + // db: "example", + // }, + // }, + // influx_demo2: { + // key_expr: "demo/influxdb2/**", + // strip_prefix: "demo/influxdb2", + // volume: { + // id: "influxdb2", + // db: "example", + // }, + // }, + // }, + // }, + // }, + // /// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // } + // }, +} \ No newline at end of file diff --git a/client_ca.pem b/client_ca.pem new file mode 100644 index 0000000000..53648fdb59 --- /dev/null +++ b/client_ca.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw +MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ +uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs +DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc +8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 +T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b +QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB +AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 +/llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq +hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ +e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc +yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 +8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 +Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN +R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== +-----END CERTIFICATE----- diff --git a/client_cert.pem b/client_cert.pem new file mode 100644 index 0000000000..a2c10ba744 --- /dev/null +++ b/client_cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw +MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT +He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ +Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj +eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 +eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M +tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud +DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE +DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 +3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD +wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q +GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC +9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ +p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ +abY= +-----END CERTIFICATE----- diff --git a/client_key.pem b/client_key.pem new file mode 100644 index 0000000000..8e5f66ee3c --- /dev/null +++ b/client_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi +qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy +aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU +cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha +Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr +Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 +2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 +lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU +WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX +Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI +9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak +r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn +qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY +CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu +fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj +4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih +XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 +38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT +Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV +jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R +5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H +n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm +qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD +tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v +F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== +-----END RSA PRIVATE KEY----- diff --git a/client_quic.json5 b/client_quic.json5 new file mode 100644 index 0000000000..3223a9c49f --- /dev/null +++ b/client_quic.json5 @@ -0,0 +1,56 @@ +{ + mode: "peer", + /// Configure the scouting mechanisms and their behaviours + scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 0, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 0, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: false, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: false, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: false, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + "transport": { + "link": { + "protocols": [ + "quic", + //"tls" + ], + "tls": { + "root_ca_certificate": "server_ca.pem", + "client_auth": false, + "client_private_key": "client_key.pem", + "client_certificate": "client_cert.pem" + } + } + } +} \ No newline at end of file diff --git a/io/zenoh-link-commons/src/lib.rs b/io/zenoh-link-commons/src/lib.rs index 0a43aac3d9..12b4f0cabb 100644 --- a/io/zenoh-link-commons/src/lib.rs +++ b/io/zenoh-link-commons/src/lib.rs @@ -48,6 +48,7 @@ pub struct Link { pub is_reliable: bool, pub is_streamed: bool, pub interfaces: Vec, + pub auth_identifier: AuthIdentifier, } #[async_trait] @@ -77,6 +78,7 @@ impl From<&LinkUnicast> for Link { is_reliable: link.is_reliable(), is_streamed: link.is_streamed(), interfaces: link.get_interface_names(), + auth_identifier: link.get_auth_identifier(), } } } @@ -97,6 +99,10 @@ impl From<&LinkMulticast> for Link { is_reliable: link.is_reliable(), is_streamed: false, interfaces: vec![], + auth_identifier: AuthIdentifier { + username: None, + tls_cert_name: None, + }, } } } diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs index 8aa40103cc..150169c5d3 100644 --- a/io/zenoh-link-commons/src/unicast.rs +++ b/io/zenoh-link-commons/src/unicast.rs @@ -19,6 +19,7 @@ use core::{ hash::{Hash, Hasher}, ops::Deref, }; +use serde::Serialize; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::ZResult; @@ -47,6 +48,7 @@ pub trait LinkUnicastTrait: Send + Sync { fn is_reliable(&self) -> bool; fn is_streamed(&self) -> bool; fn get_interface_names(&self) -> Vec; + fn get_auth_identifier(&self) -> AuthIdentifier; async fn write(&self, buffer: &[u8]) -> ZResult; async fn write_all(&self, buffer: &[u8]) -> ZResult<()>; async fn read(&self, buffer: &mut [u8]) -> ZResult; @@ -115,7 +117,8 @@ pub fn get_ip_interface_names(addr: &SocketAddr) -> Vec { } } -#[derive(Debug)] +#[derive(Clone, Debug, Serialize, Hash, PartialEq, Eq)] + pub struct AuthIdentifier { pub username: Option, pub tls_cert_name: Option, diff --git a/io/zenoh-links/zenoh-link-quic/src/unicast-modified.rs b/io/zenoh-links/zenoh-link-quic/src/unicast-modified.rs deleted file mode 100644 index 88e3befe6c..0000000000 --- a/io/zenoh-links/zenoh-link-quic/src/unicast-modified.rs +++ /dev/null @@ -1,662 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// - -use x509_parser::prelude::*; - -use crate::base64_decode; -use crate::{ - config::*, get_quic_addr, verify::WebPkiVerifierAnyServerName, ALPN_QUIC_HTTP, - QUIC_ACCEPT_THROTTLE_TIME, QUIC_DEFAULT_MTU, QUIC_LOCATOR_PREFIX, -}; -use async_std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; -use async_std::prelude::FutureExt; -use async_std::sync::Mutex as AsyncMutex; -use async_std::task; -use async_std::task::JoinHandle; -use async_trait::async_trait; -use rustls::{Certificate, PrivateKey}; -use rustls_pemfile::Item; -use std::collections::HashMap; -use std::fmt; -use std::io::BufReader; -use std::net::IpAddr; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, RwLock}; -use std::time::Duration; -use zenoh_core::{zasynclock, zread, zwrite}; -use zenoh_link_commons::{ - AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, -}; -use zenoh_protocol::core::{EndPoint, Locator}; -use zenoh_result::{bail, zerror, ZError, ZResult}; -use zenoh_sync::Signal; - -pub struct LinkUnicastQuic { - connection: quinn::Connection, - src_addr: SocketAddr, - src_locator: Locator, - dst_locator: Locator, - send: AsyncMutex, - recv: AsyncMutex, -} - -impl LinkUnicastQuic { - fn new( - connection: quinn::Connection, - src_addr: SocketAddr, - dst_locator: Locator, - send: quinn::SendStream, - recv: quinn::RecvStream, - ) -> LinkUnicastQuic { - // Build the Quic object - LinkUnicastQuic { - connection, - src_addr, - src_locator: Locator::new(QUIC_LOCATOR_PREFIX, src_addr.to_string(), "").unwrap(), - dst_locator, - send: AsyncMutex::new(send), - recv: AsyncMutex::new(recv), - } - } -} - -#[async_trait] -impl LinkUnicastTrait for LinkUnicastQuic { - async fn close(&self) -> ZResult<()> { - log::trace!("Closing QUIC link: {}", self); - // Flush the QUIC stream - let mut guard = zasynclock!(self.send); - if let Err(e) = guard.finish().await { - log::trace!("Error closing QUIC stream {}: {}", self, e); - } - self.connection.close(quinn::VarInt::from_u32(0), &[0]); - Ok(()) - } - - async fn write(&self, buffer: &[u8]) -> ZResult { - let mut guard = zasynclock!(self.send); - guard.write(buffer).await.map_err(|e| { - log::trace!("Write error on QUIC link {}: {}", self, e); - zerror!(e).into() - }) - } - - async fn write_all(&self, buffer: &[u8]) -> ZResult<()> { - let mut guard = zasynclock!(self.send); - guard.write_all(buffer).await.map_err(|e| { - log::trace!("Write error on QUIC link {}: {}", self, e); - zerror!(e).into() - }) - } - - async fn read(&self, buffer: &mut [u8]) -> ZResult { - let mut guard = zasynclock!(self.recv); - guard - .read(buffer) - .await - .map_err(|e| { - let e = zerror!("Read error on QUIC link {}: {}", self, e); - log::trace!("{}", &e); - e - })? - .ok_or_else(|| { - let e = zerror!( - "Read error on QUIC link {}: stream {} has been closed", - self, - guard.id() - ); - log::trace!("{}", &e); - e.into() - }) - } - - async fn read_exact(&self, buffer: &mut [u8]) -> ZResult<()> { - let mut guard = zasynclock!(self.recv); - guard.read_exact(buffer).await.map_err(|e| { - let e = zerror!("Read error on QUIC link {}: {}", self, e); - log::trace!("{}", &e); - e.into() - }) - } - - #[inline(always)] - fn get_src(&self) -> &Locator { - &self.src_locator - } - - #[inline(always)] - fn get_dst(&self) -> &Locator { - &self.dst_locator - } - - #[inline(always)] - fn get_mtu(&self) -> u16 { - *QUIC_DEFAULT_MTU - } - - #[inline(always)] - fn get_interface_names(&self) -> Vec { - // @TODO: Not supported for now - log::debug!("The get_interface_names for LinkUnicastQuic is not supported"); - vec![] - } - - #[inline(always)] - fn is_reliable(&self) -> bool { - true - } - - #[inline(always)] - fn is_streamed(&self) -> bool { - true - } -} - -impl Drop for LinkUnicastQuic { - fn drop(&mut self) { - self.connection.close(quinn::VarInt::from_u32(0), &[0]); - } -} - -impl fmt::Display for LinkUnicastQuic { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{} => {}", - self.src_addr, - self.connection.remote_address() - )?; - Ok(()) - } -} - -impl fmt::Debug for LinkUnicastQuic { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Quic") - .field("src", &self.src_addr) - .field("dst", &self.connection.remote_address()) - .finish() - } -} - -/*************************************/ -/* LISTENER */ -/*************************************/ -struct ListenerUnicastQuic { - endpoint: EndPoint, - active: Arc, - signal: Signal, - handle: JoinHandle>, -} - -impl ListenerUnicastQuic { - fn new( - endpoint: EndPoint, - active: Arc, - signal: Signal, - handle: JoinHandle>, - ) -> ListenerUnicastQuic { - ListenerUnicastQuic { - endpoint, - active, - signal, - handle, - } - } -} - -pub struct LinkManagerUnicastQuic { - manager: NewLinkChannelSender, - listeners: Arc>>, -} - -impl LinkManagerUnicastQuic { - pub fn new(manager: NewLinkChannelSender) -> Self { - Self { - manager, - listeners: Arc::new(RwLock::new(HashMap::new())), - } - } -} - -#[async_trait] -impl LinkManagerUnicastTrait for LinkManagerUnicastQuic { - async fn new_link(&self, endpoint: EndPoint) -> ZResult { - println!("this is called when connecting via quic"); - let epaddr = endpoint.address(); - let host = epaddr - .as_str() - .split(':') - .next() - .ok_or("Endpoints must be of the form quic/
:")?; - let epconf = endpoint.config(); - - let addr = get_quic_addr(&epaddr).await?; - - let server_name_verification: bool = epconf - .get(TLS_SERVER_NAME_VERIFICATION) - .unwrap_or(TLS_SERVER_NAME_VERIFICATION_DEFAULT) - .parse()?; - - if !server_name_verification { - log::warn!("Skipping name verification of servers"); - } - - // Initialize the QUIC connection - let mut root_cert_store = rustls::RootCertStore::empty(); - - // Read the certificates - let f = if let Some(value) = epconf.get(TLS_ROOT_CA_CERTIFICATE_RAW) { - value.as_bytes().to_vec() - } else if let Some(b64_certificate) = epconf.get(TLS_ROOT_CA_CERTIFICATE_BASE64) { - base64_decode(b64_certificate)? - } else if let Some(value) = epconf.get(TLS_ROOT_CA_CERTIFICATE_FILE) { - async_std::fs::read(value) - .await - .map_err(|e| zerror!("Invalid QUIC CA certificate file: {}", e))? - } else { - vec![] - }; - - let certificates = if f.is_empty() { - rustls_native_certs::load_native_certs() - .map_err(|e| zerror!("Invalid QUIC CA certificate file: {}", e))? - .drain(..) - .map(|x| rustls::Certificate(x.to_vec())) - .collect::>() - } else { - rustls_pemfile::certs(&mut BufReader::new(f.as_slice())) - .map(|result| { - result - .map_err(|err| zerror!("Invalid QUIC CA certificate file: {}", err)) - .map(|der| Certificate(der.to_vec())) - }) - .collect::, ZError>>()? - }; - for c in certificates.iter() { - root_cert_store.add(c).map_err(|e| zerror!("{}", e))?; - } - - let client_crypto = rustls::ClientConfig::builder().with_safe_defaults(); - - let mut client_crypto = if server_name_verification { - client_crypto - .with_root_certificates(root_cert_store) - .with_no_client_auth() - } else { - client_crypto - .with_custom_certificate_verifier(Arc::new(WebPkiVerifierAnyServerName::new( - root_cert_store, - ))) - .with_no_client_auth() - }; - - client_crypto.alpn_protocols = ALPN_QUIC_HTTP.iter().map(|&x| x.into()).collect(); - - let ip_addr: IpAddr = if addr.is_ipv4() { - Ipv4Addr::UNSPECIFIED.into() - } else { - Ipv6Addr::UNSPECIFIED.into() - }; - - let mut quic_endpoint = quinn::Endpoint::client(SocketAddr::new(ip_addr, 0)) - .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))?; - - quic_endpoint.set_default_client_config(quinn::ClientConfig::new(Arc::new(client_crypto))); - - let src_addr = quic_endpoint - .local_addr() - .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))?; - println!("tried to make quic_connection"); - - let quic_conn = quic_endpoint - .connect(addr, host) - .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))? - .await - .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))?; - println!("was able to make quic_connection"); - - let (send, recv) = quic_conn - .open_bi() - .await - .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))?; - - // let pi = &quic_conn.peer_identity().unwrap(); - // match pi.downcast_ref::>() { - // Some(serv_certs) => { - // println!("the server certs were found"); - // for item in serv_certs { - // let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); - // let subject_name = &cert - // .subject - // .iter_common_name() - // .next() - // .and_then(|cn| cn.as_str().ok()) - // .unwrap(); - // let auth_identifier = AuthIdentifier { - // username: None, - // tls_cert_name: Some(subject_name.to_string()), - // }; - - // println!("auth_identifier: {:?}", auth_identifier); - // } - // } - // None => { - // println!("no server certs found"); - // } - // } - - let link = Arc::new(LinkUnicastQuic::new( - quic_conn, - src_addr, - endpoint.into(), - send, - recv, - )); - - Ok(LinkUnicast(link)) - } - - async fn new_listener(&self, mut endpoint: EndPoint) -> ZResult { - let epaddr = endpoint.address(); - let epconf = endpoint.config(); - - if epconf.is_empty() { - bail!("No QUIC configuration provided"); - }; - - let addr = get_quic_addr(&epaddr).await?; - - let f = if let Some(value) = epconf.get(TLS_SERVER_CERTIFICATE_RAW) { - value.as_bytes().to_vec() - } else if let Some(b64_certificate) = epconf.get(TLS_SERVER_CERTIFICATE_BASE64) { - base64_decode(b64_certificate)? - } else if let Some(value) = epconf.get(TLS_SERVER_CERTIFICATE_FILE) { - async_std::fs::read(value) - .await - .map_err(|e| zerror!("Invalid QUIC CA certificate file: {}", e))? - } else { - bail!("No QUIC CA certificate has been provided."); - }; - let certificates = rustls_pemfile::certs(&mut BufReader::new(f.as_slice())) - .map(|result| { - result - .map_err(|err| zerror!("Invalid QUIC CA certificate file: {}", err)) - .map(|der| Certificate(der.to_vec())) - }) - .collect::, ZError>>()?; - - // Private keys - let f = if let Some(value) = epconf.get(TLS_SERVER_PRIVATE_KEY_RAW) { - value.as_bytes().to_vec() - } else if let Some(b64_key) = epconf.get(TLS_SERVER_PRIVATE_KEY_BASE64) { - base64_decode(b64_key)? - } else if let Some(value) = epconf.get(TLS_SERVER_PRIVATE_KEY_FILE) { - async_std::fs::read(value) - .await - .map_err(|e| zerror!("Invalid QUIC CA certificate file: {}", e))? - } else { - bail!("No QUIC CA private key has been provided."); - }; - let items: Vec = rustls_pemfile::read_all(&mut BufReader::new(f.as_slice())) - .map(|result| { - result.map_err(|err| zerror!("Invalid QUIC CA private key file: {}", err)) - }) - .collect::, ZError>>()?; - - let private_key = items - .into_iter() - .filter_map(|x| match x { - rustls_pemfile::Item::Pkcs1Key(k) => Some(k.secret_pkcs1_der().to_vec()), - rustls_pemfile::Item::Pkcs8Key(k) => Some(k.secret_pkcs8_der().to_vec()), - rustls_pemfile::Item::Sec1Key(k) => Some(k.secret_sec1_der().to_vec()), - _ => None, - }) - .take(1) - .next() - .ok_or_else(|| zerror!("No QUIC CA private key has been provided.")) - .map(PrivateKey)?; - - // Server config - let mut server_crypto = rustls::ServerConfig::builder() - .with_safe_defaults() - .with_no_client_auth() - .with_single_cert(certificates, private_key)?; - server_crypto.alpn_protocols = ALPN_QUIC_HTTP.iter().map(|&x| x.into()).collect(); - let mut server_config = quinn::ServerConfig::with_crypto(Arc::new(server_crypto)); - - // We do not accept unidireactional streams. - Arc::get_mut(&mut server_config.transport) - .unwrap() - .max_concurrent_uni_streams(0_u8.into()); - // For the time being we only allow one bidirectional stream - Arc::get_mut(&mut server_config.transport) - .unwrap() - .max_concurrent_bidi_streams(1_u8.into()); - - // Initialize the Endpoint - let quic_endpoint = quinn::Endpoint::server(server_config, addr) - .map_err(|e| zerror!("Can not create a new QUIC listener on {}: {}", addr, e))?; - - let local_addr = quic_endpoint - .local_addr() - .map_err(|e| zerror!("Can not create a new QUIC listener on {}: {}", addr, e))?; - - // Update the endpoint locator address - endpoint = EndPoint::new( - endpoint.protocol(), - local_addr.to_string(), - endpoint.metadata(), - endpoint.config(), - )?; - - // Spawn the accept loop for the listener - let active = Arc::new(AtomicBool::new(true)); - let signal = Signal::new(); - let mut listeners = zwrite!(self.listeners); - - let c_active = active.clone(); - let c_signal = signal.clone(); - let c_manager = self.manager.clone(); - let c_listeners = self.listeners.clone(); - let c_addr = local_addr; - let handle = task::spawn(async move { - // Wait for the accept loop to terminate - let res = accept_task(quic_endpoint, c_active, c_signal, c_manager).await; - zwrite!(c_listeners).remove(&c_addr); - res - }); - - // Initialize the QuicAcceptor - let locator = endpoint.to_locator(); - let listener = ListenerUnicastQuic::new(endpoint, active, signal, handle); - // Update the list of active listeners on the manager - listeners.insert(local_addr, listener); - - Ok(locator) - } - - async fn del_listener(&self, endpoint: &EndPoint) -> ZResult<()> { - let epaddr = endpoint.address(); - - let addr = get_quic_addr(&epaddr).await?; - - // Stop the listener - let listener = zwrite!(self.listeners).remove(&addr).ok_or_else(|| { - let e = zerror!( - "Can not delete the QUIC listener because it has not been found: {}", - addr - ); - log::trace!("{}", e); - e - })?; - - // Send the stop signal - listener.active.store(false, Ordering::Release); - listener.signal.trigger(); - listener.handle.await - } - - fn get_listeners(&self) -> Vec { - zread!(self.listeners) - .values() - .map(|x| x.endpoint.clone()) - .collect() - } - - fn get_locators(&self) -> Vec { - let mut locators = vec![]; - - let guard = zread!(self.listeners); - for (key, value) in guard.iter() { - let (kip, kpt) = (key.ip(), key.port()); - - // Either ipv4/0.0.0.0 or ipv6/[::] - if kip.is_unspecified() { - let mut addrs = match kip { - IpAddr::V4(_) => zenoh_util::net::get_ipv4_ipaddrs(), - IpAddr::V6(_) => zenoh_util::net::get_ipv6_ipaddrs(), - }; - let iter = addrs.drain(..).map(|x| { - Locator::new( - value.endpoint.protocol(), - SocketAddr::new(x, kpt).to_string(), - value.endpoint.metadata(), - ) - .unwrap() - }); - locators.extend(iter); - } else { - locators.push(value.endpoint.to_locator()); - } - } - - locators - } -} - -async fn accept_task( - endpoint: quinn::Endpoint, - active: Arc, - signal: Signal, - manager: NewLinkChannelSender, -) -> ZResult<()> { - enum Action { - Accept(quinn::Connection), - Stop, - } - - async fn accept(acceptor: quinn::Accept<'_>) -> ZResult { - let qc = acceptor - .await - .ok_or_else(|| zerror!("Can not accept QUIC connections: acceptor closed"))?; - - let conn = qc.await.map_err(|e| { - let e = zerror!("QUIC acceptor failed: {:?}", e); - log::warn!("{}", e); - e - })?; - - Ok(Action::Accept(conn)) - } - - async fn stop(signal: Signal) -> ZResult { - signal.wait().await; - Ok(Action::Stop) - } - - let src_addr = endpoint - .local_addr() - .map_err(|e| zerror!("Can not accept QUIC connections: {}", e))?; - - // The accept future - log::trace!("Ready to accept QUIC connections on: {:?}", src_addr); - while active.load(Ordering::Acquire) { - // Wait for incoming connections - let quic_conn = match accept(endpoint.accept()).race(stop(signal.clone())).await { - Ok(action) => match action { - Action::Accept(qc) => qc, - Action::Stop => break, - }, - Err(e) => { - log::warn!("{} Hint: increase the system open file limit.", e); - // Throttle the accept loop upon an error - // NOTE: This might be due to various factors. However, the most common case is that - // the process has reached the maximum number of open files in the system. On - // Linux systems this limit can be changed by using the "ulimit" command line - // tool. In case of systemd-based systems, this can be changed by using the - // "sysctl" command line tool. - task::sleep(Duration::from_micros(*QUIC_ACCEPT_THROTTLE_TIME)).await; - continue; - } - }; - - // Get the bideractional streams. Note that we don't allow unidirectional streams. - let (send, recv) = match quic_conn.accept_bi().await { - Ok(stream) => stream, - Err(e) => { - log::warn!("QUIC connection has no streams: {:?}", e); - continue; - } - }; - - // Create the new link object - // let pi = &quic_conn.peer_identity().unwrap(); - //println!("the accept function is also called before check"); - - // match quic_conn - // .peer_identity() - // .unwrap() - // .downcast_ref::>() - // { - // Some(serv_certs) => { - // println!("the client certs were found"); - // for item in serv_certs { - // let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); - // let subject_name = &cert - // .subject - // .iter_common_name() - // .next() - // .and_then(|cn| cn.as_str().ok()) - // .unwrap(); - // let auth_identifier = AuthIdentifier { - // username: None, - // tls_cert_name: Some(subject_name.to_string()), - // }; - - // println!("auth_identifier: {:?}", auth_identifier); - // } - // } - // None => { - // println!("no client certs found"); - // } - // } - let dst_addr = quic_conn.remote_address(); - log::debug!("Accepted QUIC connection on {:?}: {:?}", src_addr, dst_addr); - let link = Arc::new(LinkUnicastQuic::new( - quic_conn, - src_addr, - Locator::new(QUIC_LOCATOR_PREFIX, dst_addr.to_string(), "")?, - send, - recv, - )); - - // Communicate the new link to the initial transport manager - if let Err(e) = manager.send_async(LinkUnicast(link)).await { - log::error!("{}-{}: {}", file!(), line!(), e) - } - } - - Ok(()) -} diff --git a/io/zenoh-links/zenoh-link-quic/src/unicast.rs b/io/zenoh-links/zenoh-link-quic/src/unicast.rs index 366860801e..13903eb1b2 100644 --- a/io/zenoh-links/zenoh-link-quic/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-quic/src/unicast.rs @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // +use x509_parser::prelude::*; use crate::base64_decode; use crate::{ @@ -32,7 +33,7 @@ use std::sync::Arc; use std::time::Duration; use zenoh_core::zasynclock; use zenoh_link_commons::{ - get_ip_interface_names, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, + get_ip_interface_names, AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, }; use zenoh_protocol::core::{EndPoint, Locator}; @@ -46,6 +47,7 @@ pub struct LinkUnicastQuic { dst_locator: Locator, send: AsyncMutex, recv: AsyncMutex, + auth_identifier: Option, } impl LinkUnicastQuic { @@ -55,6 +57,7 @@ impl LinkUnicastQuic { dst_locator: Locator, send: quinn::SendStream, recv: quinn::RecvStream, + auth_identifier: Option, ) -> LinkUnicastQuic { // Build the Quic object LinkUnicastQuic { @@ -64,6 +67,7 @@ impl LinkUnicastQuic { dst_locator, send: AsyncMutex::new(send), recv: AsyncMutex::new(recv), + auth_identifier, } } } @@ -156,6 +160,15 @@ impl LinkUnicastTrait for LinkUnicastQuic { fn is_streamed(&self) -> bool { true } + fn get_auth_identifier(&self) -> AuthIdentifier { + match &self.auth_identifier { + Some(identifier) => identifier.clone(), + None => AuthIdentifier { + username: None, + tls_cert_name: None, + }, + } + } } impl Drop for LinkUnicastQuic { @@ -296,14 +309,42 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastQuic { .await .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))?; + let mut test_auth_id: Option = None; + + let pi = &quic_conn.peer_identity().unwrap(); + match pi.downcast_ref::>() { + Some(serv_certs) => { + println!("the server certs were found"); + for item in serv_certs { + let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); + let subject_name = &cert + .subject + .iter_common_name() + .next() + .and_then(|cn| cn.as_str().ok()) + .unwrap(); + let auth_identifier = AuthIdentifier { + username: None, + tls_cert_name: Some(subject_name.to_string()), + }; + + println!("server side quic auth_identifier: {:?}", auth_identifier); + test_auth_id = Some(auth_identifier); + } + } + None => { + println!("no server certs found"); + } + } + let link = Arc::new(LinkUnicastQuic::new( quic_conn, src_addr, endpoint.into(), send, recv, + test_auth_id, )); - Ok(LinkUnicast(link)) } @@ -501,6 +542,51 @@ async fn accept_task( continue; } }; + println!("the accept function is also called before check"); + let mut test_auth_id: Option = None; + { + let new_conn = quic_conn.clone(); + println!( + "handshake information: {:?}", + new_conn + .handshake_data() + .unwrap() + .downcast_ref::() + .unwrap() + .server_name + ); + //println!("connection info: {:?}", new_conn); + if let Some(cert_info) = new_conn.peer_identity() { + //use cert info + + match cert_info.downcast_ref::>() { + Some(serv_certs) => { + println!("the client certs were found"); + for item in serv_certs { + let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); + let subject_name = &cert + .subject + .iter_common_name() + .next() + .and_then(|cn| cn.as_str().ok()) + .unwrap(); + let auth_identifier = AuthIdentifier { + username: None, + tls_cert_name: Some(subject_name.to_string()), + }; + + println!("client side quic auth_identifier: {:?}", auth_identifier); + test_auth_id = Some(auth_identifier); + } + } + None => { + println!("no client certs found"); + } + } + } else { + println!("no certs were found"); + } + } let dst_addr = quic_conn.remote_address(); log::debug!("Accepted QUIC connection on {:?}: {:?}", src_addr, dst_addr); @@ -511,6 +597,7 @@ async fn accept_task( Locator::new(QUIC_LOCATOR_PREFIX, dst_addr.to_string(), "")?, send, recv, + test_auth_id, )); // Communicate the new link to the initial transport manager diff --git a/io/zenoh-links/zenoh-link-serial/src/unicast.rs b/io/zenoh-links/zenoh-link-serial/src/unicast.rs index fafac4c393..9f28d251a1 100644 --- a/io/zenoh-links/zenoh-link-serial/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-serial/src/unicast.rs @@ -25,8 +25,8 @@ use std::sync::{Arc, RwLock}; use std::time::Duration; use zenoh_core::{zasynclock, zread, zwrite}; use zenoh_link_commons::{ - ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, - NewLinkChannelSender, + AuthIdentifier, ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, + LinkUnicastTrait, NewLinkChannelSender, }; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::{zerror, ZResult}; @@ -206,6 +206,12 @@ impl LinkUnicastTrait for LinkUnicastSerial { fn is_streamed(&self) -> bool { false } + fn get_auth_identifier(&self) -> AuthIdentifier { + AuthIdentifier { + username: None, + tls_cert_name: None, + } + } } impl fmt::Display for LinkUnicastSerial { diff --git a/io/zenoh-links/zenoh-link-tcp/src/unicast.rs b/io/zenoh-links/zenoh-link-tcp/src/unicast.rs index b01d8be22e..22367aa2ee 100644 --- a/io/zenoh-links/zenoh-link-tcp/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-tcp/src/unicast.rs @@ -22,7 +22,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::Duration; use zenoh_link_commons::{ - get_ip_interface_names, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, + get_ip_interface_names, AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, BIND_INTERFACE, }; use zenoh_protocol::core::{EndPoint, Locator}; @@ -156,6 +156,12 @@ impl LinkUnicastTrait for LinkUnicastTcp { fn is_streamed(&self) -> bool { true } + fn get_auth_identifier(&self) -> AuthIdentifier { + AuthIdentifier { + username: None, + tls_cert_name: None, + } + } } impl Drop for LinkUnicastTcp { diff --git a/io/zenoh-links/zenoh-link-tls/src/unicast-modified.rs b/io/zenoh-links/zenoh-link-tls/src/unicast-modified.rs deleted file mode 100644 index 4d6f316fbd..0000000000 --- a/io/zenoh-links/zenoh-link-tls/src/unicast-modified.rs +++ /dev/null @@ -1,916 +0,0 @@ -// -// Copyright (c) 2023 ZettaScale Technology -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License 2.0 which is available at -// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// -// Contributors: -// ZettaScale Zenoh Team, -// -use x509_parser::prelude::*; - -use crate::{ - base64_decode, config::*, get_tls_addr, get_tls_host, get_tls_server_name, - verify::WebPkiVerifierAnyServerName, TLS_ACCEPT_THROTTLE_TIME, TLS_DEFAULT_MTU, - TLS_LINGER_TIMEOUT, TLS_LOCATOR_PREFIX, -}; -use async_rustls::{ - rustls::{ - server::AllowAnyAuthenticatedClient, version::TLS13, Certificate, ClientConfig, - OwnedTrustAnchor, PrivateKey, RootCertStore, ServerConfig, - }, - TlsAcceptor, TlsConnector, TlsStream, -}; -use async_std::fs; -use async_std::net::{SocketAddr, TcpListener, TcpStream}; -use async_std::prelude::FutureExt; -use async_std::sync::Mutex as AsyncMutex; -use async_std::task; -use async_std::task::JoinHandle; -use async_trait::async_trait; -use futures::io::AsyncReadExt; -use futures::io::AsyncWriteExt; -use std::collections::HashMap; -use std::convert::TryInto; -use std::fmt; -use std::fs::File; -use std::io::{BufReader, Cursor}; -use std::net::{IpAddr, Shutdown}; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, RwLock}; -use std::time::Duration; -use std::{cell::UnsafeCell, io}; -use webpki::{ - anchor_from_trusted_cert, - types::{CertificateDer, TrustAnchor}, -}; -use zenoh_core::{zasynclock, zread, zwrite}; -use zenoh_link_commons::{ - AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, -}; -use zenoh_protocol::core::endpoint::Config; -use zenoh_protocol::core::{EndPoint, Locator}; -use zenoh_result::{bail, zerror, ZError, ZResult}; -use zenoh_sync::Signal; - -pub struct LinkUnicastTls { - // The underlying socket as returned from the async-rustls library - // NOTE: TlsStream requires &mut for read and write operations. This means - // that concurrent reads and writes are not possible. To achieve that, - // we use an UnsafeCell for interior mutability. Using an UnsafeCell - // is safe in our case since the transmission and reception logic - // already ensures that no concurrent reads or writes can happen on - // the same stream: there is only one task at the time that writes on - // the stream and only one task at the time that reads from the stream. - inner: UnsafeCell>, - // The source socket address of this link (address used on the local host) - src_addr: SocketAddr, - src_locator: Locator, - // The destination socket address of this link (address used on the local host) - dst_addr: SocketAddr, - dst_locator: Locator, - // Make sure there are no concurrent read or writes - write_mtx: AsyncMutex<()>, - read_mtx: AsyncMutex<()>, -} - -unsafe impl Send for LinkUnicastTls {} -unsafe impl Sync for LinkUnicastTls {} - -impl LinkUnicastTls { - fn new( - socket: TlsStream, - src_addr: SocketAddr, - dst_addr: SocketAddr, - ) -> LinkUnicastTls { - let (tcp_stream, _) = socket.get_ref(); - // Set the TLS nodelay option - if let Err(err) = tcp_stream.set_nodelay(true) { - log::warn!( - "Unable to set NODEALY option on TLS link {} => {}: {}", - src_addr, - dst_addr, - err - ); - } - - // Set the TLS linger option - if let Err(err) = zenoh_util::net::set_linger( - tcp_stream, - Some(Duration::from_secs( - (*TLS_LINGER_TIMEOUT).try_into().unwrap(), - )), - ) { - log::warn!( - "Unable to set LINGER option on TLS link {} => {}: {}", - src_addr, - dst_addr, - err - ); - } - - // Build the Tls object - LinkUnicastTls { - inner: UnsafeCell::new(socket), - src_addr, - src_locator: Locator::new(TLS_LOCATOR_PREFIX, src_addr.to_string(), "").unwrap(), - dst_addr, - dst_locator: Locator::new(TLS_LOCATOR_PREFIX, dst_addr.to_string(), "").unwrap(), - write_mtx: AsyncMutex::new(()), - read_mtx: AsyncMutex::new(()), - } - } - - // NOTE: It is safe to suppress Clippy warning since no concurrent reads - // or concurrent writes will ever happen. The read_mtx and write_mtx - // are respectively acquired in any read and write operation. - #[allow(clippy::mut_from_ref)] - fn get_sock_mut(&self) -> &mut TlsStream { - unsafe { &mut *self.inner.get() } - } -} - -#[async_trait] -impl LinkUnicastTrait for LinkUnicastTls { - async fn close(&self) -> ZResult<()> { - log::trace!("Closing TLS link: {}", self); - // Flush the TLS stream - let _guard = zasynclock!(self.write_mtx); - let tls_stream = self.get_sock_mut(); - let res = tls_stream.flush().await; - log::trace!("TLS link flush {}: {:?}", self, res); - // Close the underlying TCP stream - let (tcp_stream, _) = tls_stream.get_ref(); - let res = tcp_stream.shutdown(Shutdown::Both); - log::trace!("TLS link shutdown {}: {:?}", self, res); - res.map_err(|e| zerror!(e).into()) - } - - async fn write(&self, buffer: &[u8]) -> ZResult { - let _guard = zasynclock!(self.write_mtx); - self.get_sock_mut().write(buffer).await.map_err(|e| { - log::trace!("Write error on TLS link {}: {}", self, e); - zerror!(e).into() - }) - } - - async fn write_all(&self, buffer: &[u8]) -> ZResult<()> { - let _guard = zasynclock!(self.write_mtx); - self.get_sock_mut().write_all(buffer).await.map_err(|e| { - log::trace!("Write error on TLS link {}: {}", self, e); - zerror!(e).into() - }) - } - - async fn read(&self, buffer: &mut [u8]) -> ZResult { - let _guard = zasynclock!(self.read_mtx); - self.get_sock_mut().read(buffer).await.map_err(|e| { - log::trace!("Read error on TLS link {}: {}", self, e); - zerror!(e).into() - }) - } - - async fn read_exact(&self, buffer: &mut [u8]) -> ZResult<()> { - let _guard = zasynclock!(self.read_mtx); - self.get_sock_mut().read_exact(buffer).await.map_err(|e| { - log::trace!("Read error on TLS link {}: {}", self, e); - zerror!(e).into() - }) - } - - #[inline(always)] - fn get_src(&self) -> &Locator { - &self.src_locator - } - - #[inline(always)] - fn get_dst(&self) -> &Locator { - &self.dst_locator - } - - #[inline(always)] - fn get_mtu(&self) -> u16 { - *TLS_DEFAULT_MTU - } - - #[inline(always)] - fn get_interface_names(&self) -> Vec { - // @TODO: Not supported for now - log::debug!("The get_interface_names for LinkUnicastTls is not supported"); - vec![] - } - - #[inline(always)] - fn is_reliable(&self) -> bool { - true - } - - #[inline(always)] - fn is_streamed(&self) -> bool { - true - } -} - -impl Drop for LinkUnicastTls { - fn drop(&mut self) { - // Close the underlying TCP stream - let (tcp_stream, _) = self.get_sock_mut().get_ref(); - let _ = tcp_stream.shutdown(Shutdown::Both); - } -} - -impl fmt::Display for LinkUnicastTls { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{} => {}", self.src_addr, self.dst_addr)?; - Ok(()) - } -} - -impl fmt::Debug for LinkUnicastTls { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Tls") - .field("src", &self.src_addr) - .field("dst", &self.dst_addr) - .finish() - } -} - -/*************************************/ -/* LISTENER */ -/*************************************/ -struct ListenerUnicastTls { - endpoint: EndPoint, - active: Arc, - signal: Signal, - handle: JoinHandle>, -} - -impl ListenerUnicastTls { - fn new( - endpoint: EndPoint, - active: Arc, - signal: Signal, - handle: JoinHandle>, - ) -> ListenerUnicastTls { - ListenerUnicastTls { - endpoint, - active, - signal, - handle, - } - } -} - -pub struct LinkManagerUnicastTls { - manager: NewLinkChannelSender, - listeners: Arc>>, -} - -impl LinkManagerUnicastTls { - pub fn new(manager: NewLinkChannelSender) -> Self { - Self { - manager, - listeners: Arc::new(RwLock::new(HashMap::new())), - } - } -} - -#[async_trait] -impl LinkManagerUnicastTrait for LinkManagerUnicastTls { - async fn new_link(&self, endpoint: EndPoint) -> ZResult { - let epaddr = endpoint.address(); - let epconf = endpoint.config(); - - let server_name = get_tls_server_name(&epaddr)?; - let addr = get_tls_addr(&epaddr).await?; - - // Initialize the TLS Config - let client_config = TlsClientConfig::new(&epconf) - .await - .map_err(|e| zerror!("Cannot create a new TLS listener to {endpoint}: {e}"))?; - let config = Arc::new(client_config.client_config); - let connector = TlsConnector::from(config); - - // Initialize the TcpStream - let tcp_stream = TcpStream::connect(addr).await.map_err(|e| { - zerror!( - "Can not create a new TLS link bound to {:?}: {}", - server_name, - e - ) - })?; - - let src_addr = tcp_stream.local_addr().map_err(|e| { - zerror!( - "Can not create a new TLS link bound to {:?}: {}", - server_name, - e - ) - })?; - - let dst_addr = tcp_stream.peer_addr().map_err(|e| { - zerror!( - "Can not create a new TLS link bound to {:?}: {}", - server_name, - e - ) - })?; - - // Initialize the TlsStream - let tls_stream = connector - .connect(server_name.to_owned(), tcp_stream) - .await - .map_err(|e| { - zerror!( - "Can not create a new TLS link bound to {:?}: {}", - server_name, - e - ) - })?; - let (_, tls_conn) = tls_stream.get_ref(); - - let serv_certs = tls_conn.peer_certificates().unwrap(); - - for item in serv_certs { - let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); - let subject_name = &cert - .subject - .iter_common_name() - .next() - .and_then(|cn| cn.as_str().ok()) - .unwrap(); - let auth_identifier = AuthIdentifier { - username: None, - tls_cert_name: Some(subject_name.to_string()), - }; - - println!("auth_identifier: {:?}", auth_identifier); - } - let tls_stream = TlsStream::Client(tls_stream); - let link = Arc::new(LinkUnicastTls::new(tls_stream, src_addr, dst_addr)); - - Ok(LinkUnicast(link)) - } - - async fn new_listener(&self, endpoint: EndPoint) -> ZResult { - let epaddr = endpoint.address(); - let epconf = endpoint.config(); - - let addr = get_tls_addr(&epaddr).await?; - let host = get_tls_host(&epaddr)?; - - // Initialize TlsConfig - let tls_server_config = TlsServerConfig::new(&epconf) - .await - .map_err(|e| zerror!("Cannot create a new TLS listener on {addr}. {e}"))?; - - // Initialize the TcpListener - let socket = TcpListener::bind(addr) - .await - .map_err(|e| zerror!("Can not create a new TLS listener on {}: {}", addr, e))?; - - let local_addr = socket - .local_addr() - .map_err(|e| zerror!("Can not create a new TLS listener on {}: {}", addr, e))?; - let local_port = local_addr.port(); - - // Initialize the TlsAcceptor - let acceptor = TlsAcceptor::from(Arc::new(tls_server_config.server_config)); - let active = Arc::new(AtomicBool::new(true)); - let signal = Signal::new(); - - // Spawn the accept loop for the listener - let c_active = active.clone(); - let c_signal = signal.clone(); - let c_manager = self.manager.clone(); - let c_listeners = self.listeners.clone(); - let c_addr = local_addr; - let handle = task::spawn(async move { - // Wait for the accept loop to terminate - let res = accept_task(socket, acceptor, c_active, c_signal, c_manager).await; - zwrite!(c_listeners).remove(&c_addr); - res - }); - - // Update the endpoint locator address - let locator = Locator::new( - endpoint.protocol(), - format!("{host}:{local_port}"), - endpoint.metadata(), - )?; - - let listener = ListenerUnicastTls::new(endpoint, active, signal, handle); - // Update the list of active listeners on the manager - zwrite!(self.listeners).insert(local_addr, listener); - - Ok(locator) - } - - async fn del_listener(&self, endpoint: &EndPoint) -> ZResult<()> { - let epaddr = endpoint.address(); - - let addr = get_tls_addr(&epaddr).await?; - - // Stop the listener - let listener = zwrite!(self.listeners).remove(&addr).ok_or_else(|| { - let e = zerror!( - "Can not delete the TLS listener because it has not been found: {}", - addr - ); - log::trace!("{}", e); - e - })?; - - // Send the stop signal - listener.active.store(false, Ordering::Release); - listener.signal.trigger(); - listener.handle.await - } - - fn get_listeners(&self) -> Vec { - zread!(self.listeners) - .values() - .map(|x| x.endpoint.clone()) - .collect() - } - - fn get_locators(&self) -> Vec { - let mut locators = vec![]; - - let guard = zread!(self.listeners); - for (key, value) in guard.iter() { - let (kip, kpt) = (key.ip(), key.port()); - - // Either ipv4/0.0.0.0 or ipv6/[::] - if kip.is_unspecified() { - let mut addrs = match kip { - IpAddr::V4(_) => zenoh_util::net::get_ipv4_ipaddrs(), - IpAddr::V6(_) => zenoh_util::net::get_ipv6_ipaddrs(), - }; - let iter = addrs.drain(..).map(|x| { - Locator::new( - value.endpoint.protocol(), - SocketAddr::new(x, kpt).to_string(), - value.endpoint.metadata(), - ) - .unwrap() - }); - locators.extend(iter); - } else { - locators.push(value.endpoint.to_locator()); - } - } - - locators - } -} - -async fn accept_task( - socket: TcpListener, - acceptor: TlsAcceptor, - active: Arc, - signal: Signal, - manager: NewLinkChannelSender, -) -> ZResult<()> { - enum Action { - Accept((TcpStream, SocketAddr)), - Stop, - } - - async fn accept(socket: &TcpListener) -> ZResult { - let res = socket.accept().await.map_err(|e| zerror!(e))?; - Ok(Action::Accept(res)) - } - - async fn stop(signal: Signal) -> ZResult { - signal.wait().await; - Ok(Action::Stop) - } - - let src_addr = socket.local_addr().map_err(|e| { - let e = zerror!("Can not accept TLS connections: {}", e); - log::warn!("{}", e); - e - })?; - - log::trace!("Ready to accept TLS connections on: {:?}", src_addr); - while active.load(Ordering::Acquire) { - // Wait for incoming connections - let (tcp_stream, dst_addr) = match accept(&socket).race(stop(signal.clone())).await { - Ok(action) => match action { - Action::Accept((tcp_stream, dst_addr)) => (tcp_stream, dst_addr), - Action::Stop => break, - }, - Err(e) => { - log::warn!("{}. Hint: increase the system open file limit.", e); - // Throttle the accept loop upon an error - // NOTE: This might be due to various factors. However, the most common case is that - // the process has reached the maximum number of open files in the system. On - // Linux systems this limit can be changed by using the "ulimit" command line - // tool. In case of systemd-based systems, this can be changed by using the - // "sysctl" command line tool. - task::sleep(Duration::from_micros(*TLS_ACCEPT_THROTTLE_TIME)).await; - continue; - } - }; - // Accept the TLS connection - let tls_stream = match acceptor.accept(tcp_stream).await { - Ok(stream) => TlsStream::Server(stream), - Err(e) => { - let e = format!("Can not accept TLS connection: {e}"); - log::warn!("{}", e); - continue; - } - }; - let (_, tls_conn) = tls_stream.get_ref(); - let auth_identifier = get_tls_cert_name(tls_conn); - match auth_identifier { - Some(auth_id) => println!("client's ID: {:?}", auth_id), - None => println!("no client ID found"), - } - - log::debug!("Accepted TLS connection on {:?}: {:?}", src_addr, dst_addr); - // Create the new link object - let link = Arc::new(LinkUnicastTls::new(tls_stream, src_addr, dst_addr)); - - // Communicate the new link to the initial transport manager - if let Err(e) = manager.send_async(LinkUnicast(link)).await { - log::error!("{}-{}: {}", file!(), line!(), e) - } - } - - Ok(()) -} -fn get_tls_cert_name(tls_conn: &rustls::CommonState) -> Option { - let serv_certs = tls_conn.peer_certificates()?; - let (_, cert) = X509Certificate::from_der(serv_certs[0].as_ref()).unwrap(); - let subject_name = &cert - .subject - .iter_common_name() - .next() - .and_then(|cn| cn.as_str().ok()) - .unwrap(); - - Some(AuthIdentifier { - username: None, - tls_cert_name: Some(subject_name.to_string()), - }) -} -struct TlsServerConfig { - server_config: ServerConfig, -} - -impl TlsServerConfig { - pub async fn new(config: &Config<'_>) -> ZResult { - let tls_server_client_auth: bool = match config.get(TLS_CLIENT_AUTH) { - Some(s) => s - .parse() - .map_err(|_| zerror!("Unknown client auth argument: {}", s))?, - None => false, - }; - let tls_server_private_key = TlsServerConfig::load_tls_private_key(config).await?; - let tls_server_certificate = TlsServerConfig::load_tls_certificate(config).await?; - - let certs: Vec = - rustls_pemfile::certs(&mut Cursor::new(&tls_server_certificate)) - .map(|result| { - result - .map_err(|err| zerror!("Error processing server certificate: {err}.")) - .map(|der| Certificate(der.to_vec())) - }) - .collect::, ZError>>()?; - - let mut keys: Vec = - rustls_pemfile::rsa_private_keys(&mut Cursor::new(&tls_server_private_key)) - .map(|result| { - result - .map_err(|err| zerror!("Error processing server key: {err}.")) - .map(|key| PrivateKey(key.secret_pkcs1_der().to_vec())) - }) - .collect::, ZError>>()?; - - if keys.is_empty() { - keys = rustls_pemfile::pkcs8_private_keys(&mut Cursor::new(&tls_server_private_key)) - .map(|result| { - result - .map_err(|err| zerror!("Error processing server key: {err}.")) - .map(|key| PrivateKey(key.secret_pkcs8_der().to_vec())) - }) - .collect::, ZError>>()?; - } - - if keys.is_empty() { - keys = rustls_pemfile::ec_private_keys(&mut Cursor::new(&tls_server_private_key)) - .map(|result| { - result - .map_err(|err| zerror!("Error processing server key: {err}.")) - .map(|key| PrivateKey(key.secret_sec1_der().to_vec())) - }) - .collect::, ZError>>()?; - } - - if keys.is_empty() { - bail!("No private key found for TLS server."); - } - - let sc = if tls_server_client_auth { - let root_cert_store = load_trust_anchors(config)?.map_or_else( - || { - Err(zerror!( - "Missing root certificates while client authentication is enabled." - )) - }, - Ok, - )?; - ServerConfig::builder() - .with_safe_default_cipher_suites() - .with_safe_default_kx_groups() - .with_protocol_versions(&[&TLS13]) // Force TLS 1.3 - .map_err(|e| zerror!(e))? - .with_client_cert_verifier(Arc::new(AllowAnyAuthenticatedClient::new(root_cert_store))) - .with_single_cert(certs, keys.remove(0)) - .map_err(|e| zerror!(e))? - } else { - ServerConfig::builder() - .with_safe_defaults() - .with_no_client_auth() - .with_single_cert(certs, keys.remove(0)) - .map_err(|e| zerror!(e))? - }; - Ok(TlsServerConfig { server_config: sc }) - } - - async fn load_tls_private_key(config: &Config<'_>) -> ZResult> { - load_tls_key( - config, - TLS_SERVER_PRIVATE_KEY_RAW, - TLS_SERVER_PRIVATE_KEY_FILE, - TLS_SERVER_PRIVATE_KEY_BASE_64, - ) - .await - } - - async fn load_tls_certificate(config: &Config<'_>) -> ZResult> { - load_tls_certificate( - config, - TLS_SERVER_CERTIFICATE_RAW, - TLS_SERVER_CERTIFICATE_FILE, - TLS_SERVER_CERTIFICATE_BASE64, - ) - .await - } -} - -struct TlsClientConfig { - client_config: ClientConfig, -} - -impl TlsClientConfig { - pub async fn new(config: &Config<'_>) -> ZResult { - let tls_client_server_auth: bool = match config.get(TLS_CLIENT_AUTH) { - Some(s) => s - .parse() - .map_err(|_| zerror!("Unknown client auth argument: {}", s))?, - None => false, - }; - - let tls_server_name_verification: bool = match config.get(TLS_SERVER_NAME_VERIFICATION) { - Some(s) => { - let s: bool = s - .parse() - .map_err(|_| zerror!("Unknown server name verification argument: {}", s))?; - if s { - log::warn!("Skipping name verification of servers"); - } - s - } - None => false, - }; - - // Allows mixed user-generated CA and webPKI CA - log::debug!("Loading default Web PKI certificates."); - let mut root_cert_store: RootCertStore = RootCertStore { - roots: load_default_webpki_certs().roots, - }; - - if let Some(custom_root_cert) = load_trust_anchors(config)? { - log::debug!("Loading user-generated certificates."); - root_cert_store.add_trust_anchors(custom_root_cert.roots.into_iter()); - } - - let cc = if tls_client_server_auth { - log::debug!("Loading client authentication key and certificate..."); - let tls_client_private_key = TlsClientConfig::load_tls_private_key(config).await?; - let tls_client_certificate = TlsClientConfig::load_tls_certificate(config).await?; - - let certs: Vec = - rustls_pemfile::certs(&mut Cursor::new(&tls_client_certificate)) - .map(|result| { - result - .map_err(|err| zerror!("Error processing client certificate: {err}.")) - .map(|der| Certificate(der.to_vec())) - }) - .collect::, ZError>>()?; - - let mut keys: Vec = - rustls_pemfile::rsa_private_keys(&mut Cursor::new(&tls_client_private_key)) - .map(|result| { - result - .map_err(|err| zerror!("Error processing client key: {err}.")) - .map(|key| PrivateKey(key.secret_pkcs1_der().to_vec())) - }) - .collect::, ZError>>()?; - - if keys.is_empty() { - keys = - rustls_pemfile::pkcs8_private_keys(&mut Cursor::new(&tls_client_private_key)) - .map(|result| { - result - .map_err(|err| zerror!("Error processing client key: {err}.")) - .map(|key| PrivateKey(key.secret_pkcs8_der().to_vec())) - }) - .collect::, ZError>>()?; - } - - if keys.is_empty() { - keys = rustls_pemfile::ec_private_keys(&mut Cursor::new(&tls_client_private_key)) - .map(|result| { - result - .map_err(|err| zerror!("Error processing client key: {err}.")) - .map(|key| PrivateKey(key.secret_sec1_der().to_vec())) - }) - .collect::, ZError>>()?; - } - - if keys.is_empty() { - bail!("No private key found for TLS client."); - } - - let builder = ClientConfig::builder() - .with_safe_default_cipher_suites() - .with_safe_default_kx_groups() - .with_protocol_versions(&[&TLS13]) - .map_err(|e| zerror!("Config parameters should be valid: {}", e))?; - - if tls_server_name_verification { - builder - .with_root_certificates(root_cert_store) - .with_client_auth_cert(certs, keys.remove(0)) - } else { - builder - .with_custom_certificate_verifier(Arc::new(WebPkiVerifierAnyServerName::new( - root_cert_store, - ))) - .with_client_auth_cert(certs, keys.remove(0)) - } - .map_err(|e| zerror!("Bad certificate/key: {}", e))? - } else { - let builder = ClientConfig::builder().with_safe_defaults(); - if tls_server_name_verification { - builder - .with_root_certificates(root_cert_store) - .with_no_client_auth() - } else { - builder - .with_custom_certificate_verifier(Arc::new(WebPkiVerifierAnyServerName::new( - root_cert_store, - ))) - .with_no_client_auth() - } - }; - Ok(TlsClientConfig { client_config: cc }) - } - - async fn load_tls_private_key(config: &Config<'_>) -> ZResult> { - load_tls_key( - config, - TLS_CLIENT_PRIVATE_KEY_RAW, - TLS_CLIENT_PRIVATE_KEY_FILE, - TLS_CLIENT_PRIVATE_KEY_BASE64, - ) - .await - } - - async fn load_tls_certificate(config: &Config<'_>) -> ZResult> { - load_tls_certificate( - config, - TLS_CLIENT_CERTIFICATE_RAW, - TLS_CLIENT_CERTIFICATE_FILE, - TLS_CLIENT_CERTIFICATE_BASE64, - ) - .await - } -} - -async fn load_tls_key( - config: &Config<'_>, - tls_private_key_raw_config_key: &str, - tls_private_key_file_config_key: &str, - tls_private_key_base64_config_key: &str, -) -> ZResult> { - if let Some(value) = config.get(tls_private_key_raw_config_key) { - return Ok(value.as_bytes().to_vec()); - } else if let Some(b64_key) = config.get(tls_private_key_base64_config_key) { - return base64_decode(b64_key); - } else if let Some(value) = config.get(tls_private_key_file_config_key) { - return Ok(fs::read(value) - .await - .map_err(|e| zerror!("Invalid TLS private key file: {}", e))?) - .and_then(|result| { - if result.is_empty() { - Err(zerror!("Empty TLS key.").into()) - } else { - Ok(result) - } - }); - } - Err(zerror!("Missing TLS private key.").into()) -} - -async fn load_tls_certificate( - config: &Config<'_>, - tls_certificate_raw_config_key: &str, - tls_certificate_file_config_key: &str, - tls_certificate_base64_config_key: &str, -) -> ZResult> { - if let Some(value) = config.get(tls_certificate_raw_config_key) { - return Ok(value.as_bytes().to_vec()); - } else if let Some(b64_certificate) = config.get(tls_certificate_base64_config_key) { - return base64_decode(b64_certificate); - } else if let Some(value) = config.get(tls_certificate_file_config_key) { - return Ok(fs::read(value) - .await - .map_err(|e| zerror!("Invalid TLS certificate file: {}", e))?); - } - Err(zerror!("Missing tls certificates.").into()) -} - -fn load_trust_anchors(config: &Config<'_>) -> ZResult> { - let mut root_cert_store = RootCertStore::empty(); - if let Some(value) = config.get(TLS_ROOT_CA_CERTIFICATE_RAW) { - let mut pem = BufReader::new(value.as_bytes()); - let trust_anchors = process_pem(&mut pem)?; - root_cert_store.add_trust_anchors(trust_anchors.into_iter()); - return Ok(Some(root_cert_store)); - } - - if let Some(b64_certificate) = config.get(TLS_ROOT_CA_CERTIFICATE_BASE64) { - let certificate_pem = base64_decode(b64_certificate)?; - let mut pem = BufReader::new(certificate_pem.as_slice()); - let trust_anchors = process_pem(&mut pem)?; - root_cert_store.add_trust_anchors(trust_anchors.into_iter()); - return Ok(Some(root_cert_store)); - } - - if let Some(filename) = config.get(TLS_ROOT_CA_CERTIFICATE_FILE) { - let mut pem = BufReader::new(File::open(filename)?); - let trust_anchors = process_pem(&mut pem)?; - root_cert_store.add_trust_anchors(trust_anchors.into_iter()); - return Ok(Some(root_cert_store)); - } - Ok(None) -} - -fn process_pem(pem: &mut dyn io::BufRead) -> ZResult> { - let certs: Vec = rustls_pemfile::certs(pem) - .map(|result| result.map_err(|err| zerror!("Error processing PEM certificates: {err}."))) - .collect::, ZError>>()?; - - let trust_anchors: Vec = certs - .into_iter() - .map(|cert| { - anchor_from_trusted_cert(&cert) - .map_err(|err| zerror!("Error processing trust anchor: {err}.")) - .map(|trust_anchor| trust_anchor.to_owned()) - }) - .collect::, ZError>>()?; - - let owned_trust_anchors: Vec = trust_anchors - .into_iter() - .map(|ta| { - OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject.to_vec(), - ta.subject_public_key_info.to_vec(), - ta.name_constraints.map(|x| x.to_vec()), - ) - }) - .collect(); - - Ok(owned_trust_anchors) -} - -fn load_default_webpki_certs() -> RootCertStore { - let mut root_cert_store = RootCertStore::empty(); - root_cert_store.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { - OwnedTrustAnchor::from_subject_spki_name_constraints( - ta.subject.to_vec(), - ta.subject_public_key_info.to_vec(), - ta.name_constraints.clone().map(|x| x.to_vec()), - ) - })); - root_cert_store -} diff --git a/io/zenoh-links/zenoh-link-tls/src/unicast.rs b/io/zenoh-links/zenoh-link-tls/src/unicast.rs index 8cb2d32698..5b744ed353 100644 --- a/io/zenoh-links/zenoh-link-tls/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-tls/src/unicast.rs @@ -74,6 +74,7 @@ pub struct LinkUnicastTls { // Make sure there are no concurrent read or writes write_mtx: AsyncMutex<()>, read_mtx: AsyncMutex<()>, + auth_identifier: Option, } unsafe impl Send for LinkUnicastTls {} @@ -84,6 +85,7 @@ impl LinkUnicastTls { socket: TlsStream, src_addr: SocketAddr, dst_addr: SocketAddr, + auth_identifier: Option, ) -> LinkUnicastTls { let (tcp_stream, _) = socket.get_ref(); // Set the TLS nodelay option @@ -120,6 +122,7 @@ impl LinkUnicastTls { dst_locator: Locator::new(TLS_LOCATOR_PREFIX, dst_addr.to_string(), "").unwrap(), write_mtx: AsyncMutex::new(()), read_mtx: AsyncMutex::new(()), + auth_identifier, } } @@ -209,6 +212,16 @@ impl LinkUnicastTrait for LinkUnicastTls { fn is_streamed(&self) -> bool { true } + #[inline(always)] + fn get_auth_identifier(&self) -> AuthIdentifier { + match &self.auth_identifier { + Some(identifier) => identifier.clone(), + None => AuthIdentifier { + username: None, + tls_cert_name: None, + }, + } + } } impl Drop for LinkUnicastTls { @@ -305,6 +318,7 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastTls { let (_, tls_conn) = tls_stream.get_ref(); let serv_certs = tls_conn.peer_certificates().unwrap(); + let mut test_auth_id: Option = None; for item in serv_certs { let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); @@ -319,11 +333,17 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastTls { tls_cert_name: Some(subject_name.to_string()), }; - println!("auth_identifier: {:?}", auth_identifier); + println!("server side tls auth_identifier: {:?}", auth_identifier); + test_auth_id = Some(auth_identifier); } let tls_stream = TlsStream::Client(tls_stream); - let link = Arc::new(LinkUnicastTls::new(tls_stream, src_addr, dst_addr)); + let link = Arc::new(LinkUnicastTls::new( + tls_stream, + src_addr, + dst_addr, + test_auth_id, + )); Ok(LinkUnicast(link)) } @@ -451,15 +471,22 @@ async fn accept_task( }; let (_, tls_conn) = tls_stream.get_ref(); + //let mut test_auth_id: Option = None; let auth_identifier = get_tls_cert_name(tls_conn); - match auth_identifier { - Some(auth_id) => println!("client's ID: {:?}", auth_id), - None => println!("no client ID found"), - } + println!("client side tls auth_identifier: {:?}", auth_identifier); + // match auth_identifier { + // Some(auth_id) => println!("client's ID: {:?}", auth_id), + // None => println!("no client ID found"), + // } log::debug!("Accepted TLS connection on {:?}: {:?}", src_addr, dst_addr); // Create the new link object - let link = Arc::new(LinkUnicastTls::new(tls_stream, src_addr, dst_addr)); + let link = Arc::new(LinkUnicastTls::new( + tls_stream, + src_addr, + dst_addr, + auth_identifier, + )); // Communicate the new link to the initial transport manager if let Err(e) = manager.send_async(LinkUnicast(link)).await { diff --git a/io/zenoh-links/zenoh-link-udp/src/unicast.rs b/io/zenoh-links/zenoh-link-udp/src/unicast.rs index d5214510be..2dde7bc085 100644 --- a/io/zenoh-links/zenoh-link-udp/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-udp/src/unicast.rs @@ -27,8 +27,9 @@ use std::sync::{Arc, Mutex, Weak}; use std::time::Duration; use zenoh_core::{zasynclock, zlock}; use zenoh_link_commons::{ - get_ip_interface_names, ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, - LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, BIND_INTERFACE, + get_ip_interface_names, AuthIdentifier, ConstructibleLinkManagerUnicast, + LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, + NewLinkChannelSender, BIND_INTERFACE, }; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::{bail, zerror, Error as ZError, ZResult}; @@ -220,6 +221,12 @@ impl LinkUnicastTrait for LinkUnicastUdp { fn is_streamed(&self) -> bool { false } + fn get_auth_identifier(&self) -> AuthIdentifier { + AuthIdentifier { + username: None, + tls_cert_name: None, + } + } } impl fmt::Display for LinkUnicastUdp { diff --git a/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs b/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs index 83f6414dee..0fb4e7d2ef 100644 --- a/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs +++ b/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs @@ -35,8 +35,8 @@ use zenoh_protocol::core::{EndPoint, Locator}; use unix_named_pipe::{create, open_write}; use zenoh_link_commons::{ - ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, - NewLinkChannelSender, + AuthIdentifier, ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, + LinkUnicastTrait, NewLinkChannelSender, }; use zenoh_result::{bail, ZResult}; @@ -508,6 +508,12 @@ impl LinkUnicastTrait for UnicastPipe { fn is_streamed(&self) -> bool { true } + fn get_auth_identifier(&self) -> AuthIdentifier { + AuthIdentifier { + username: None, + tls_cert_name: None, + } + } } impl fmt::Display for UnicastPipe { diff --git a/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs b/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs index 3ac1bcbfe6..3111108438 100644 --- a/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs @@ -31,7 +31,7 @@ use std::time::Duration; use uuid::Uuid; use zenoh_core::{zread, zwrite}; use zenoh_link_commons::{ - LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, + AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::{zerror, ZResult}; @@ -131,6 +131,12 @@ impl LinkUnicastTrait for LinkUnicastUnixSocketStream { fn is_streamed(&self) -> bool { true } + fn get_auth_identifier(&self) -> AuthIdentifier { + AuthIdentifier { + username: None, + tls_cert_name: None, + } + } } impl Drop for LinkUnicastUnixSocketStream { diff --git a/io/zenoh-links/zenoh-link-ws/src/unicast.rs b/io/zenoh-links/zenoh-link-ws/src/unicast.rs index 0ff1b1ab46..33862dc89c 100644 --- a/io/zenoh-links/zenoh-link-ws/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-ws/src/unicast.rs @@ -32,6 +32,7 @@ use tokio_tungstenite::accept_async; use tokio_tungstenite::tungstenite::Message; use tokio_tungstenite::{MaybeTlsStream, WebSocketStream}; use zenoh_core::{zasynclock, zread, zwrite}; +use zenoh_link_commons::AuthIdentifier; use zenoh_link_commons::{ LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; @@ -223,6 +224,12 @@ impl LinkUnicastTrait for LinkUnicastWs { fn is_streamed(&self) -> bool { false } + fn get_auth_identifier(&self) -> AuthIdentifier { + AuthIdentifier { + username: None, + tls_cert_name: None, + } + } } impl Drop for LinkUnicastWs { diff --git a/myed25519.key b/myed25519.key new file mode 100644 index 0000000000..eec2318e30 --- /dev/null +++ b/myed25519.key @@ -0,0 +1,3 @@ +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIHqhe4/aAYsQ7CY1XCLIwCh+5nEZcCyIRZCbJcS233gc +-----END PRIVATE KEY----- diff --git a/myedserver.crt b/myedserver.crt new file mode 100644 index 0000000000..79f686e84a --- /dev/null +++ b/myedserver.crt @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBvTCCAW+gAwIBAgIUNfcUs1gokRmiNXzXRxeVsK8PAVEwBQYDK2VwMFQxCzAJ +BgNVBAYTAkZSMQswCQYDVQQIDAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpz +LCBJbmMuMRgwFgYDVQQDDA90ZXN0X3Rsc19zZXJ2ZXIwHhcNMjQwMzExMTUxNjA3 +WhcNMjUwMzExMTUxNjA3WjBUMQswCQYDVQQGEwJGUjELMAkGA1UECAwCSUYxCzAJ +BgNVBAcMAlBSMREwDwYDVQQKDAh6cywgSW5jLjEYMBYGA1UEAwwPdGVzdF90bHNf +c2VydmVyMCowBQYDK2VwAyEAtHIXi5k5PlaXGcUoqvN71aNZXipGzSiCrWfinY3r +zLejUzBRMB0GA1UdDgQWBBSCTrn8VCUbrLpvVaxc0e9tWWluRzAfBgNVHSMEGDAW +gBSCTrn8VCUbrLpvVaxc0e9tWWluRzAPBgNVHRMBAf8EBTADAQH/MAUGAytlcANB +AD9CgSNdcqVpoPGkwFqHnvDkTs9LxFOQWTMoUfnBMayOCOAKNl10LAyF6ST85QZc +USlMTo7EbXm/RmdqCBq3LQI= +-----END CERTIFICATE----- diff --git a/mypub2.crt b/mypub2.crt new file mode 100644 index 0000000000..63a916d900 --- /dev/null +++ b/mypub2.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDjTCCAnWgAwIBAgIUcK4p0GvmJBQ3LpiK7iY4EwTlhekwDQYJKoZIhvcNAQEL +BQAwVTELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGTAXBgNVBAMMEHpzX3Rlc3Rfcm9vdF9jYTIwHhcNMjQw +MzEzMTMxOTI2WhcNMjUwMzEzMTMxOTI2WjBQMQswCQYDVQQGEwJGUjELMAkGA1UE +CAwCSUYxCzAJBgNVBAcMAlBSMREwDwYDVQQKDAh6cywgSW5jLjEUMBIGA1UEAwwL +cHViMl9zZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCp7qWN +2iA0+rhJMyyVrFXGcsqPNvz1ASTz2PHqhIOvS/tH2yaYaPkVGI3NHxvMp/USWUGj +we95ow2k7uPhuJ9q615tZ2u5+NFWjy72FU5MB0sFDbwB7Amb57KG5OyKk3gYyojL +TTyRevkMpokbpWfUoCgLx6LjMwzAlnbOoipsrh8Bg4VLadvhBFGfYtN6PrYOr5S1 +79L86aelaFZbxFqEmGmTQ8e8fPBn0DMasL8cIzavkkE+CAEXQV9SGIGddSc6MLVz +61mmh6umivfYEY4ZkkS4mK7zcKquhoYdLZK4yZWu+BtgCe+H4+jD3+Rv9TJ5YFU4 +MOCvgymUyOw4PExBAgMBAAGjWjBYMBYGA1UdEQQPMA2CC3B1YjJfc2VydmVyMB0G +A1UdDgQWBBTVL7smU8+53bqP3c7hvu21SNs5SzAfBgNVHSMEGDAWgBTbO03TDw3d +xyHU6YTEOL5mgdBVrDANBgkqhkiG9w0BAQsFAAOCAQEAKUbq0+KYUJthA51n/rV9 +dNhWqFRqKOuW5ubgK4NlgJxhRxE4HYjeqW41vMgbUYqcYrRlR/Mxg02AW0RE/TSl +31ptkDKVie2okJrAMGkz30M7N1Y4bTYEkdt0t4+cYr3ZqJF8uZfZCc3BWZlDTzWI +4N7zyxFvLE8qEsjkkAGMZYZyvudXsp9bSwtdLH6krOsFO1kbr1rjg/T7u9Dv8OvY +XPlWOOMXPM2pQV/eZP4/8LuuzLMrjROPx7oRNSbOzCNT3+pfiZh2A4pH8O1K5Jus +lcGN5lwsAQEkyQgVBC/XXmQ14Ke0yFXz/JRxM+wOD+UT8J5I4N6lRUrlaGJk/RtG +mA== +-----END CERTIFICATE----- diff --git a/mypub2.key b/mypub2.key new file mode 100644 index 0000000000..331427b8d0 --- /dev/null +++ b/mypub2.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCp7qWN2iA0+rhJ +MyyVrFXGcsqPNvz1ASTz2PHqhIOvS/tH2yaYaPkVGI3NHxvMp/USWUGjwe95ow2k +7uPhuJ9q615tZ2u5+NFWjy72FU5MB0sFDbwB7Amb57KG5OyKk3gYyojLTTyRevkM +pokbpWfUoCgLx6LjMwzAlnbOoipsrh8Bg4VLadvhBFGfYtN6PrYOr5S179L86ael +aFZbxFqEmGmTQ8e8fPBn0DMasL8cIzavkkE+CAEXQV9SGIGddSc6MLVz61mmh6um +ivfYEY4ZkkS4mK7zcKquhoYdLZK4yZWu+BtgCe+H4+jD3+Rv9TJ5YFU4MOCvgymU +yOw4PExBAgMBAAECggEABY9+Eli3YhRsMFUA2fr0KZS7BRmvCFNbwrDwJZTlfDh3 +xf+pUSZqNCMEDNi+P6GlVs7d435mmCvaN/HrOgkhCk4eXmUadNDsBLGVv06uK7W3 +YjhzVPrEy7m2sUxPYy91KBaEiGaEG1yTRrMyXFm6vo3pEY2cSmPywGCMDbHnwnuY +c/7ggx5XtvbDYkv4HZdiu0ZtxZGk4YhNXv58mHM24rmQLWwA7Y1Rw+amHqcStMQJ +BT64YqOnCO5fI6dx889zo9XAvRe7Nv9Fu4FOa2SneqyfkR9819CuxclJ1rAkYnFk +St5vrf19J2rwyAaoT1gA+jQ3Lj2SiZN3mEgPnBp32QKBgQDbtxgYfzXKdxJebwXy +9jl8iEp+8TVOvj+7AWj6AnfFgiqyXlWE891MSa5srxtxtFjwJGoDUB/ySd2DsXmo +rhx7SF5P7moUmg53D+qta1CORebaJ9/kcWnAGSZkraVFhEx0XghIctdWoXE9jWf8 +k3vt5Vq791v5WPzlMbf8rktvVQKBgQDF/uAc/vSFSl9+q+8ArhmZbHioLq8fSsIr +RvYofOVIUXYGHZI9lY+qqDMU/icizsg2Rm2VVCWTLeqBMpsxmaV+2KWAsqHh0hm8 +0m2vReN0TDnr4P6/ul53sEmNxXwd3NWeY+PhcH186vkPuwqycNHOT/R7aio5RXQK +wj/NrSWxPQKBgFAyL2BZplelSJYhbgl1qBv1X0OgZTW9qWNnq1p95hu4XD9IwWxK +2r6KsljHPXwuOLxGfk+BQnfcUDdOYzqXepvhGVORkTS92oPI0n7ECd40U4PTRByM +7O2KAIKFAysxk/pxjBJtoH3lZYDzCT6e0oBN0+WB7xc/TOeXUzGuqKgVAoGAa8mr +fF2YBJBOmIlFXdtp+EpDDVwM3j42opTJIZWMxOgEFqQ2nuwzADb9SCpsZ9imylVh +BvB+XDec+KTyM/hvTjTnNL8KvgNBG7h7GfY0M3Xj+nPMe9gb4ZDJGjMutJsqeEXt +Iye4SS8qU9QBqM8eiPCiKiXLws36tHi3f2MJqAkCgYEAkFu7cG50zH+k/qs/UOzk +FQXSVboVooBkHlOBpC+mjD7uPm69Id/83UsF+5wTZSW0EuZ6IxC/M+uuRX2qINv9 +RDDqXaszxvpPaNhjdoir4mGgnXYOgg256F4dqSTiBSlNH5puRkAiG8J+Ng4aPnES +YJYfM97wJO8rXKaA8z+TOjQ= +-----END PRIVATE KEY----- diff --git a/mysub.csr b/mysub.csr deleted file mode 100644 index dbe6d89071..0000000000 --- a/mysub.csr +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIICmDCCAYACAQAwUzELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQH -DAJQUjERMA8GA1UECgwIenMsIEluYy4xFzAVBgNVBAMMDnN1Yl90bHNfY2xpZW50 -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm8MSy4j1uWUoebudOtO8 -XUgnOOyvNbzRfIS5qkrVuTYRbjfO8pIwari4ZPxpN3VSzRFcKv6/EZP+qNITAen+ -8xj9+3nwOlD3eEC2x8Iw0ow07pOjrpf8Velz2eQWekSad1YpVqfXgSZy9QFt57Nt -ht99EE3UhBKPkrvArjm24S3Lwas86e2W6Z2hIlfjBFxsrzsMIitZt9Ao5zp3ZdaV -0koqOSJmdAmVucNBR2OIlA28K/6MQzGwLgz9g2OlpPXGrt/HWhyFh1Vm9a7dzV5h -ixX2C/MpWYZQ6w9ahdcr189D7dmkTQB9xSxia59y+robQPMYgRmvDpJlyuq+NFpF -nwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEBAIBa6ccode0L5STQm7npmTVJmx+w -doTDcM7dAUdc4iaDkQLKiEsUl7pClsbroZCVB/CctxkthukgZS5w8PSt1nJPqe7Q -lUrv88ARDPOBS6+XTIJZyXBxvz01DtvHxsLUmedPfVDGqQYCWGudcX+KWkJEApTz -pw888FneR+aKe2QatyoGfF3C0zSeZY2el/f6CHV9RFEBIBuPGZO05wfHPcDo92Kb -VScgQi/eMD81x3nKPD208CyyK3o96tUAQjzpXivHSnJmdDc4H6pKs3ufy0T0R3T/ -RwcY34MHhu5BxJ9gC0YQD0PlObFBL2MuQi/OlnmWcQ2R3UIKyw0jaSG42Ak= ------END CERTIFICATE REQUEST----- diff --git a/peer_pub.json5 b/peer_pub.json5 new file mode 100644 index 0000000000..cf5e2a343e --- /dev/null +++ b/peer_pub.json5 @@ -0,0 +1,12 @@ +{ + "mode": "peer", + "transport": { + "link": { + "tls": { + "root_ca_certificate": "ca.crt", + "server_private_key": "mypub2.key", + "server_certificate": "mypub2.crt" + } + } + } +} \ No newline at end of file diff --git a/peer_sub.json5 b/peer_sub.json5 new file mode 100644 index 0000000000..7143210394 --- /dev/null +++ b/peer_sub.json5 @@ -0,0 +1,12 @@ +{ + "mode": "peer", + "transport": { + "link": { + "tls": { + "root_ca_certificate": "ca.crt", + "server_private_key": "mysub.key", + "server_certificate": "mysub.crt" + } + } + } +} \ No newline at end of file diff --git a/pub_client.json5 b/pub_client.json5 index c33f5de2e4..b98cb7dcb4 100644 --- a/pub_client.json5 +++ b/pub_client.json5 @@ -173,7 +173,10 @@ /// If not configured, all the supported protocols are automatically whitelisted. /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] /// For example, to only enable "tls" and "quic": - // protocols: ["tls", "quic"], + protocols: [ + "tls", + "quic" + ], /// Configure the zenoh TX parameters of a link tx: { /// The resolution in bits to be used for the message sequence numbers. diff --git a/router.json5 b/router.json5 index 82afaf8f20..56ff9b5efa 100644 --- a/router.json5 +++ b/router.json5 @@ -173,7 +173,9 @@ /// If not configured, all the supported protocols are automatically whitelisted. /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] /// For example, to only enable "tls" and "quic": - // protocols: ["tls", "quic"], + protocols: [ + "tls" + ], /// Configure the zenoh TX parameters of a link tx: { /// The resolution in bits to be used for the message sequence numbers. diff --git a/router_quic.json5 b/router_quic.json5 new file mode 100644 index 0000000000..512e40aa29 --- /dev/null +++ b/router_quic.json5 @@ -0,0 +1,56 @@ +{ + mode: "peer", + /// Configure the scouting mechanisms and their behaviours +scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 0, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 0, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: false, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: false, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: false, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + "transport": { + "link": { + "protocols": [ + "quic", + // "tls" + ], + "tls": { + "root_ca_certificate": "client_ca.pem", + "client_auth": false, + "server_private_key": "server_key.pem", + "server_certificate": "server_cert.pem" + } + } + } +} \ No newline at end of file diff --git a/server_ca.pem b/server_ca.pem new file mode 100644 index 0000000000..83e287e214 --- /dev/null +++ b/server_ca.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIITcwv1N10nqEwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw +MzA2MTY0MTA2WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSA0ZGNjMmYwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2WUgN7NMlXIknew1cXiTWGmS0 +1T1EjcNNDAq7DqZ7/ZVXrjD47yxTt5EOiOXK/cINKNw4Zq/MKQvq9qu+Oax4lwiV +Ha0i8ShGLSuYI1HBlXu4MmvdG+3/SjwYoGsGaShr0y/QGzD3cD+DQZg/RaaIPHlO +MdmiUXxkMcy4qa0hFJ1imlJdq/6Tlx46X+0vRCh8nkekvOZR+t7Z5U4jn4XE54Kl +0PiwcyX8vfDZ3epa/FSHZvVQieM/g5Yh9OjIKCkdWRg7tD0IEGsaW11tEPJ5SiQr +mDqdRneMzZKqY0xC+QqXSvIlzpOjiu8PYQx7xugaUFE/npKRQdvh8ojHJMdNAgMB +AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr +BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTX46+p+Po1npE6 +QLQ7mMI+83s6qDAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDANBgkq +hkiG9w0BAQsFAAOCAQEAaN0IvEC677PL/JXzMrXcyBV88IvimlYN0zCt48GYlhmx +vL1YUDFLJEB7J+dyERGE5N6BKKDGblC4WiTFgDMLcHFsMGRc0v7zKPF1PSBwRYJi +ubAmkwdunGG5pDPUYtTEDPXMlgClZ0YyqSFJMOqA4IzQg6exVjXtUxPqzxNhyC7S +vlgUwPbX46uNi581a9+Ls2V3fg0ZnhkTSctYZHGZNeh0Nsf7Am8xdUDYG/bZcVef +jbQ9gpChosdjF0Bgblo7HSUct/2Va+YlYwW+WFjJX8k4oN6ZU5W5xhdfO8Czmgwk +US5kJ/+1M0uR8zUhZHL61FbsdPxEj+fYKrHv4woo+A== +-----END CERTIFICATE----- diff --git a/server_cert.pem b/server_cert.pem new file mode 100644 index 0000000000..0afe5c63b8 --- /dev/null +++ b/server_cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDLjCCAhagAwIBAgIIW1mAtJWJAJYwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw +MzA2MTY0MTA2WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCYMLJKooc+YRlKEMfeV09pX9myH34eUcUuT0fXS8lm +PlZ/NW7mm5lDwa8EUg61WuXQv2ouQDptmIcdeb/w4RW93Xflkyng1Xbd91OwQBJd ++8ZVBjzL7hSRk3QPDqx/CVBU/I1GmXKzb6cWzq1fTkOn1WLNXf21I6p7+N3qHLPF +JQeoVq1HBBFcAjTgJnpyQNvRGLDuLTK+OsWEGib2U8qrgiRdkaBLkxGXSlGABlOo +cQyW/zOhf4pwb2Z/JAge2mRW5IcexCPBWint8ydPsoJDds8j5+AyYCD6HUhHX0Ob +Qkz73OW7f2PQhuTK2uzKy0Yz6lNFt2nuzaWC04wIW3T7AgMBAAGjdjB0MA4GA1Ud +DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +AQH/BAIwADAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDAUBgNVHREE +DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAAxrmQPG54ybKgMVliN8 +Mg5povSdPIVVnlU/HOVG9yxzAOav/xQP003M4wqpatWxI8tR1PcLuZf0EPmcdJgb +tVl9nZMVZtveQnYMlU8PpkEVu56VM4Zr3rH9liPRlr0JEAXODdKw76kWKzmdqWZ/ +rzhup3Ek7iEX6T5j/cPUvTWtMD4VEK2I7fgoKSHIX8MIVzqM7cuboGWPtS3eRNXl +MgvahA4TwLEXPEe+V1WAq6nSb4g2qSXWIDpIsy/O1WGS/zzRnKvXu9/9NkXWqZMl +C1LSpiiQUaRSglOvYf/Zx6r+4BOS4OaaArwHkecZQqBSCcBLEAyb/FaaXdBowI0U +PQ4= +-----END CERTIFICATE----- diff --git a/server_key.pem b/server_key.pem new file mode 100644 index 0000000000..24fa62a138 --- /dev/null +++ b/server_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAmDCySqKHPmEZShDH3ldPaV/Zsh9+HlHFLk9H10vJZj5WfzVu +5puZQ8GvBFIOtVrl0L9qLkA6bZiHHXm/8OEVvd135ZMp4NV23fdTsEASXfvGVQY8 +y+4UkZN0Dw6sfwlQVPyNRplys2+nFs6tX05Dp9VizV39tSOqe/jd6hyzxSUHqFat +RwQRXAI04CZ6ckDb0Riw7i0yvjrFhBom9lPKq4IkXZGgS5MRl0pRgAZTqHEMlv8z +oX+KcG9mfyQIHtpkVuSHHsQjwVop7fMnT7KCQ3bPI+fgMmAg+h1IR19Dm0JM+9zl +u39j0IbkytrsystGM+pTRbdp7s2lgtOMCFt0+wIDAQABAoIBADNTSO2uvlmlOXgn +DKDJZTiuYKaXxFrJTOx/REUxg+x9XYJtLMeM9jVJnpKgceFrlFHAHDkY5BuN8xNX +ugmsfz6W8BZ2eQsgMoRNIuYv1YHopUyLW/mSg1FNHzjsw/Pb2kGvIp4Kpgopv3oL +naCkrmBtsHJ+Hk/2hUpl9cE8iMwVWcVevLzyHi98jNy1IDdIPhRtl0dhMiqC5MRr +4gLJ5gNkLYX7xf3tw5Hmfk/bVNProqZXDIQVI7rFvItX586nvQ3LNQkmW/D2ShZf +3FEqMu6EdA2Ycc4UZgAlQNGV0VBrWWVXizOQ+9gjLnBk3kJjqfigCU6NG94bTJ+H +0YIhsGECgYEAwdSSyuMSOXgzZQ7Vv+GsNn/7ivi/H8eb/lDzksqS/JroA2ciAmHG +2OF30eUJKRg+STqBTpOfXgS4QUa8QLSwBSnwcw6579x9bYGUhqD2Ypaw9uCnOukA +CwwggZ9cDmF0tb5rYjqkW3bFPqkCnTGb0ylMFaYRhRDU20iG5t8PQckCgYEAyQEM +KK18FLQUKivGrQgP5Ib6IC3myzlHGxDzfobXGpaQntFnHY7Cxp/6BBtmASzt9Jxu +etnrevmzrbKqsLTJSg3ivbiq0YTLAJ1FsZrCp71dx49YR/5o9QFiq0nQoKnwUVeb +/hrDjMAokNkjFL5vouXO711GSS6YyM4WzAKZAqMCgYEAhqGxaG06jmJ4SFx6ibIl +nSFeRhQrJNbP+mCeHrrIR98NArgS/laN+Lz7LfaJW1r0gIa7pCmTi4l5thV80vDu +RlfwJOr4qaucD4Du+mg5WxdSSdiXL6sBlarRtVdMaMy2dTqTegJDgShJLxHTt/3q +P0yzBWJ5TtT3FG0XDqum/EkCgYAYNHwWWe3bQGQ9P9BI/fOL/YUZYu2sA1XAuKXZ +0rsMhJ0dwvG76XkjGhitbe82rQZqsnvLZ3qn8HHmtOFBLkQfGtT3K8nGOUuI42eF +H7HZKUCly2lCIizZdDVBkz4AWvaJlRc/3lE2Hd3Es6E52kTvROVKhdz06xuS8t5j +6twqKQKBgQC01AeiWL6Rzo+yZNzVgbpeeDogaZz5dtmURDgCYH8yFX5eoCKLHfnI +2nDIoqpaHY0LuX+dinuH+jP4tlyndbc2muXnHd9r0atytxA69ay3sSA5WFtfi4ef +ESElGO6qXEA821RpQp+2+uhL90+iC294cPqlS5LDmvTMypVDHzrxPQ== +-----END RSA PRIVATE KEY----- diff --git a/sub_client.json5 b/sub_client.json5 index f04cc43b6d..30a688c176 100644 --- a/sub_client.json5 +++ b/sub_client.json5 @@ -234,29 +234,29 @@ max_message_size: 1073741824, }, /// Configure TLS specific parameters - tls: { - root_ca_certificate: "ca.crt" - } // tls: { - // /// Path to the certificate of the certificate authority used to validate either the server - // /// or the client's keys and certificates, depending on the node's mode. If not specified - // /// on router mode then the default WebPKI certificates are used instead. - // root_ca_certificate: null, - // /// Path to the TLS server private key - // server_private_key: null, - // /// Path to the TLS server public certificate - // server_certificate: null, - // /// Client authentication, if true enables mTLS (mutual authentication) - // client_auth: false, - // /// Path to the TLS client private key - // client_private_key: null, - // /// Path to the TLS client public certificate - // client_certificate: null, - // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. - // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your - // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). - // server_name_verification: null, - // }, + // root_ca_certificate: "ca.crt" + // } + tls: { + /// Path to the certificate of the certificate authority used to validate either the server + /// or the client's keys and certificates, depending on the node's mode. If not specified + /// on router mode then the default WebPKI certificates are used instead. + root_ca_certificate: "ca.crt", + /// Path to the TLS server private key + server_private_key: null, + /// Path to the TLS server public certificate + server_certificate: null, + /// Client authentication, if true enables mTLS (mutual authentication) + client_auth: false, + /// Path to the TLS client private key + client_private_key: null, + /// Path to the TLS client public certificate + client_certificate: null, + // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + server_name_verification: null, + }, }, /// Shared memory configuration shared_memory: { diff --git a/zenoh/src/net/routing/interceptor/mod.rs b/zenoh/src/net/routing/interceptor/mod.rs index 9dfc03ac7e..bec391983c 100644 --- a/zenoh/src/net/routing/interceptor/mod.rs +++ b/zenoh/src/net/routing/interceptor/mod.rs @@ -26,7 +26,9 @@ use zenoh_result::ZResult; use zenoh_transport::{multicast::TransportMulticast, unicast::TransportUnicast}; pub mod downsampling; +pub mod testing_interceptor; use crate::net::routing::interceptor::downsampling::downsampling_interceptor_factories; +use crate::net::routing::interceptor::testing_interceptor::new_test_interceptor; pub(crate) trait InterceptorTrait { fn compute_keyexpr_cache(&self, key_expr: &KeyExpr<'_>) -> Option>; @@ -60,7 +62,7 @@ pub(crate) fn interceptor_factories(config: &Config) -> ZResult, +} +struct IngressTestInterceptor { + _auth_id: Option, +} + +pub(crate) fn new_test_interceptor() -> ZResult> { + let res: Vec = vec![Box::new(TestInterceptor {})]; + Ok(res) +} + +impl InterceptorFactoryTrait for TestInterceptor { + fn new_transport_unicast( + &self, + transport: &TransportUnicast, + ) -> (Option, Option) { + if let Ok(links) = transport.get_links() { + for link in links { + println!("value recevied in interceptor {:?}", link.auth_identifier); + } + } + + ( + Some(Box::new(IngressTestInterceptor { _auth_id: None })), + Some(Box::new(EgressTestInterceptor { _auth_id: None })), + ) + } + + fn new_transport_multicast( + &self, + _transport: &TransportMulticast, + ) -> Option { + None + } + + fn new_peer_multicast(&self, _transport: &TransportMulticast) -> Option { + None + } +} + +impl InterceptorTrait for IngressTestInterceptor { + fn compute_keyexpr_cache(&self, key_expr: &KeyExpr<'_>) -> Option> { + let _ = key_expr; + None + } + fn intercept<'a>( + &self, + ctx: RoutingContext, + cache: Option<&Box>, + ) -> Option> { + let _ = cache; + Some(ctx) + } +} + +impl InterceptorTrait for EgressTestInterceptor { + fn compute_keyexpr_cache(&self, key_expr: &KeyExpr<'_>) -> Option> { + let _ = key_expr; + None + } + fn intercept<'a>( + &self, + ctx: RoutingContext, + cache: Option<&Box>, + ) -> Option> { + let _ = cache; + Some(ctx) + } +} From 4e91772bbb381e6fd82d40afc671e94ab48f9a68 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Mon, 18 Mar 2024 11:38:29 +0100 Subject: [PATCH 05/37] remove secret files --- ca.crt | 21 --- ca.key | 28 --- ca2.crt | 21 --- client.json5 | 433 ---------------------------------------------- client_ca.pem | 20 --- client_cert.pem | 20 --- client_key.pem | 27 --- client_quic.json5 | 56 ------ myed25519.key | 3 - myedserver.crt | 12 -- mypub.crt | 22 --- mypub.key | 28 --- mypub2.crt | 22 --- mypub2.key | 28 --- myserver.crt | 22 --- myserver.key | 28 --- mysub.crt | 22 --- mysub.key | 28 --- newmyserver.crt | 22 --- newmyserver.key | 28 --- peer_pub.json5 | 12 -- peer_sub.json5 | 12 -- pub_client.json5 | 433 ---------------------------------------------- router.json5 | 433 ---------------------------------------------- router_quic.json5 | 56 ------ server_ca.pem | 20 --- server_cert.pem | 20 --- server_key.pem | 27 --- sub_client.json5 | 430 --------------------------------------------- 29 files changed, 2334 deletions(-) delete mode 100644 ca.crt delete mode 100644 ca.key delete mode 100644 ca2.crt delete mode 100644 client.json5 delete mode 100644 client_ca.pem delete mode 100644 client_cert.pem delete mode 100644 client_key.pem delete mode 100644 client_quic.json5 delete mode 100644 myed25519.key delete mode 100644 myedserver.crt delete mode 100644 mypub.crt delete mode 100644 mypub.key delete mode 100644 mypub2.crt delete mode 100644 mypub2.key delete mode 100644 myserver.crt delete mode 100644 myserver.key delete mode 100644 mysub.crt delete mode 100644 mysub.key delete mode 100644 newmyserver.crt delete mode 100644 newmyserver.key delete mode 100644 peer_pub.json5 delete mode 100644 peer_sub.json5 delete mode 100644 pub_client.json5 delete mode 100644 router.json5 delete mode 100644 router_quic.json5 delete mode 100644 server_ca.pem delete mode 100644 server_cert.pem delete mode 100644 server_key.pem delete mode 100644 sub_client.json5 diff --git a/ca.crt b/ca.crt deleted file mode 100644 index 50b4d876ca..0000000000 --- a/ca.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDiTCCAnGgAwIBAgIUO1x6LAlICgKs5+pYUTo4CughfKEwDQYJKoZIhvcNAQEL -BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G -A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz -MTExNDM0MjNaFw0yNTAzMTExNDM0MjNaMFQxCzAJBgNVBAYTAkZSMQswCQYDVQQI -DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRgwFgYDVQQDDA96 -c190ZXN0X3Jvb3RfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3 -pFWM+IJNsRCYHt1v/TliecppwVZV+ZHfFw9JKN9ev4K/fWHUiAOwp91MOLxbaYKd -C6dxW28YVGltoGz3kUZJZcJRQVso1jXv24Op4muOsiYXukLc4TU2F6dG1XqkLt5t -svsYAQFf1uK3//QZFVRBosJEn+jjiJ4XCvt49mnPRolp1pNKX0z31mZO6bSly6c9 -OVlJMjWpDCYSOuf6qZZ36fa9eSut2bRJIPY0QCsgnqYBTnIEhksS+3jy6Qt+QpLz -95pFdLbW/MW4XKpaDltyYkO6QrBekF6uWRlvyAHU+NqvXZ4F/3Z5l26qLuBcsLPJ -kyawkO+yNIDxORmQgMczAgMBAAGjUzBRMB0GA1UdDgQWBBThgotd9ws2ryEEaKp2 -+RMOWV8D7jAfBgNVHSMEGDAWgBThgotd9ws2ryEEaKp2+RMOWV8D7jAPBgNVHRMB -Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA9QoPv78hGmvmqF4GZeqrOBKQB -N/H5wL7f8H6BXU/wpNo2nnWOJn3u37lT+zivAdGEv+x+GeKekcugKBCSluhBLpVb -VNXe4WwMm5FBuO2NRBN2nblTMm1kEO00nVk1/yNo4hI8mj7d4YLU62d7324osNpF -wHqu6B0/c99JeKRvODGswyff1i8rJ1jpcgk/JmHg7UQBHEIkn0cRR0f9W3Mxv6b5 -ZeowRe81neWNkC6IMiMmzA0iHGkhoUMA15qG1ZKOr1XR364LH5BfNNpzAWYwkvJs -0JFrrdw+rm+cRJWs55yiyCCs7pyg1IJkY/o8bifdCOUgIyonzffwREk3+kZR ------END CERTIFICATE----- diff --git a/ca.key b/ca.key deleted file mode 100644 index 19edffa35d..0000000000 --- a/ca.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3pFWM+IJNsRCY -Ht1v/TliecppwVZV+ZHfFw9JKN9ev4K/fWHUiAOwp91MOLxbaYKdC6dxW28YVGlt -oGz3kUZJZcJRQVso1jXv24Op4muOsiYXukLc4TU2F6dG1XqkLt5tsvsYAQFf1uK3 -//QZFVRBosJEn+jjiJ4XCvt49mnPRolp1pNKX0z31mZO6bSly6c9OVlJMjWpDCYS -Ouf6qZZ36fa9eSut2bRJIPY0QCsgnqYBTnIEhksS+3jy6Qt+QpLz95pFdLbW/MW4 -XKpaDltyYkO6QrBekF6uWRlvyAHU+NqvXZ4F/3Z5l26qLuBcsLPJkyawkO+yNIDx -ORmQgMczAgMBAAECggEAHo70g3hI6pe3zLB6JawMFARzN8Tp0nWsneRu8Twha1lP -7wB0upKFlqxgSVI5mbaFew+Y5eaSpohJYOosp8efXBBYVQAcpL98izTKhIb+Yejo -KNOgU7QQEDfAaKuWdGKuNa/uU5C7Q1D1OiwX2OKxOhjU3emELfSqZeg4b2kFs21f -KWSbgRbgKHGRavdastf9qVFBsTk3wi6tAyoBM0zy1PNm66yW1Bl4KuMXVIq4tjZp -0TOPCUwQKeOPTWQDoBq3enuyLCnSTH+jT6jOEHKMy4fCRIELYOst2KMPA2JOe/jl -d7qlgU52TNgRCs0tFV0CWNj6ShzmDm2DbMwnJbXbPQKBgQD2Wzft4ezBnkdHS5PX -Dh3DuJC5vA5KZrfCPydFAfsd1wAsJ9V1Hyt/r/sm3SfYFg73YqH4lhBrOhfCY6Ql -9s1TGHz9ulNB4TZMzBxihFgF9vjcze/GXjeLsQ6n9iCLqfWG4WFtOBGa7cAaKyBz -mxWMrXb5X5fz4XVSHw4zRNKbnwKBgQC+1KS0dlLZHO5fKvErFqvYqnFRPcCEX4iI -otkhPqe7H0U6JRFcqGDB1dWsy2XOsbUuh3Lf1IZXtWcYReF4bdnk2qo8xXD0LAmv -G0SAMN9ThSP+NZ2HugcvjaMXPbFq9tUMi4/Hx/Smo7e8d64ltcjXOtSWsNNrr8yC -EMuhS70r7QKBgQC5RZrHTRxn9Gf4p08U8enSktBMzrAUpjFWZXZcAIRhSZs4mfB/ -d6SYD7oa3UGk0doJlGTpdbn9WiAaMiN15ak+7/C4RNNufTgAA5TpRkyIl9dK/5lu -nta5OLwj9wc84eHjwUYrBHrBAEJzq7FpH93SAXazToARiqJX00Ezr3OQUwKBgQCG -clCcaCTUnGKBIEMLpYxrOSJfJ4+kc55BDeLGXltUJaLjZUxHKMYKqrpBZIgUyPUq -k/lmI1iHIOJCorFI5LQ4XarE6CI9lW05No/bdRNSx6HlLycOgg0f/r0h2bBO+Rp/ -HTCug30ljoEbwoIqRVn78ZHnnStHWnNOS8D7od3kvQKBgQCiCmFBdVYB5NxOY2KE -XlEOCdo23d/fWAen7MJlHfEsivcL5xbO4IKDIfO0szG6cEuVqEdgTotfmGZ3qYbQ -i5rDIBfho2YbHue5UfiZOv+cfCKw64wGnx0ZOfSRLjpbJh+XjeOW54nLrJTFLiW+ -/wNl+w1WfsllQiDPbK13DrW7dg== ------END PRIVATE KEY----- diff --git a/ca2.crt b/ca2.crt deleted file mode 100644 index e3a7d77fbd..0000000000 --- a/ca2.crt +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDizCCAnOgAwIBAgIULpNcDIKDOM7YxmzXHSjXrlFZ6+kwDQYJKoZIhvcNAQEL -BQAwVTELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G -A1UECgwIenMsIEluYy4xGTAXBgNVBAMMEHpzX3Rlc3Rfcm9vdF9jYTIwHhcNMjQw -MzEzMTMxNTM5WhcNMjUwMzEzMTMxNTM5WjBVMQswCQYDVQQGEwJGUjELMAkGA1UE -CAwCSUYxCzAJBgNVBAcMAlBSMREwDwYDVQQKDAh6cywgSW5jLjEZMBcGA1UEAwwQ -enNfdGVzdF9yb290X2NhMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AKoQonePPKy4/uEzzF6t0+JYgT+Z1amlAf0Tc/Az2zA9gc0JdSCfYnZL0ie23dXk -wUvmQMPXh6nmQJO+mw1CG/DAGnj2g/u3PxWKdbxj77wyVJI0BIuEKakv6dmugyhP -I7/PKl/H2XGqQvoHFScegIdFhSkk1V9eg5CZZMqkpwI0bLb/yx73Ed5syWFbMtYK -LvGBNZmG1UT7vBo/gkOq7viLMrWpqkSPv+8/DbZCe0FYYWz0sUp8iWi6SmxMCLsT -S5Plm9f8VQErQnoVBUfWIJYvL2FCIx8klJykWQPssH372wupaXDX9EgBV0eedGIH -4PEpP3ovRGia6vM12Lvl4y0CAwEAAaNTMFEwHQYDVR0OBBYEFNs7TdMPDd3HIdTp -hMQ4vmaB0FWsMB8GA1UdIwQYMBaAFNs7TdMPDd3HIdTphMQ4vmaB0FWsMA8GA1Ud -EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJwtREvIwVZZNeaeseHWtaYe -vIYX0G2ONC7tAVO+RajjllisRlsKYvw2bXWBgMADdlDs9sqbKYSfz/A79SHhaEqF -QnPisSHVkTMnYWkeEaeXfxx/GEa1aXt9lEeDaDHCy2cW1cff9gJAXEE96INVAPv1 -8+w9x1AyjicbgkI/+Ldtf5g9we3wdJQXbbxop92R55+MGB73UN2Bru8pESFX+FpK -Z8Bxc9ruYBUfPl1CCmapDp6lHGtGCE6gnZoMjqTZJGWYz8tBdf2zITPkOKAueuX8 -5UVVtJTzpvPziktp0NZSmPzwotjH0glwL7aGIR/+5bS/cP5Je1FfKAIdH31AJmA= ------END CERTIFICATE----- diff --git a/client.json5 b/client.json5 deleted file mode 100644 index 69cd0f3169..0000000000 --- a/client.json5 +++ /dev/null @@ -1,433 +0,0 @@ -/// This file attempts to list and document available configuration elements. -/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. -/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. -{ - /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) - /// that zenoh runtime will use. - /// If not set, a random unsigned 128bit integer will be used. - /// WARNING: this id must be unique in your zenoh network. - // id: "1234567890abcdef", - /// The node's mode (router, peer or client) - mode: "client", - /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ - metadata: { - name: "strawberry", - location: "Penny Lane" - }, - /// Which endpoints to connect to. E.g. tcp/localhost:7447. - /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. - /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: - /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 - connect: { - endpoints: [ - // "/
" - "tls/127.0.0.1:7447" - ], - }, - /// Which endpoints to listen on. E.g. tcp/localhost:7447. - /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, - /// peers, or client can use to establish a zenoh session. - /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: - /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 - listen: { - endpoints: [ - // "/
" - ], - }, - /// Configure the scouting mechanisms and their behaviours - scouting: { - /// In client mode, the period dedicated to scouting for a router before failing - timeout: 3000, - /// In peer mode, the period dedicated to scouting remote peers before attempting other operations - delay: 200, - /// The multicast scouting configuration. - multicast: { - /// Whether multicast scouting is enabled or not - enabled: true, - /// The socket which should be used for multicast scouting - address: "224.0.0.224:7446", - /// The network interface which should be used for multicast scouting - interface: "auto", // If not set or set to "auto" the interface if picked automatically - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - /// Whether or not to listen for scout messages on UDP multicast and reply to them. - listen: true, - }, - /// The gossip scouting configuration. - gossip: { - /// Whether gossip scouting is enabled or not - enabled: true, - /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. - /// When false, gossip scouting informations are only propagated to the next hop. - /// Activating multihop gossip implies more scouting traffic and a lower scalability. - /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have - /// direct connectivity with each other. - multihop: false, - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - }, - }, - /// Configuration of data messages timestamps management. - timestamping: { - /// Whether data messages should be timestamped if not already. - /// Accepts a single boolean value or different values for router, peer and client. - enabled: { router: true, peer: false, client: false - }, - /// Whether data messages with timestamps in the future should be dropped or not. - /// If set to false (default), messages with timestamps in the future are retimestamped. - /// Timestamps are ignored if timestamping is disabled. - drop_future_timestamp: false, - }, - /// The default timeout to apply to queries in milliseconds. - queries_default_timeout: 10000, - /// The routing strategy to use and it's configuration. - routing: { - /// The routing strategy to use in routers and it's configuration. - router: { - /// When set to true a router will forward data between two peers - /// directly connected to it if it detects that those peers are not - /// connected to each other. - /// The failover brokering only works if gossip discovery is enabled. - peers_failover_brokering: true, - }, - /// The routing strategy to use in peers and it's configuration. - peer: { - /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). - mode: "peer_to_peer", - }, - }, - // /// The declarations aggregation strategy. - // aggregation: { - // /// A list of key-expressions for which all included subscribers will be aggregated into. - // subscribers: [ - // // key_expression - // ], - // /// A list of key-expressions for which all included publishers will be aggregated into. - // publishers: [ - // // key_expression - // ], - // }, - // /// The downsampling declaration. - // downsampling: [ - // { - // /// A list of network interfaces messages will be processed on, the rest will be passed as is. - // interfaces: [ "wlan0" ], - // /// Data flow messages will be processed on. ("egress" or "ingress") - // flow: "egress", - // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz - // rules: [ - // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, - // ], - // }, - // ], - /// Configure internal transport parameters - transport: { - unicast: { - /// Timeout in milliseconds when opening a link - accept_timeout: 10000, - /// Maximum number of zenoh session in pending state while accepting - accept_pending: 100, - /// Maximum number of sessions that can be simultaneously alive - max_sessions: 1000, - /// Maximum number of incoming links that are admitted per session - max_links: 1, - /// Enables the LowLatency transport - /// This option does not make LowLatency transport mandatory, the actual implementation of transport - /// used will depend on Establish procedure and other party's settings - /// - /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. - /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to - /// enable 'lowlatency' you need to explicitly disable 'qos'. - lowlatency: false, - /// Enables QoS on unicast communications. - qos: { - enabled: true, - }, - /// Enables compression on unicast communications. - /// Compression capabilities are negotiated during session establishment. - /// If both Zenoh nodes support compression, then compression is activated. - compression: { - enabled: false, - }, - }, - multicast: { - /// Enables QoS on multicast communication. - /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. - qos: { - enabled: false, - }, - /// Enables compression on multicast communication. - /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. - compression: { - enabled: false, - }, - }, - link: { - /// An optional whitelist of protocols to be used for accepting and opening sessions. - /// If not configured, all the supported protocols are automatically whitelisted. - /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] - /// For example, to only enable "tls" and "quic": - protocols: [ - "tls" - ], - /// Configure the zenoh TX parameters of a link - tx: { - /// The resolution in bits to be used for the message sequence numbers. - /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. - /// Accepted values: 8bit, 16bit, 32bit, 64bit. - sequence_number_resolution: "32bit", - /// Link lease duration in milliseconds to announce to other zenoh nodes - lease: 10000, - /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive - /// messages will be sent at the configured time interval. - /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, - /// set the actual keep_alive timeout to one fourth of the lease time. - /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity - /// check which considers a link as failed when no messages are received in 3.5 times the - /// target interval. - keep_alive: 4, - /// Batch size in bytes is expressed as a 16bit unsigned integer. - /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). - /// The default batch size value is the maximum batch size: 65535. - batch_size: 65535, - /// Each zenoh link has a transmission queue that can be configured - queue: { - /// The size of each priority queue indicates the number of batches a given queue can contain. - /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. - /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, - /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. - /// If qos is false, then only the DATA priority will be allocated. - size: { - control: 1, - real_time: 1, - interactive_high: 1, - interactive_low: 1, - data_high: 2, - data: 4, - data_low: 4, - background: 4, - }, - /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. - /// Higher values lead to a more aggressive batching but it will introduce additional latency. - backoff: 100, - }, - // Number of threads dedicated to transmission - // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) - // threads: 4, - }, - /// Configure the zenoh RX parameters of a link - rx: { - /// Receiving buffer size in bytes for each link - /// The default the rx_buffer_size value is the same as the default batch size: 65335. - /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate - /// more in-flight data. This is particularly relevant when dealing with large messages. - /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. - buffer_size: 65535, - /// Maximum size of the defragmentation buffer at receiver end. - /// Fragmented messages that are larger than the configured size will be dropped. - /// The default value is 1GiB. This would work in most scenarios. - /// NOTE: reduce the value if you are operating on a memory constrained device. - max_message_size: 1073741824, - }, - /// Configure TLS specific parameters - // tls: { - // server_private_key: "myserver.key", - // server_certificate: "myserver.crt" - // } - tls: { - /// Path to the certificate of the certificate authority used to validate either the server - /// or the client's keys and certificates, depending on the node's mode. If not specified - /// on router mode then the default WebPKI certificates are used instead. - root_ca_certificate: "ca.crt", - /// Path to the TLS server private key - server_private_key: null, - /// Path to the TLS server public certificate - server_certificate: null, - /// Client authentication, if true enables mTLS (mutual authentication) - client_auth: true, - /// Path to the TLS client private key - client_private_key: "newmyserver.key", - /// Path to the TLS client public certificate - client_certificate: "newmyserver.crt", - // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. - // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your - // ca to verify that the server at baz.com is actually baz.com, let this be true (default). - server_name_verification: null, - }, - }, - /// Shared memory configuration - shared_memory: { - enabled: false, - }, - /// Access control configuration - auth: { - /// The configuration of authentication. - /// A password implies a username is required. - usrpwd: { - user: null, - password: null, - /// The path to a file containing the user password dictionary - dictionary_file: null, - }, - pubkey: { - public_key_pem: null, - private_key_pem: null, - public_key_file: null, - private_key_file: null, - key_size: null, - known_keys_file: null, - }, - }, - }, - /// Configure the Admin Space - /// Unstable: this configuration part works as advertised, but may change in a future release - adminspace: { - // read and/or write permissions on the admin space - permissions: { - read: true, - write: false, - }, - }, - /// - /// Plugins configurations - /// - // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup - // plugins_search_dirs: [], - // /// Plugins are only loaded if present in the configuration. When starting - // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. - // plugins: { - // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) - // - // /// Plugin settings may contain field `__config__` - // /// - If `__config__` is specified, it's content is merged into plugin configuration - // /// - Properties loaded from `__config__` file overrides existing properties - // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively - // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config - // /// - // /// See below exapmle of plugin configuration using `__config__` property - // - // /// Configure the REST API plugin - // rest: { - // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. - // __required__: true, // defaults to false - // /// load configuration from the file - // __config__: "./plugins/zenoh-plugin-rest/config.json5", - // /// http port to answer to rest requests - // http_port: 8000, - // }, - // - // /// Configure the storage manager plugin - // storage_manager: { - // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. - // __path__: [ - // "./target/release/libzenoh_plugin_storage_manager.so", - // "./target/release/libzenoh_plugin_storage_manager.dylib", - // ], - // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup - // backend_search_dirs: [], - // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. - // volumes: { - // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb - // influxdb: { - // url: "https://myinfluxdb.example", - // /// Some plugins may need passwords in their configuration. - // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. - // /// any value held at the key "private" will not be shown in the adminspace. - // private: { - // username: "user1", - // password: "pw1", - // }, - // }, - // influxdb2: { - // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. - // backend: "influxdb", - // private: { - // username: "user2", - // password: "pw2", - // }, - // url: "https://localhost:8086", - // }, - // }, - // - // /// Configure the storages supported by the volumes - // storages: { - // demo: { - // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. - // key_expr: "demo/memory/**", - // /// Storages also need to know which volume will be used to actually store their key-value pairs. - // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. - // volume: "memory", - // }, - // demo2: { - // key_expr: "demo/memory2/**", - // volume: "memory", - // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. - // /// Metadata includes the set of wild card updates and deletions (tombstones). - // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. - // garbage_collection: { - // /// The garbage collection event will be periodic with this duration. - // /// The duration is specified in seconds. - // period: 30, - // /// Metadata older than this parameter will be garbage collected. - // /// The duration is specified in seconds. - // lifespan: 86400, - // }, - // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. - // /// In the absence of this configuration, a normal storage is initialized - // /// Note: all the samples to be stored in replicas should be timestamped - // replica_config: { - // /// Specifying the parameters is optional, by default the values provided will be used. - // /// Time interval between different synchronization attempts in seconds - // publication_interval: 5, - // /// Expected propagation delay of the network in milliseconds - // propagation_delay: 200, - // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. - // /// Higher the frequency of updates, lower the delta should be chosen - // /// To be efficient, delta should be the time containing no more than 100,000 samples - // delta: 1000, - // } - // }, - // demo3: { - // key_expr: "demo/memory3/**", - // volume: "memory", - // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. - // /// If not configured, complete defaults to false. - // complete: "true", - // }, - // influx_demo: { - // key_expr: "demo/influxdb/**", - // /// This prefix will be stripped of the received keys when storing. - // strip_prefix: "demo/influxdb", - // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: - // volume: { - // id: "influxdb", - // db: "example", - // }, - // }, - // influx_demo2: { - // key_expr: "demo/influxdb2/**", - // strip_prefix: "demo/influxdb2", - // volume: { - // id: "influxdb2", - // db: "example", - // }, - // }, - // }, - // }, - // }, - // /// Plugin configuration example using `__config__` property - // plugins: { - // rest: { - // __config__: "./plugins/zenoh-plugin-rest/config.json5", - // }, - // storage_manager: { - // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", - // } - // }, -} \ No newline at end of file diff --git a/client_ca.pem b/client_ca.pem deleted file mode 100644 index 53648fdb59..0000000000 --- a/client_ca.pem +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDSzCCAjOgAwIBAgIIB42n1ZIkOakwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMwN1oYDzIxMjMw -MzA2MTYwMzA3WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSAwNzhkYTcwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIuCq24O4P4Aep5vAVlrIQ7P8+ -uWWgcHIFYa02TmhBUB/hjo0JANCQvAtpVNuQ8NyKPlqnnq1cttePbSYVeA0rrnOs -DcfySAiyGBEY9zMjFfHJtH1wtrPcJEU8XIEY3xUlrAJE2CEuV9dVYgfEEydnvgLc -8Ug0WXSiARjqbnMW3l8jh6bYCp/UpL/gSM4mxdKrgpfyPoweGhlOWXc3RTS7cqM9 -T25acURGOSI6/g8GF0sNE4VZmUvHggSTmsbLeXMJzxDWO+xVehRmbQx3IkG7u++b -QdRwGIJcDNn7zHlDMHtQ0Z1DBV94fZNBwCULhCBB5g20XTGw//S7Fj2FPwyhAgMB -AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTWfAmQ/BUIQm/9 -/llJJs2jUMWzGzAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzANBgkq -hkiG9w0BAQsFAAOCAQEAvtcZFAELKiTuOiAeYts6zeKxc+nnHCzayDeD/BDCbxGJ -e1n+xdHjLtWGd+/Anc+fvftSYBPTFQqCi84lPiUIln5z/rUxE+ke81hNPIfw2obc -yIg87xCabQpVyEh8s+MV+7YPQ1+fH4FuSi2Fck1FejxkVqN2uOZPvOYUmSTsaVr1 -8SfRnwJNZ9UMRPM2bD4Jkvj0VcL42JM3QkOClOzYW4j/vll2cSs4kx7er27cIoo1 -Ck0v2xSPAiVjg6w65rUQeW6uB5m0T2wyj+wm0At8vzhZPlgS1fKhcmT2dzOq3+oN -R+IdLiXcyIkg0m9N8I17p0ljCSkbrgGMD3bbePRTfg== ------END CERTIFICATE----- diff --git a/client_cert.pem b/client_cert.pem deleted file mode 100644 index a2c10ba744..0000000000 --- a/client_cert.pem +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDLjCCAhagAwIBAgIIeUtmIdFQznMwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgMDc4ZGE3MCAXDTIzMDMwNjE2MDMxOFoYDzIxMjMw -MzA2MTYwMzE4WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQCx+oC6ESU3gefJ6oui9J3hB76c2/kDAKNI74cWIXfT -He9DUeKpEDRSbIWVKoGcUfdNQebglxp3jRB+tfx/XU0oZl2m8oewxipiNmdiREUZ -Lazh9DJoNtXkzTqzdQNfwRM+BjjVjx8IpNJV2L2IeTBxWtczFS7ggEHHQLWvYZKj -eCQgGdRwQt0V1pQ5Jt0KKkmFueTCLESvaHs9fHBtrtIhmBm1FpBZqTVUT1vvXqp7 -eIy4yFoR+j9SgWZ5kI+7myl/Bo5mycKzFE+TYiNvOWwdMnT2Uz3CZsQUcExUBd6M -tOT75Kte3yMBJmE16f/YbPItA0Cq4af3yUIxDpKwT28tAgMBAAGjdjB0MA4GA1Ud -DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T -AQH/BAIwADAfBgNVHSMEGDAWgBTWfAmQ/BUIQm/9/llJJs2jUMWzGzAUBgNVHREE -DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAG/POnBob0S7iYwsbtI2 -3LTTbRnmseIErtJuJmI9yYzgVIm6sUSKhlIUfAIm4rfRuzE94KFeWR2w9RabxOJD -wjYLLKvQ6rFY5g2AV/J0TwDjYuq0absdaDPZ8MKJ+/lpGYK3Te+CTOfq5FJRFt1q -GOkXAxnNpGg0obeRWRKFiAMHbcw6a8LIMfRjCooo3+uSQGsbVzGxSB4CYo720KcC -9vB1K9XALwzoqCewP4aiQsMY1GWpAmzXJftY3w+lka0e9dBYcdEdOqxSoZb5OBBZ -p5e60QweRuJsb60aUaCG8HoICevXYK2fFqCQdlb5sIqQqXyN2K6HuKAFywsjsGyJ -abY= ------END CERTIFICATE----- diff --git a/client_key.pem b/client_key.pem deleted file mode 100644 index 8e5f66ee3c..0000000000 --- a/client_key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAsfqAuhElN4HnyeqLovSd4Qe+nNv5AwCjSO+HFiF30x3vQ1Hi -qRA0UmyFlSqBnFH3TUHm4Jcad40QfrX8f11NKGZdpvKHsMYqYjZnYkRFGS2s4fQy -aDbV5M06s3UDX8ETPgY41Y8fCKTSVdi9iHkwcVrXMxUu4IBBx0C1r2GSo3gkIBnU -cELdFdaUOSbdCipJhbnkwixEr2h7PXxwba7SIZgZtRaQWak1VE9b716qe3iMuMha -Efo/UoFmeZCPu5spfwaOZsnCsxRPk2IjbzlsHTJ09lM9wmbEFHBMVAXejLTk++Sr -Xt8jASZhNen/2GzyLQNAquGn98lCMQ6SsE9vLQIDAQABAoIBAGQkKggHm6Q20L+4 -2+bNsoOqguLplpvM4RMpyx11qWE9h6GeUmWD+5yg+SysJQ9aw0ZSHWEjRD4ePji9 -lxvm2IIxzuIftp+NcM2gBN2ywhpfq9XbO/2NVR6PJ0dQQJzBG12bzKDFDdYkP0EU -WdiPL+WoEkvo0F57bAd77n6G7SZSgxYekBF+5S6rjbu5I1cEKW+r2vLehD4uFCVX -Q0Tu7TyIOE1KJ2anRb7ZXVUaguNj0/Er7EDT1+wN8KJKvQ1tYGIq/UUBtkP9nkOI -9XJd25k6m5AQPDddzd4W6/5+M7kjyVPi3CsQcpBPss6ueyecZOMaKqdWAHeEyaak -r67TofUCgYEA6GBa+YkRvp0Ept8cd5mh4gCRM8wUuhtzTQnhubCPivy/QqMWScdn -qD0OiARLAsqeoIfkAVgyqebVnxwTrKTvWe0JwpGylEVWQtpGz3oHgjST47yZxIiY -CSAaimi2CYnJZ+QB2oBkFVwNCuXdPEGX6LgnOGva19UKrm6ONsy6V9MCgYEAxBJu -fu4dGXZreARKEHa/7SQjI9ayAFuACFlON/EgSlICzQyG/pumv1FsMEiFrv6w7PRj -4AGqzyzGKXWVDRMrUNVeGPSKJSmlPGNqXfPaXRpVEeB7UQhAs5wyMrWDl8jEW7Ih -XcWhMLn1f/NOAKyrSDSEaEM+Nuu+xTifoAghvP8CgYEAlta9Fw+nihDIjT10cBo0 -38w4dOP7bFcXQCGy+WMnujOYPzw34opiue1wOlB3FIfL8i5jjY/fyzPA5PhHuSCT -Ec9xL3B9+AsOFHU108XFi/pvKTwqoE1+SyYgtEmGKKjdKOfzYA9JaCgJe1J8inmV -jwXCx7gTJVjwBwxSmjXIm+sCgYBQF8NhQD1M0G3YCdCDZy7BXRippCL0OGxVfL2R -5oKtOVEBl9NxH/3+evE5y/Yn5Mw7Dx3ZPHUcygpslyZ6v9Da5T3Z7dKcmaVwxJ+H -n3wcugv0EIHvOPLNK8npovINR6rGVj6BAqD0uZHKYYYEioQxK5rGyGkaoDQ+dgHm -qku12wKBgQDem5FvNp5iW7mufkPZMqf3sEGtu612QeqejIPFM1z7VkUgetsgPBXD -tYsqC2FtWzY51VOEKNpnfH7zH5n+bjoI9nAEAW63TK9ZKkr2hRGsDhJdGzmLfQ7v -F6/CuIw9EsAq6qIB8O88FXQqald+BZOx6AzB8Oedsz/WtMmIEmr/+Q== ------END RSA PRIVATE KEY----- diff --git a/client_quic.json5 b/client_quic.json5 deleted file mode 100644 index 3223a9c49f..0000000000 --- a/client_quic.json5 +++ /dev/null @@ -1,56 +0,0 @@ -{ - mode: "peer", - /// Configure the scouting mechanisms and their behaviours - scouting: { - /// In client mode, the period dedicated to scouting for a router before failing - timeout: 0, - /// In peer mode, the period dedicated to scouting remote peers before attempting other operations - delay: 0, - /// The multicast scouting configuration. - multicast: { - /// Whether multicast scouting is enabled or not - enabled: false, - /// The socket which should be used for multicast scouting - address: "224.0.0.224:7446", - /// The network interface which should be used for multicast scouting - interface: "auto", // If not set or set to "auto" the interface if picked automatically - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - /// Whether or not to listen for scout messages on UDP multicast and reply to them. - listen: false, - }, - /// The gossip scouting configuration. - gossip: { - /// Whether gossip scouting is enabled or not - enabled: false, - /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. - /// When false, gossip scouting informations are only propagated to the next hop. - /// Activating multihop gossip implies more scouting traffic and a lower scalability. - /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have - /// direct connectivity with each other. - multihop: false, - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - }, - }, - "transport": { - "link": { - "protocols": [ - "quic", - //"tls" - ], - "tls": { - "root_ca_certificate": "server_ca.pem", - "client_auth": false, - "client_private_key": "client_key.pem", - "client_certificate": "client_cert.pem" - } - } - } -} \ No newline at end of file diff --git a/myed25519.key b/myed25519.key deleted file mode 100644 index eec2318e30..0000000000 --- a/myed25519.key +++ /dev/null @@ -1,3 +0,0 @@ ------BEGIN PRIVATE KEY----- -MC4CAQAwBQYDK2VwBCIEIHqhe4/aAYsQ7CY1XCLIwCh+5nEZcCyIRZCbJcS233gc ------END PRIVATE KEY----- diff --git a/myedserver.crt b/myedserver.crt deleted file mode 100644 index 79f686e84a..0000000000 --- a/myedserver.crt +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBvTCCAW+gAwIBAgIUNfcUs1gokRmiNXzXRxeVsK8PAVEwBQYDK2VwMFQxCzAJ -BgNVBAYTAkZSMQswCQYDVQQIDAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpz -LCBJbmMuMRgwFgYDVQQDDA90ZXN0X3Rsc19zZXJ2ZXIwHhcNMjQwMzExMTUxNjA3 -WhcNMjUwMzExMTUxNjA3WjBUMQswCQYDVQQGEwJGUjELMAkGA1UECAwCSUYxCzAJ -BgNVBAcMAlBSMREwDwYDVQQKDAh6cywgSW5jLjEYMBYGA1UEAwwPdGVzdF90bHNf -c2VydmVyMCowBQYDK2VwAyEAtHIXi5k5PlaXGcUoqvN71aNZXipGzSiCrWfinY3r -zLejUzBRMB0GA1UdDgQWBBSCTrn8VCUbrLpvVaxc0e9tWWluRzAfBgNVHSMEGDAW -gBSCTrn8VCUbrLpvVaxc0e9tWWluRzAPBgNVHRMBAf8EBTADAQH/MAUGAytlcANB -AD9CgSNdcqVpoPGkwFqHnvDkTs9LxFOQWTMoUfnBMayOCOAKNl10LAyF6ST85QZc -USlMTo7EbXm/RmdqCBq3LQI= ------END CERTIFICATE----- diff --git a/mypub.crt b/mypub.crt deleted file mode 100644 index 1f94e5d243..0000000000 --- a/mypub.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDkjCCAnqgAwIBAgIUFMs3tKqT0Cvz3r0aSN9KSVPCsfwwDQYJKoZIhvcNAQEL -BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G -A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz -MTIxMjM5MzlaFw0yNTAzMTIxMjM5MzlaMFMxCzAJBgNVBAYTAkZSMQswCQYDVQQI -DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRcwFQYDVQQDDA5w -dWJfdGxzX2NsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALFj -0iNYAXqGniTo9R7qMHu6a0p9mQkuXn4Cppb6ovj3JozaSBxjgbrTVbxCZqJ6WCkk -0cRU+flcmQ2Sae6pHnRIB/PZ54s18jhhC80g9svgHf6+bSuqFqUZRRh+R0WZI5UV -YxbOJbMpG3ScyFgQ/iMlD9UpZqMGh+Rs/BCBfV8HB5+KcFNkPA45VOeyRcZf3PDp -eL9mP13uyNAEq4D5KSxV8lTvJqgTMpGpQmrJctGQ4+bQJ5mqAnVofMaShl7MqBSU -0U3CO9voe55sUQ/lYBYMK9oZKwfF6pfN4lShZSRWoYS8MsnK38U14wme2sNCeQEL -eRYm+UT7nzX/W6pw8DMCAwEAAaNdMFswGQYDVR0RBBIwEIIOcHViX3Rsc19jbGll -bnQwHQYDVR0OBBYEFMB042sagkaONASSTUQjMRTq3qi0MB8GA1UdIwQYMBaAFOGC -i133CzavIQRoqnb5Ew5ZXwPuMA0GCSqGSIb3DQEBCwUAA4IBAQCcuTc1POPJvYrT -NQYhPDj/Y+B2542+dVZzGQGqab95tngAGQC/n9bN+it35VaCadSSy2WHszp2GCmE -A3icXsL3UVvItDbdt/Uczb+VxjLrMtmUiZIlSXxQ1J1GTnjvJpdfRwc5YC6/RAav -Caqiazxuo4TS4cueUgbB4ry/8g/r/CPC4h0JLe3pNb4EGBo3MoJ4y5wcDIoD/0ns -9SLZSbrOtTKiPRonoEOws7a3IxprPfZZ3BP+lrm/ArkBMPOtfvcNKsfT8UBM4rsq -hvEkuCcig7A54z/xgY1u6fdwDLn6D+otzmKkw19o9JCYzfx1vWZFft5v+Y1mnXQF -fs26RWOK ------END CERTIFICATE----- diff --git a/mypub.key b/mypub.key deleted file mode 100644 index ffcba548d0..0000000000 --- a/mypub.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCxY9IjWAF6hp4k -6PUe6jB7umtKfZkJLl5+AqaW+qL49yaM2kgcY4G601W8QmaielgpJNHEVPn5XJkN -kmnuqR50SAfz2eeLNfI4YQvNIPbL4B3+vm0rqhalGUUYfkdFmSOVFWMWziWzKRt0 -nMhYEP4jJQ/VKWajBofkbPwQgX1fBwefinBTZDwOOVTnskXGX9zw6Xi/Zj9d7sjQ -BKuA+SksVfJU7yaoEzKRqUJqyXLRkOPm0CeZqgJ1aHzGkoZezKgUlNFNwjvb6Hue -bFEP5WAWDCvaGSsHxeqXzeJUoWUkVqGEvDLJyt/FNeMJntrDQnkBC3kWJvlE+581 -/1uqcPAzAgMBAAECggEACdVfw8fQJSurPp6PYAxZbbJy2ilGP4ULhe69r2bre+Ov -hmVfU/uMKIAoo4wGxoEDvBwnaLvRM6qXbXItXyaO4qFPl4v/0u7Fo6x1jASEyd59 -qy6BPMdsA/D3rJjreIc5urz5xjzdSCZCOF+sl30xqV8Xlph58RWemOIVwxB6k7bn -a9fK1cZuiCHNZda6RBTceihL+p+lS5qNs5MMMJeWEyQiMw5govdbVNDjw+g2yEtr -ooU7GlQg2Ss3cKAyQnux3BkQOUmqzBlZJu0MZ0Taqo0odlXH9Zc9JJq/eFCBaNwD -sQsZ1oMzdo0OQtzaS9g7bXDPIoeO2oyVJe++sS1c8QKBgQDV7jaQ+/SyQpid0h7O -ayyvwOCWf1sxBHWcWxFkSLFaiUsQEZXVmkK5GLOOGxrRYeev+iypDZNgP7W5qv67 -zRtLbiMhBRZGVTPYLzwRQlJBpWp+ZNdMRRa6iQPhsh8smcUl3XJZjscf2ulOHTtN -J01T7HSKScilPmNLTxLghT3CKwKBgQDURhCHyKeJVTkGB9OVCRlYzeSDnvx5uIqg -pRiAHFJUeC9cXamHE5fMrgEmMoLSudizin14PIRV4AIQIySI6wu+nIOQaKur1goG -RxRkbCx0qSgx083vJxVPfww8CFUkgOJ6qbLrpjB/LNoo1ecHrR0mXzIOe9kxR2Rq -jiUpRS/uGQKBgQCv0svIFzwCcleKhlJJZq5geI5dQqjJPZgH/JTrrg8NkP8/YqSZ -3OHvzMxuA/rjkarg6CVif8TbeyE5Sr93zFgdg5Sdo9et0IL+r7uXl8GRMIm4/dox -Visa/ldRXJrghjURLNK5pm4j0UCkscO2YpHcYt9ZdNDSdtcW4xNpsjiS5wKBgQCa -sAwvxus/ytjpKh7nhl/wNOoHeH4n/XEYK/c0tG7Sm1p4BtEZXA/M2iiAO2LWSRQ/ -kfZo/kC5i6o1NEbVd+NxHgFJ5NzlNe7MMFQN8j5bLUHbPaveUS7YZY722GOjXECu -fqehzdOdeYPpKidXkrGhWtHReDMIFCx68ebmskKBUQKBgEwizz/5ibXTrtiU+1vQ -P+mQC0WeY+awGnlPTkqDIz2RjaWZ53ZaOLwM9jJgMOdvL7NxwtLNpo0Zlkyonrmz -rEnXgh6VPzebZ7HXV1cpxh7/V/KKq6DlOgfz/uIO2b7jJgDZKgt74DVgheJEEnMG -N5XoKGfFvlqT27jqWsooqWma ------END PRIVATE KEY----- diff --git a/mypub2.crt b/mypub2.crt deleted file mode 100644 index 63a916d900..0000000000 --- a/mypub2.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDjTCCAnWgAwIBAgIUcK4p0GvmJBQ3LpiK7iY4EwTlhekwDQYJKoZIhvcNAQEL -BQAwVTELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G -A1UECgwIenMsIEluYy4xGTAXBgNVBAMMEHpzX3Rlc3Rfcm9vdF9jYTIwHhcNMjQw -MzEzMTMxOTI2WhcNMjUwMzEzMTMxOTI2WjBQMQswCQYDVQQGEwJGUjELMAkGA1UE -CAwCSUYxCzAJBgNVBAcMAlBSMREwDwYDVQQKDAh6cywgSW5jLjEUMBIGA1UEAwwL -cHViMl9zZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCp7qWN -2iA0+rhJMyyVrFXGcsqPNvz1ASTz2PHqhIOvS/tH2yaYaPkVGI3NHxvMp/USWUGj -we95ow2k7uPhuJ9q615tZ2u5+NFWjy72FU5MB0sFDbwB7Amb57KG5OyKk3gYyojL -TTyRevkMpokbpWfUoCgLx6LjMwzAlnbOoipsrh8Bg4VLadvhBFGfYtN6PrYOr5S1 -79L86aelaFZbxFqEmGmTQ8e8fPBn0DMasL8cIzavkkE+CAEXQV9SGIGddSc6MLVz -61mmh6umivfYEY4ZkkS4mK7zcKquhoYdLZK4yZWu+BtgCe+H4+jD3+Rv9TJ5YFU4 -MOCvgymUyOw4PExBAgMBAAGjWjBYMBYGA1UdEQQPMA2CC3B1YjJfc2VydmVyMB0G -A1UdDgQWBBTVL7smU8+53bqP3c7hvu21SNs5SzAfBgNVHSMEGDAWgBTbO03TDw3d -xyHU6YTEOL5mgdBVrDANBgkqhkiG9w0BAQsFAAOCAQEAKUbq0+KYUJthA51n/rV9 -dNhWqFRqKOuW5ubgK4NlgJxhRxE4HYjeqW41vMgbUYqcYrRlR/Mxg02AW0RE/TSl -31ptkDKVie2okJrAMGkz30M7N1Y4bTYEkdt0t4+cYr3ZqJF8uZfZCc3BWZlDTzWI -4N7zyxFvLE8qEsjkkAGMZYZyvudXsp9bSwtdLH6krOsFO1kbr1rjg/T7u9Dv8OvY -XPlWOOMXPM2pQV/eZP4/8LuuzLMrjROPx7oRNSbOzCNT3+pfiZh2A4pH8O1K5Jus -lcGN5lwsAQEkyQgVBC/XXmQ14Ke0yFXz/JRxM+wOD+UT8J5I4N6lRUrlaGJk/RtG -mA== ------END CERTIFICATE----- diff --git a/mypub2.key b/mypub2.key deleted file mode 100644 index 331427b8d0..0000000000 --- a/mypub2.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCp7qWN2iA0+rhJ -MyyVrFXGcsqPNvz1ASTz2PHqhIOvS/tH2yaYaPkVGI3NHxvMp/USWUGjwe95ow2k -7uPhuJ9q615tZ2u5+NFWjy72FU5MB0sFDbwB7Amb57KG5OyKk3gYyojLTTyRevkM -pokbpWfUoCgLx6LjMwzAlnbOoipsrh8Bg4VLadvhBFGfYtN6PrYOr5S179L86ael -aFZbxFqEmGmTQ8e8fPBn0DMasL8cIzavkkE+CAEXQV9SGIGddSc6MLVz61mmh6um -ivfYEY4ZkkS4mK7zcKquhoYdLZK4yZWu+BtgCe+H4+jD3+Rv9TJ5YFU4MOCvgymU -yOw4PExBAgMBAAECggEABY9+Eli3YhRsMFUA2fr0KZS7BRmvCFNbwrDwJZTlfDh3 -xf+pUSZqNCMEDNi+P6GlVs7d435mmCvaN/HrOgkhCk4eXmUadNDsBLGVv06uK7W3 -YjhzVPrEy7m2sUxPYy91KBaEiGaEG1yTRrMyXFm6vo3pEY2cSmPywGCMDbHnwnuY -c/7ggx5XtvbDYkv4HZdiu0ZtxZGk4YhNXv58mHM24rmQLWwA7Y1Rw+amHqcStMQJ -BT64YqOnCO5fI6dx889zo9XAvRe7Nv9Fu4FOa2SneqyfkR9819CuxclJ1rAkYnFk -St5vrf19J2rwyAaoT1gA+jQ3Lj2SiZN3mEgPnBp32QKBgQDbtxgYfzXKdxJebwXy -9jl8iEp+8TVOvj+7AWj6AnfFgiqyXlWE891MSa5srxtxtFjwJGoDUB/ySd2DsXmo -rhx7SF5P7moUmg53D+qta1CORebaJ9/kcWnAGSZkraVFhEx0XghIctdWoXE9jWf8 -k3vt5Vq791v5WPzlMbf8rktvVQKBgQDF/uAc/vSFSl9+q+8ArhmZbHioLq8fSsIr -RvYofOVIUXYGHZI9lY+qqDMU/icizsg2Rm2VVCWTLeqBMpsxmaV+2KWAsqHh0hm8 -0m2vReN0TDnr4P6/ul53sEmNxXwd3NWeY+PhcH186vkPuwqycNHOT/R7aio5RXQK -wj/NrSWxPQKBgFAyL2BZplelSJYhbgl1qBv1X0OgZTW9qWNnq1p95hu4XD9IwWxK -2r6KsljHPXwuOLxGfk+BQnfcUDdOYzqXepvhGVORkTS92oPI0n7ECd40U4PTRByM -7O2KAIKFAysxk/pxjBJtoH3lZYDzCT6e0oBN0+WB7xc/TOeXUzGuqKgVAoGAa8mr -fF2YBJBOmIlFXdtp+EpDDVwM3j42opTJIZWMxOgEFqQ2nuwzADb9SCpsZ9imylVh -BvB+XDec+KTyM/hvTjTnNL8KvgNBG7h7GfY0M3Xj+nPMe9gb4ZDJGjMutJsqeEXt -Iye4SS8qU9QBqM8eiPCiKiXLws36tHi3f2MJqAkCgYEAkFu7cG50zH+k/qs/UOzk -FQXSVboVooBkHlOBpC+mjD7uPm69Id/83UsF+5wTZSW0EuZ6IxC/M+uuRX2qINv9 -RDDqXaszxvpPaNhjdoir4mGgnXYOgg256F4dqSTiBSlNH5puRkAiG8J+Ng4aPnES -YJYfM97wJO8rXKaA8z+TOjQ= ------END PRIVATE KEY----- diff --git a/myserver.crt b/myserver.crt deleted file mode 100644 index a68071aa18..0000000000 --- a/myserver.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDmDCCAoCgAwIBAgIUFMs3tKqT0Cvz3r0aSN9KSVPCsfkwDQYJKoZIhvcNAQEL -BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G -A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz -MTExNDQ0MzZaFw0yNTAzMTExNDQ0MzZaMFQxCzAJBgNVBAYTAkZSMQswCQYDVQQI -DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRgwFgYDVQQDDA90 -ZXN0X3Rsc19zZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCh -86dsAI7FzJxhKykW5uzHuz9NGbmzq8G9ndUdIwTHYmawTTgr3NCBAYEF1+iOo6y9 -8yUUsTyN3bqx3biFVQHWVP6iHI7WPBazFOZOyyjc3gcRD6M5LVPBIc5Ar+zcKNzL -b8ZTW4G1T4fye5XXPS+Zu2IHjIBAPoXQVhKZjWfmpPmloF+hphF5l8L7ilDfsj3o -1qo88XzGVUjkR5fF5UE/6iuiiipXsLRtEvsYSYMvvLuKWGN+e0t3JwvfH0JnAURK -/KKOixhqnbGcnrwVY1bzgFo3u9NSQjjYREvu6QBEthuLtPkc+PCR+DxjBmdh1der -7Bwwnfa3AgKbbtoZhlkPAgMBAAGjYjBgMB4GA1UdEQQXMBWCE25ld190ZXN0X3Rs -c19zZXJ2ZXIwHQYDVR0OBBYEFG2WT0EOXqPY2QiWTxtb/detOQUDMB8GA1UdIwQY -MBaAFOGCi133CzavIQRoqnb5Ew5ZXwPuMA0GCSqGSIb3DQEBCwUAA4IBAQBKvVh0 -uzdlPkGrkU56hVOvNe2QqKXHbz0xRVeNn/rXItUnV3YbzuiNpyjkHGPBMsDtgri2 -YUf0dKfVr8+Zyr0Yc/Nhbe2gWezGMnoOo9dw6An0r4vSYmJdSaO/s5hH7/orHQxS -zCRN+6iwURT6r1quJDxJLcsA6nzOvLdQnMxTKcak/V6A7eBpoUINdFVNhvPoXMDd -PVaju1U00SEbun8Qgeh/yWz4CPQYgQqKUORkPf0ToK5V3jrbIuW9VfQi8VcOzCn9 -YPihAEzkhh+PG8FYwK3vc6u2qKNlcbEuMu6rOQTUDWAi6+PJY5ClHQYdnb4/ThjT -vcP3w3j3YhSd/9iA ------END CERTIFICATE----- diff --git a/myserver.key b/myserver.key deleted file mode 100644 index 3cad67bdc9..0000000000 --- a/myserver.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCh86dsAI7FzJxh -KykW5uzHuz9NGbmzq8G9ndUdIwTHYmawTTgr3NCBAYEF1+iOo6y98yUUsTyN3bqx -3biFVQHWVP6iHI7WPBazFOZOyyjc3gcRD6M5LVPBIc5Ar+zcKNzLb8ZTW4G1T4fy -e5XXPS+Zu2IHjIBAPoXQVhKZjWfmpPmloF+hphF5l8L7ilDfsj3o1qo88XzGVUjk -R5fF5UE/6iuiiipXsLRtEvsYSYMvvLuKWGN+e0t3JwvfH0JnAURK/KKOixhqnbGc -nrwVY1bzgFo3u9NSQjjYREvu6QBEthuLtPkc+PCR+DxjBmdh1der7Bwwnfa3AgKb -btoZhlkPAgMBAAECggEAP5vQA8L6UKUrPJzzoAumL1KTq8gxYGjTCRMvS6jf7SHw -fElwCQZLHIhHMVDahf+yTs7rnwN36a6Pb+HKYg//zzuF4Y0+6tUiA0dvp73yuEE6 -XFCchs4PSdlpxY1zhgtEoWCu8DmOKfTpS+uPcEEXa5WmDJn6G4GTFD9iQc5A410D -oBf0ONw7X8nE1ZBZr6dpJBdsP68pRJC8BfhTH/dS3d4I4JYb2BgLER1ZbMqfFeW/ -sAZ3FKKETdYvCgLb380/Xpb08FRAHlQ1MowEpfe2sNBqsnkHjESExMIP8Ne7O+ts -9IUIGHZkKIl9u/B/RHCve8Db3GM9F/lMjJ9p84FEXQKBgQDTzYX+9FyAZt5NGPwW -5mTqlh5EHLZzgnVGo2DySu0Zi7MN/YYKV1wAT3i6cTATMjjdSYu2u6L1VYhfIYYq -43MIcsHe7XMAQxbQ6l6oULUa77huMzC0Js0l08kV/ERkH0/nUS9JRp5FJUKR7mkH -Am2dz040MceQMITzCewwskf+jQKBgQDDvxgxBTNJYF3tN3uNLBPRcib0Kk+p2LfW -oDv43++MiyqkTejJJqMDHtYsXNivH6T7CE2U0Qf+2MonAzoVnNsEAfonS19okn8c -LqkMlTZmiT9Tld+h+pcAsf7lYYXSuZv10lgXSN2nj8LBm/EM130ShzyrM58vCGRC -/fDPu9ZNCwKBgQCnuWdVILlnzQ5ZS2HF2Kktw7cwBPTOwA6S46pP9NmRkzk16QAO -jGOEs2pNanjBmtHBGw6SpEBFu3gErY2LxRZBKG8yVCLvoDEfO5m9/DuOmysXyV3W -K6vlOrNQv7aA+vLRoU6q3ktTQlBXM87kCB46DAJH/uuj2WhO9hqd7XBpuQKBgFCG -/9vCyOuJ0noxVgmotWp3rKDL+0PjXRXVi3aCIZlO8zbuujJuS6eP+wn7FEVPHl8L -dmcfa0ujQd60zCNyCQPoEFI0BscNZW9hnrgHdn7OPZgUUxDe91oY38TbzuL26rtB -Um4Z0t4JHVTq40qmJ9UEf6fqr7T4nc6Vi4jaPHorAoGAL1hVy8oYAKtJCTlRQalw -apM3ZJUlTK7qfkjajPEvmhuHntplHDkGEe5ZROUu3zluDiS7MHzOYtunitoMaZbG -cRMO34aDO/UXoLdUWabuk81e3/AWgs6wHVFBOpRAYKAQzigrmXanMclwiL0V5T9K -IgP5i6aUi4zduiV1YLHj4UA= ------END PRIVATE KEY----- diff --git a/mysub.crt b/mysub.crt deleted file mode 100644 index 741949a7ba..0000000000 --- a/mysub.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDkjCCAnqgAwIBAgIUFMs3tKqT0Cvz3r0aSN9KSVPCsf4wDQYJKoZIhvcNAQEL -BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G -A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz -MTIxMjQzNDZaFw0yNTAzMTIxMjQzNDZaMFMxCzAJBgNVBAYTAkZSMQswCQYDVQQI -DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRcwFQYDVQQDDA5z -dWJfdGxzX2NsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJvD -EsuI9bllKHm7nTrTvF1IJzjsrzW80XyEuapK1bk2EW43zvKSMGq4uGT8aTd1Us0R -XCr+vxGT/qjSEwHp/vMY/ft58DpQ93hAtsfCMNKMNO6To66X/FXpc9nkFnpEmndW -KVan14EmcvUBbeezbYbffRBN1IQSj5K7wK45tuEty8GrPOntlumdoSJX4wRcbK87 -DCIrWbfQKOc6d2XWldJKKjkiZnQJlbnDQUdjiJQNvCv+jEMxsC4M/YNjpaT1xq7f -x1ochYdVZvWu3c1eYYsV9gvzKVmGUOsPWoXXK9fPQ+3ZpE0AfcUsYmufcvq6G0Dz -GIEZrw6SZcrqvjRaRZ8CAwEAAaNdMFswGQYDVR0RBBIwEIIOc3ViX3Rsc19jbGll -bnQwHQYDVR0OBBYEFMoXVCYQ/vmz5gHtw/9XCteQFn72MB8GA1UdIwQYMBaAFOGC -i133CzavIQRoqnb5Ew5ZXwPuMA0GCSqGSIb3DQEBCwUAA4IBAQASWyALPl3y5lnD -7QQrolp3ytKzsrhR7ly8RuCUQsaTqTQ4RnS+AyHCcY1MRiElHP0KxeO44fTPqZvW -4yg93a7ec75RPYCTuAbUPhpR4Njui7oEYkVl5dSYdm/+P1G2BAIH6neOlBuECjcH -lfwjX9aJEsE8sD5447WY+1VQIb+rsHAovg0S3UoYYXBmAjxMIKRq25ut2FoADO/J -dh6wz6zTIZOB53wJ1PPU3w16Mdy2mACr2kYw2l9J0PuKLgge/FFCHEzkJleZZqgc -H7qlZPbTRLcZRqFSqfZfneTF0RFCGR0i2vxxW3hNZCZn0nDw0Dtkx9Xbp7lo+ObE -L1qTQTjw ------END CERTIFICATE----- diff --git a/mysub.key b/mysub.key deleted file mode 100644 index 0d9f6a2dae..0000000000 --- a/mysub.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQCbwxLLiPW5ZSh5 -u50607xdSCc47K81vNF8hLmqStW5NhFuN87ykjBquLhk/Gk3dVLNEVwq/r8Rk/6o -0hMB6f7zGP37efA6UPd4QLbHwjDSjDTuk6Oul/xV6XPZ5BZ6RJp3VilWp9eBJnL1 -AW3ns22G330QTdSEEo+Su8CuObbhLcvBqzzp7ZbpnaEiV+MEXGyvOwwiK1m30Cjn -Ondl1pXSSio5ImZ0CZW5w0FHY4iUDbwr/oxDMbAuDP2DY6Wk9cau38daHIWHVWb1 -rt3NXmGLFfYL8ylZhlDrD1qF1yvXz0Pt2aRNAH3FLGJrn3L6uhtA8xiBGa8OkmXK -6r40WkWfAgMBAAECgf84yOh8J5xQcll2FLiyDdaN1xrjqRGiDb+IhUJOWwbgm+J6 -12kMPPtpuPfHskQUcixi1zilkTZxymiBZC6TfZRAywXTZ20mVxOtNNPPHKUKpUnQ -7egzDD9c8lDLlqyoGlqXDQ/knkirRLPhtPSz4bX1pjnONjbfQFmsRTstUtnd/71/ -QpVVX/oKNPXHT5UtwmKA/nC+YtCJ1iuiQWCYH41GlZkpMt0G0FLa4vXpOEFTgwnd -X5w638BPaUBm7fbV5pMIS10qu7qISUlU/wDihJBa5UT3NwbTfB6AkBkp5YSMbsbY -a7kMgALlhMRRqNkAfVvZ5JCdII2bChTL9XRVdFECgYEA0IzIjjDZRzAUTIdWzffw -OebeKG3CjoS8ek7AF5cmmb1PSjCPvXOdplWKSN1fM9rqrHsyJJnKPS9tniGBPU00 -5/PxANjmCxEwkKM7ejHoP9EaIIm7ncBKJcgTdn4f2b1kGVY5LESSQdU7Mz0wjBSl -3SkxffunEH1/DVPT9v7TSOkCgYEAvzOZlPamijQVxznFRftfrkI8yUW+Io6n+gEs -2Id0hehNTUVWJMo9PxUkH18AcAtWEsEz2yf0QshBTKi9ZZ6BCgC8PsOKneCpn0tS -WgnMpD7IQun9X5kmwblDBPeD8GRNa7IZIQ16kZ4tnqpdQf+cgaDXEOKmqPymEZAD -X9/ghUcCgYEAxTSbYXnnvF1GlKdV+iZ+TwJ1CR3hYAs8fxuAoc4YfkB5fdo10hxF -80foH8bVg597UeadH+cdSoZSzbk5ENK1OLGAMCDqR4TVu6/fSklvKQl9/06+zwlK -FDgBz4asb6Wbxim2npmpA/+yn105Tv0nat7NIiiZbgp93ghq46FMAiECgYAgtqZn -W1AhQ0oanSLIl3rGaOTXlwwyA3BwEPVoUry4EIfxWZSklMmn2mkkyO9dPENM0Cuc -KpjbOEIb6J8HHPh9CqUqo/A6lO7Qp2V+rECMNYW0FS7ZxW1hJd52oha78Z1heMZd -5l17PrIVfJaaLS7M6wUBCZZ0QU30oUxCgh57DwKBgHK8W/do25qyIz5dXQKCzayN -Tv4cU/9dA34wi2+QA3TMj92oqVrbXzrt6hPdYSm8u9No7B8CVX3lEEkHwreuwi3n -U45wP/GlAl8KpjbjEZDrl2gsXlwoxIu/V21S5fsHwD4OAqldLgtc+Kbj4U6bfC4S -VuQ4MTpTKj+nVbzjOIMF ------END PRIVATE KEY----- diff --git a/newmyserver.crt b/newmyserver.crt deleted file mode 100644 index 3459120a9e..0000000000 --- a/newmyserver.crt +++ /dev/null @@ -1,22 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDnDCCAoSgAwIBAgIUFMs3tKqT0Cvz3r0aSN9KSVPCsfswDQYJKoZIhvcNAQEL -BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G -A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz -MTExNjI0MzBaFw0yNTAzMTExNjI0MzBaMFgxCzAJBgNVBAYTAkZSMQswCQYDVQQI -DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRwwGgYDVQQDDBNu -ZXdfdGVzdF90bHNfc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAtSmanq4rho3EkYpTVro/gOcrZnG+n5VY+d9maWDb4Fc+DP8Fki4jWtl5Vc7A -wtRUy3SAXkrKJCKcC0opUMZvFSCr+43B3CKJcrEJb5Eu3k90HyiOVL/ZAFHIRO2f -2cOWYNu/WEHrBPz8Bj1qualKTuo5mjgLSuGWYb8On03qdXRdD9lpYpyWvL8vYHQ0 -m0ljR/kcVaUaI7XhTu6Ea8gIaxJVxs2P99mhjIfoJgVIoc5mP/+jWNJP4y1Bm4I5 -3p5iArBHWYOvMaumlkMYoZm97MsA5+8iXOImIPFxj+d14VmvqMq9J0iLandU4Uvw -FUXnLHi+QQyeFmlgO/2BAaRw9QIDAQABo2IwYDAeBgNVHREEFzAVghNuZXdfdGVz -dF90bHNfc2VydmVyMB0GA1UdDgQWBBQebkuD+avdhGdqrPLWgT+p8lcB6TAfBgNV -HSMEGDAWgBThgotd9ws2ryEEaKp2+RMOWV8D7jANBgkqhkiG9w0BAQsFAAOCAQEA -UCVixHvWTjhc7bB9fuTbIDUP9GwTf0t2qojbG7WY9m+iSTLCOO5HOHy4jvtm7hHa -hdF/6ohSLP/LRwoWzeEQQi7oAzSVck3w0SlRrdV97FEdIBAjRRK3IICsIagLtKKS -qBoHx7gbyNsaocn1yxkQPbqrh4GE3TpcoHFlAjpHKJI42YkDsNCshSSRO7WIhyQP -0ty3uPss20t6iH8TuZQnqRKKvz6/NCGKi8wu3C750vdmbd4Y7eyEjeNbG3+P5D8f -i99Kjsevk0e5YLEp1d1ydO5DssS/9TzwIeLOH6/q0tFK9lQln6MvSJ3EMQjOrLVb -80O7goMvO+wd5Q2D7JBjVQ== ------END CERTIFICATE----- diff --git a/newmyserver.key b/newmyserver.key deleted file mode 100644 index fb5f4aa6e2..0000000000 --- a/newmyserver.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC1KZqeriuGjcSR -ilNWuj+A5ytmcb6flVj532ZpYNvgVz4M/wWSLiNa2XlVzsDC1FTLdIBeSsokIpwL -SilQxm8VIKv7jcHcIolysQlvkS7eT3QfKI5Uv9kAUchE7Z/Zw5Zg279YQesE/PwG -PWq5qUpO6jmaOAtK4ZZhvw6fTep1dF0P2WlinJa8vy9gdDSbSWNH+RxVpRojteFO -7oRryAhrElXGzY/32aGMh+gmBUihzmY//6NY0k/jLUGbgjnenmICsEdZg68xq6aW -Qxihmb3sywDn7yJc4iYg8XGP53XhWa+oyr0nSItqd1ThS/AVRecseL5BDJ4WaWA7 -/YEBpHD1AgMBAAECggEAV/anBoRgSvmcJ+Tn2VUez4qvdpMlMVx1cwJnuiQXLyN9 -VBchz9xKO2scMK9uxksODyn2yJH8+7W4Wfz8+aUYO8R87Wxj5Gz6my9d+weeH8Cp -jBWHopvylGahXOKaesSuyEH68zIymN3zy13X6+VI2O9+36R1yzqk57o6sdxFyxhN -jgjroWV0WXaquN1X61WQsQDOVKPGyYnp7y7+R3nUwROipl/H6LcRQHiCWbuoZwuo -ykoMczn0YrguC0t1smj0yiF6mllsMNcWSknjPmCSUHyWKCcyDx0J/pu0Q4JYa0NZ -PMwL5Rv8BQhLFDUrHpHKlt3CcL3ZNdEr2bV4YTW/cwKBgQD3cM8lMeGteq+NwiIj -EWHR1uZxeIswveCKDot/mMZhYH3MiMXy9GNfEbgnwfQ8bbwojmEOHsdhy/L7+lY5 -LdkYmX5osy+iiFhZStMPc76DolWCAD/CxbLwO6YuDo+aM7eZI5zZdCAHZafUF3Y8 -ArFGWxnVGtWkwYh5dNzI8zr1SwKBgQC7bd/Bg9AZcYijBqqGDiJgPymb1hbY4hW4 -XERS7JSJuwZ8ZQH5wkdOWHpZO8gk191Ke0gaREKtFSz3uSQ9TTjdqkqxv6Y8TyHP -DjTn4A9UK7ZWFVlU7bnzms8Vgs99cZibaZAcn8ZtcdowlsvNMubOKVnIn7O9AG+6 -lZOr5ieKvwKBgQCqk8cJUiDMkeYR6IHWAPaZTPdhxALYYB05rxs1pCEmIfm3FZa4 -jQcwE6wLJGb1fYSXxMddj5RNc+aXFJV6J4QgtDfzf4tYFXwqWi2z2ku8vR0LWJab -8+QOPmCqIXmXiQ2JcYaAVdB6qPaQfHgSmJyS7tyZDz22rYAikpBdq2e6jwKBgCNc -1qO/R+sVBa+kmVXTot6/7AzP9t2SwoBXQDjZFClsVQvxTs8dvbBldygQ5HE3HTRp -UDBMgrv/S82ta835HOqNr6wbubSVRY64YnkBSEMcQDm7q3Afrj7tDXdEh/tmDGH+ -J8eOybRqj70tJmSf3vY0zRDSOOpHA82TXRpIwVsnAoGBAM/uA2XSyxMb4Ld91WMr -xPL5vWnLf8tbgrN1KoJvx+q1zJvEcZKeIFYrgQr/A4c7VW7jzEuQnO0bsAkxz/If -W+n4FY4MT7EswsMG9U/itW0FU8CBR0RhuJPzOtH8+tnDLjDIDuRPkQt0jDdWGlzO -RhmR9FoLOICtr03U7el+9mh+ ------END PRIVATE KEY----- diff --git a/peer_pub.json5 b/peer_pub.json5 deleted file mode 100644 index cf5e2a343e..0000000000 --- a/peer_pub.json5 +++ /dev/null @@ -1,12 +0,0 @@ -{ - "mode": "peer", - "transport": { - "link": { - "tls": { - "root_ca_certificate": "ca.crt", - "server_private_key": "mypub2.key", - "server_certificate": "mypub2.crt" - } - } - } -} \ No newline at end of file diff --git a/peer_sub.json5 b/peer_sub.json5 deleted file mode 100644 index 7143210394..0000000000 --- a/peer_sub.json5 +++ /dev/null @@ -1,12 +0,0 @@ -{ - "mode": "peer", - "transport": { - "link": { - "tls": { - "root_ca_certificate": "ca.crt", - "server_private_key": "mysub.key", - "server_certificate": "mysub.crt" - } - } - } -} \ No newline at end of file diff --git a/pub_client.json5 b/pub_client.json5 deleted file mode 100644 index b98cb7dcb4..0000000000 --- a/pub_client.json5 +++ /dev/null @@ -1,433 +0,0 @@ -/// This file attempts to list and document available configuration elements. -/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. -/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. -{ - /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) - /// that zenoh runtime will use. - /// If not set, a random unsigned 128bit integer will be used. - /// WARNING: this id must be unique in your zenoh network. - // id: "1234567890abcdef", - /// The node's mode (router, peer or client) - mode: "client", - /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ - metadata: { - name: "strawberry", - location: "Penny Lane" - }, - /// Which endpoints to connect to. E.g. tcp/localhost:7447. - /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. - /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: - /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 - connect: { - endpoints: [ - // "/
" - "tls/127.0.0.1:7447" - ], - }, - /// Which endpoints to listen on. E.g. tcp/localhost:7447. - /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, - /// peers, or client can use to establish a zenoh session. - /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: - /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 - listen: { - endpoints: [ - // "/
" - ], - }, - /// Configure the scouting mechanisms and their behaviours - scouting: { - /// In client mode, the period dedicated to scouting for a router before failing - timeout: 3000, - /// In peer mode, the period dedicated to scouting remote peers before attempting other operations - delay: 200, - /// The multicast scouting configuration. - multicast: { - /// Whether multicast scouting is enabled or not - enabled: true, - /// The socket which should be used for multicast scouting - address: "224.0.0.224:7446", - /// The network interface which should be used for multicast scouting - interface: "auto", // If not set or set to "auto" the interface if picked automatically - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - /// Whether or not to listen for scout messages on UDP multicast and reply to them. - listen: true, - }, - /// The gossip scouting configuration. - gossip: { - /// Whether gossip scouting is enabled or not - enabled: true, - /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. - /// When false, gossip scouting informations are only propagated to the next hop. - /// Activating multihop gossip implies more scouting traffic and a lower scalability. - /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have - /// direct connectivity with each other. - multihop: false, - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - }, - }, - /// Configuration of data messages timestamps management. - timestamping: { - /// Whether data messages should be timestamped if not already. - /// Accepts a single boolean value or different values for router, peer and client. - enabled: { router: true, peer: false, client: false - }, - /// Whether data messages with timestamps in the future should be dropped or not. - /// If set to false (default), messages with timestamps in the future are retimestamped. - /// Timestamps are ignored if timestamping is disabled. - drop_future_timestamp: false, - }, - /// The default timeout to apply to queries in milliseconds. - queries_default_timeout: 10000, - /// The routing strategy to use and it's configuration. - routing: { - /// The routing strategy to use in routers and it's configuration. - router: { - /// When set to true a router will forward data between two peers - /// directly connected to it if it detects that those peers are not - /// connected to each other. - /// The failover brokering only works if gossip discovery is enabled. - peers_failover_brokering: true, - }, - /// The routing strategy to use in peers and it's configuration. - peer: { - /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). - mode: "peer_to_peer", - }, - }, - // /// The declarations aggregation strategy. - // aggregation: { - // /// A list of key-expressions for which all included subscribers will be aggregated into. - // subscribers: [ - // // key_expression - // ], - // /// A list of key-expressions for which all included publishers will be aggregated into. - // publishers: [ - // // key_expression - // ], - // }, - // /// The downsampling declaration. - // downsampling: [ - // { - // /// A list of network interfaces messages will be processed on, the rest will be passed as is. - // interfaces: [ "wlan0" ], - // /// Data flow messages will be processed on. ("egress" or "ingress") - // flow: "egress", - // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz - // rules: [ - // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, - // ], - // }, - // ], - /// Configure internal transport parameters - transport: { - unicast: { - /// Timeout in milliseconds when opening a link - accept_timeout: 10000, - /// Maximum number of zenoh session in pending state while accepting - accept_pending: 100, - /// Maximum number of sessions that can be simultaneously alive - max_sessions: 1000, - /// Maximum number of incoming links that are admitted per session - max_links: 1, - /// Enables the LowLatency transport - /// This option does not make LowLatency transport mandatory, the actual implementation of transport - /// used will depend on Establish procedure and other party's settings - /// - /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. - /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to - /// enable 'lowlatency' you need to explicitly disable 'qos'. - lowlatency: false, - /// Enables QoS on unicast communications. - qos: { - enabled: true, - }, - /// Enables compression on unicast communications. - /// Compression capabilities are negotiated during session establishment. - /// If both Zenoh nodes support compression, then compression is activated. - compression: { - enabled: false, - }, - }, - multicast: { - /// Enables QoS on multicast communication. - /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. - qos: { - enabled: false, - }, - /// Enables compression on multicast communication. - /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. - compression: { - enabled: false, - }, - }, - link: { - /// An optional whitelist of protocols to be used for accepting and opening sessions. - /// If not configured, all the supported protocols are automatically whitelisted. - /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] - /// For example, to only enable "tls" and "quic": - protocols: [ - "tls", - "quic" - ], - /// Configure the zenoh TX parameters of a link - tx: { - /// The resolution in bits to be used for the message sequence numbers. - /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. - /// Accepted values: 8bit, 16bit, 32bit, 64bit. - sequence_number_resolution: "32bit", - /// Link lease duration in milliseconds to announce to other zenoh nodes - lease: 10000, - /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive - /// messages will be sent at the configured time interval. - /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, - /// set the actual keep_alive timeout to one fourth of the lease time. - /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity - /// check which considers a link as failed when no messages are received in 3.5 times the - /// target interval. - keep_alive: 4, - /// Batch size in bytes is expressed as a 16bit unsigned integer. - /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). - /// The default batch size value is the maximum batch size: 65535. - batch_size: 65535, - /// Each zenoh link has a transmission queue that can be configured - queue: { - /// The size of each priority queue indicates the number of batches a given queue can contain. - /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. - /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, - /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. - /// If qos is false, then only the DATA priority will be allocated. - size: { - control: 1, - real_time: 1, - interactive_high: 1, - interactive_low: 1, - data_high: 2, - data: 4, - data_low: 4, - background: 4, - }, - /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. - /// Higher values lead to a more aggressive batching but it will introduce additional latency. - backoff: 100, - }, - // Number of threads dedicated to transmission - // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) - // threads: 4, - }, - /// Configure the zenoh RX parameters of a link - rx: { - /// Receiving buffer size in bytes for each link - /// The default the rx_buffer_size value is the same as the default batch size: 65335. - /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate - /// more in-flight data. This is particularly relevant when dealing with large messages. - /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. - buffer_size: 65535, - /// Maximum size of the defragmentation buffer at receiver end. - /// Fragmented messages that are larger than the configured size will be dropped. - /// The default value is 1GiB. This would work in most scenarios. - /// NOTE: reduce the value if you are operating on a memory constrained device. - max_message_size: 1073741824, - }, - /// Configure TLS specific parameters - // tls: { - // root_ca_certificate: "ca.crt" - // } - tls: { - /// Path to the certificate of the certificate authority used to validate either the server - /// or the client's keys and certificates, depending on the node's mode. If not specified - /// on router mode then the default WebPKI certificates are used instead. - root_ca_certificate: "ca.crt", - /// Path to the TLS server private key - server_private_key: null, - /// Path to the TLS server public certificate - server_certificate: null, - /// Client authentication, if true enables mTLS (mutual authentication) - client_auth: true, - /// Path to the TLS client private key - client_private_key: "mypub.key", - /// Path to the TLS client public certificate - client_certificate: "mypub.crt", - // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. - // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your - // ca to verify that the server at baz.com is actually baz.com, let this be true (default). - server_name_verification: false, - }, - }, - /// Shared memory configuration - shared_memory: { - enabled: false, - }, - /// Access control configuration - auth: { - /// The configuration of authentification. - /// A password implies a username is required. - usrpwd: { - user: null, - password: null, - /// The path to a file containing the user password dictionary - dictionary_file: null, - }, - pubkey: { - public_key_pem: null, - private_key_pem: null, - public_key_file: null, - private_key_file: null, - key_size: null, - known_keys_file: null, - }, - }, - }, - /// Configure the Admin Space - /// Unstable: this configuration part works as advertised, but may change in a future release - adminspace: { - // read and/or write permissions on the admin space - permissions: { - read: true, - write: false, - }, - }, - /// - /// Plugins configurations - /// - // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup - // plugins_search_dirs: [], - // /// Plugins are only loaded if present in the configuration. When starting - // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. - // plugins: { - // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) - // - // /// Plugin settings may contain field `__config__` - // /// - If `__config__` is specified, it's content is merged into plugin configuration - // /// - Properties loaded from `__config__` file overrides existing properties - // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively - // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config - // /// - // /// See below exapmle of plugin configuration using `__config__` property - // - // /// Configure the REST API plugin - // rest: { - // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. - // __required__: true, // defaults to false - // /// load configuration from the file - // __config__: "./plugins/zenoh-plugin-rest/config.json5", - // /// http port to answer to rest requests - // http_port: 8000, - // }, - // - // /// Configure the storage manager plugin - // storage_manager: { - // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. - // __path__: [ - // "./target/release/libzenoh_plugin_storage_manager.so", - // "./target/release/libzenoh_plugin_storage_manager.dylib", - // ], - // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup - // backend_search_dirs: [], - // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. - // volumes: { - // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb - // influxdb: { - // url: "https://myinfluxdb.example", - // /// Some plugins may need passwords in their configuration. - // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. - // /// any value held at the key "private" will not be shown in the adminspace. - // private: { - // username: "user1", - // password: "pw1", - // }, - // }, - // influxdb2: { - // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. - // backend: "influxdb", - // private: { - // username: "user2", - // password: "pw2", - // }, - // url: "https://localhost:8086", - // }, - // }, - // - // /// Configure the storages supported by the volumes - // storages: { - // demo: { - // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. - // key_expr: "demo/memory/**", - // /// Storages also need to know which volume will be used to actually store their key-value pairs. - // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. - // volume: "memory", - // }, - // demo2: { - // key_expr: "demo/memory2/**", - // volume: "memory", - // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. - // /// Metadata includes the set of wild card updates and deletions (tombstones). - // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. - // garbage_collection: { - // /// The garbage collection event will be periodic with this duration. - // /// The duration is specified in seconds. - // period: 30, - // /// Metadata older than this parameter will be garbage collected. - // /// The duration is specified in seconds. - // lifespan: 86400, - // }, - // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. - // /// In the absence of this configuration, a normal storage is initialized - // /// Note: all the samples to be stored in replicas should be timestamped - // replica_config: { - // /// Specifying the parameters is optional, by default the values provided will be used. - // /// Time interval between different synchronization attempts in seconds - // publication_interval: 5, - // /// Expected propagation delay of the network in milliseconds - // propagation_delay: 200, - // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. - // /// Higher the frequency of updates, lower the delta should be chosen - // /// To be efficient, delta should be the time containing no more than 100,000 samples - // delta: 1000, - // } - // }, - // demo3: { - // key_expr: "demo/memory3/**", - // volume: "memory", - // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. - // /// If not configured, complete defaults to false. - // complete: "true", - // }, - // influx_demo: { - // key_expr: "demo/influxdb/**", - // /// This prefix will be stripped of the received keys when storing. - // strip_prefix: "demo/influxdb", - // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: - // volume: { - // id: "influxdb", - // db: "example", - // }, - // }, - // influx_demo2: { - // key_expr: "demo/influxdb2/**", - // strip_prefix: "demo/influxdb2", - // volume: { - // id: "influxdb2", - // db: "example", - // }, - // }, - // }, - // }, - // }, - // /// Plugin configuration example using `__config__` property - // plugins: { - // rest: { - // __config__: "./plugins/zenoh-plugin-rest/config.json5", - // }, - // storage_manager: { - // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", - // } - // }, -} \ No newline at end of file diff --git a/router.json5 b/router.json5 deleted file mode 100644 index 56ff9b5efa..0000000000 --- a/router.json5 +++ /dev/null @@ -1,433 +0,0 @@ -/// This file attempts to list and document available configuration elements. -/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. -/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. -{ - /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) - /// that zenoh runtime will use. - /// If not set, a random unsigned 128bit integer will be used. - /// WARNING: this id must be unique in your zenoh network. - // id: "1234567890abcdef", - /// The node's mode (router, peer or client) - mode: "router", - /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ - metadata: { - name: "strawberry", - location: "Penny Lane" - }, - /// Which endpoints to connect to. E.g. tcp/localhost:7447. - /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. - /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: - /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 - connect: { - endpoints: [ - // "/
" - ], - }, - /// Which endpoints to listen on. E.g. tcp/localhost:7447. - /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, - /// peers, or client can use to establish a zenoh session. - /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: - /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 - listen: { - endpoints: [ - // "/
" - "tls/127.0.0.1:7447" - ], - }, - /// Configure the scouting mechanisms and their behaviours - scouting: { - /// In client mode, the period dedicated to scouting for a router before failing - timeout: 3000, - /// In peer mode, the period dedicated to scouting remote peers before attempting other operations - delay: 200, - /// The multicast scouting configuration. - multicast: { - /// Whether multicast scouting is enabled or not - enabled: true, - /// The socket which should be used for multicast scouting - address: "224.0.0.224:7446", - /// The network interface which should be used for multicast scouting - interface: "auto", // If not set or set to "auto" the interface if picked automatically - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - /// Whether or not to listen for scout messages on UDP multicast and reply to them. - listen: true, - }, - /// The gossip scouting configuration. - gossip: { - /// Whether gossip scouting is enabled or not - enabled: true, - /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. - /// When false, gossip scouting informations are only propagated to the next hop. - /// Activating multihop gossip implies more scouting traffic and a lower scalability. - /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have - /// direct connectivity with each other. - multihop: false, - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - }, - }, - /// Configuration of data messages timestamps management. - timestamping: { - /// Whether data messages should be timestamped if not already. - /// Accepts a single boolean value or different values for router, peer and client. - enabled: { router: true, peer: false, client: false - }, - /// Whether data messages with timestamps in the future should be dropped or not. - /// If set to false (default), messages with timestamps in the future are retimestamped. - /// Timestamps are ignored if timestamping is disabled. - drop_future_timestamp: false, - }, - /// The default timeout to apply to queries in milliseconds. - queries_default_timeout: 10000, - /// The routing strategy to use and it's configuration. - routing: { - /// The routing strategy to use in routers and it's configuration. - router: { - /// When set to true a router will forward data between two peers - /// directly connected to it if it detects that those peers are not - /// connected to each other. - /// The failover brokering only works if gossip discovery is enabled. - peers_failover_brokering: true, - }, - /// The routing strategy to use in peers and it's configuration. - peer: { - /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). - mode: "peer_to_peer", - }, - }, - // /// The declarations aggregation strategy. - // aggregation: { - // /// A list of key-expressions for which all included subscribers will be aggregated into. - // subscribers: [ - // // key_expression - // ], - // /// A list of key-expressions for which all included publishers will be aggregated into. - // publishers: [ - // // key_expression - // ], - // }, - // /// The downsampling declaration. - // downsampling: [ - // { - // /// A list of network interfaces messages will be processed on, the rest will be passed as is. - // interfaces: [ "wlan0" ], - // /// Data flow messages will be processed on. ("egress" or "ingress") - // flow: "egress", - // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz - // rules: [ - // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, - // ], - // }, - // ], - /// Configure internal transport parameters - transport: { - unicast: { - /// Timeout in milliseconds when opening a link - accept_timeout: 10000, - /// Maximum number of zenoh session in pending state while accepting - accept_pending: 100, - /// Maximum number of sessions that can be simultaneously alive - max_sessions: 1000, - /// Maximum number of incoming links that are admitted per session - max_links: 1, - /// Enables the LowLatency transport - /// This option does not make LowLatency transport mandatory, the actual implementation of transport - /// used will depend on Establish procedure and other party's settings - /// - /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. - /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to - /// enable 'lowlatency' you need to explicitly disable 'qos'. - lowlatency: false, - /// Enables QoS on unicast communications. - qos: { - enabled: true, - }, - /// Enables compression on unicast communications. - /// Compression capabilities are negotiated during session establishment. - /// If both Zenoh nodes support compression, then compression is activated. - compression: { - enabled: false, - }, - }, - multicast: { - /// Enables QoS on multicast communication. - /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. - qos: { - enabled: false, - }, - /// Enables compression on multicast communication. - /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. - compression: { - enabled: false, - }, - }, - link: { - /// An optional whitelist of protocols to be used for accepting and opening sessions. - /// If not configured, all the supported protocols are automatically whitelisted. - /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] - /// For example, to only enable "tls" and "quic": - protocols: [ - "tls" - ], - /// Configure the zenoh TX parameters of a link - tx: { - /// The resolution in bits to be used for the message sequence numbers. - /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. - /// Accepted values: 8bit, 16bit, 32bit, 64bit. - sequence_number_resolution: "32bit", - /// Link lease duration in milliseconds to announce to other zenoh nodes - lease: 10000, - /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive - /// messages will be sent at the configured time interval. - /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, - /// set the actual keep_alive timeout to one fourth of the lease time. - /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity - /// check which considers a link as failed when no messages are received in 3.5 times the - /// target interval. - keep_alive: 4, - /// Batch size in bytes is expressed as a 16bit unsigned integer. - /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). - /// The default batch size value is the maximum batch size: 65535. - batch_size: 65535, - /// Each zenoh link has a transmission queue that can be configured - queue: { - /// The size of each priority queue indicates the number of batches a given queue can contain. - /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. - /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, - /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. - /// If qos is false, then only the DATA priority will be allocated. - size: { - control: 1, - real_time: 1, - interactive_high: 1, - interactive_low: 1, - data_high: 2, - data: 4, - data_low: 4, - background: 4, - }, - /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. - /// Higher values lead to a more aggressive batching but it will introduce additional latency. - backoff: 100, - }, - // Number of threads dedicated to transmission - // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) - // threads: 4, - }, - /// Configure the zenoh RX parameters of a link - rx: { - /// Receiving buffer size in bytes for each link - /// The default the rx_buffer_size value is the same as the default batch size: 65335. - /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate - /// more in-flight data. This is particularly relevant when dealing with large messages. - /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. - buffer_size: 65535, - /// Maximum size of the defragmentation buffer at receiver end. - /// Fragmented messages that are larger than the configured size will be dropped. - /// The default value is 1GiB. This would work in most scenarios. - /// NOTE: reduce the value if you are operating on a memory constrained device. - max_message_size: 1073741824, - }, - /// Configure TLS specific parameters - // tls: { - // server_private_key: "myserver.key", - // server_certificate: "myserver.crt" - // } - tls: { - /// Path to the certificate of the certificate authority used to validate either the server - /// or the client's keys and certificates, depending on the node's mode. If not specified - /// on router mode then the default WebPKI certificates are used instead. - root_ca_certificate: "ca.crt", - /// Path to the TLS server private key - server_private_key: "myserver.key", - /// Path to the TLS server public certificate - server_certificate: "myserver.crt", - /// Client authentication, if true enables mTLS (mutual authentication) - client_auth: true, - /// Path to the TLS client private key - client_private_key: null, - /// Path to the TLS client public certificate - client_certificate: null, - // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. - // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your - // ca to verify that the server at baz.com is actually baz.com, let this be true (default). - server_name_verification: null, - }, - }, - /// Shared memory configuration - shared_memory: { - enabled: false, - }, - /// Access control configuration - auth: { - /// The configuration of authentication. - /// A password implies a username is required. - usrpwd: { - user: null, - password: null, - /// The path to a file containing the user password dictionary - dictionary_file: null, - }, - pubkey: { - public_key_pem: null, - private_key_pem: null, - public_key_file: null, - private_key_file: null, - key_size: null, - known_keys_file: null, - }, - }, - }, - /// Configure the Admin Space - /// Unstable: this configuration part works as advertised, but may change in a future release - adminspace: { - // read and/or write permissions on the admin space - permissions: { - read: true, - write: false, - }, - }, - /// - /// Plugins configurations - /// - // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup - // plugins_search_dirs: [], - // /// Plugins are only loaded if present in the configuration. When starting - // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. - // plugins: { - // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) - // - // /// Plugin settings may contain field `__config__` - // /// - If `__config__` is specified, it's content is merged into plugin configuration - // /// - Properties loaded from `__config__` file overrides existing properties - // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively - // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config - // /// - // /// See below exapmle of plugin configuration using `__config__` property - // - // /// Configure the REST API plugin - // rest: { - // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. - // __required__: true, // defaults to false - // /// load configuration from the file - // __config__: "./plugins/zenoh-plugin-rest/config.json5", - // /// http port to answer to rest requests - // http_port: 8000, - // }, - // - // /// Configure the storage manager plugin - // storage_manager: { - // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. - // __path__: [ - // "./target/release/libzenoh_plugin_storage_manager.so", - // "./target/release/libzenoh_plugin_storage_manager.dylib", - // ], - // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup - // backend_search_dirs: [], - // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. - // volumes: { - // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb - // influxdb: { - // url: "https://myinfluxdb.example", - // /// Some plugins may need passwords in their configuration. - // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. - // /// any value held at the key "private" will not be shown in the adminspace. - // private: { - // username: "user1", - // password: "pw1", - // }, - // }, - // influxdb2: { - // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. - // backend: "influxdb", - // private: { - // username: "user2", - // password: "pw2", - // }, - // url: "https://localhost:8086", - // }, - // }, - // - // /// Configure the storages supported by the volumes - // storages: { - // demo: { - // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. - // key_expr: "demo/memory/**", - // /// Storages also need to know which volume will be used to actually store their key-value pairs. - // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. - // volume: "memory", - // }, - // demo2: { - // key_expr: "demo/memory2/**", - // volume: "memory", - // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. - // /// Metadata includes the set of wild card updates and deletions (tombstones). - // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. - // garbage_collection: { - // /// The garbage collection event will be periodic with this duration. - // /// The duration is specified in seconds. - // period: 30, - // /// Metadata older than this parameter will be garbage collected. - // /// The duration is specified in seconds. - // lifespan: 86400, - // }, - // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. - // /// In the absence of this configuration, a normal storage is initialized - // /// Note: all the samples to be stored in replicas should be timestamped - // replica_config: { - // /// Specifying the parameters is optional, by default the values provided will be used. - // /// Time interval between different synchronization attempts in seconds - // publication_interval: 5, - // /// Expected propagation delay of the network in milliseconds - // propagation_delay: 200, - // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. - // /// Higher the frequency of updates, lower the delta should be chosen - // /// To be efficient, delta should be the time containing no more than 100,000 samples - // delta: 1000, - // } - // }, - // demo3: { - // key_expr: "demo/memory3/**", - // volume: "memory", - // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. - // /// If not configured, complete defaults to false. - // complete: "true", - // }, - // influx_demo: { - // key_expr: "demo/influxdb/**", - // /// This prefix will be stripped of the received keys when storing. - // strip_prefix: "demo/influxdb", - // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: - // volume: { - // id: "influxdb", - // db: "example", - // }, - // }, - // influx_demo2: { - // key_expr: "demo/influxdb2/**", - // strip_prefix: "demo/influxdb2", - // volume: { - // id: "influxdb2", - // db: "example", - // }, - // }, - // }, - // }, - // }, - // /// Plugin configuration example using `__config__` property - // plugins: { - // rest: { - // __config__: "./plugins/zenoh-plugin-rest/config.json5", - // }, - // storage_manager: { - // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", - // } - // }, -} \ No newline at end of file diff --git a/router_quic.json5 b/router_quic.json5 deleted file mode 100644 index 512e40aa29..0000000000 --- a/router_quic.json5 +++ /dev/null @@ -1,56 +0,0 @@ -{ - mode: "peer", - /// Configure the scouting mechanisms and their behaviours -scouting: { - /// In client mode, the period dedicated to scouting for a router before failing - timeout: 0, - /// In peer mode, the period dedicated to scouting remote peers before attempting other operations - delay: 0, - /// The multicast scouting configuration. - multicast: { - /// Whether multicast scouting is enabled or not - enabled: false, - /// The socket which should be used for multicast scouting - address: "224.0.0.224:7446", - /// The network interface which should be used for multicast scouting - interface: "auto", // If not set or set to "auto" the interface if picked automatically - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - /// Whether or not to listen for scout messages on UDP multicast and reply to them. - listen: false, - }, - /// The gossip scouting configuration. - gossip: { - /// Whether gossip scouting is enabled or not - enabled: false, - /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. - /// When false, gossip scouting informations are only propagated to the next hop. - /// Activating multihop gossip implies more scouting traffic and a lower scalability. - /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have - /// direct connectivity with each other. - multihop: false, - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - }, - }, - "transport": { - "link": { - "protocols": [ - "quic", - // "tls" - ], - "tls": { - "root_ca_certificate": "client_ca.pem", - "client_auth": false, - "server_private_key": "server_key.pem", - "server_certificate": "server_cert.pem" - } - } - } -} \ No newline at end of file diff --git a/server_ca.pem b/server_ca.pem deleted file mode 100644 index 83e287e214..0000000000 --- a/server_ca.pem +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDSzCCAjOgAwIBAgIITcwv1N10nqEwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw -MzA2MTY0MTA2WjAgMR4wHAYDVQQDExVtaW5pY2Egcm9vdCBjYSA0ZGNjMmYwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2WUgN7NMlXIknew1cXiTWGmS0 -1T1EjcNNDAq7DqZ7/ZVXrjD47yxTt5EOiOXK/cINKNw4Zq/MKQvq9qu+Oax4lwiV -Ha0i8ShGLSuYI1HBlXu4MmvdG+3/SjwYoGsGaShr0y/QGzD3cD+DQZg/RaaIPHlO -MdmiUXxkMcy4qa0hFJ1imlJdq/6Tlx46X+0vRCh8nkekvOZR+t7Z5U4jn4XE54Kl -0PiwcyX8vfDZ3epa/FSHZvVQieM/g5Yh9OjIKCkdWRg7tD0IEGsaW11tEPJ5SiQr -mDqdRneMzZKqY0xC+QqXSvIlzpOjiu8PYQx7xugaUFE/npKRQdvh8ojHJMdNAgMB -AAGjgYYwgYMwDgYDVR0PAQH/BAQDAgKEMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr -BgEFBQcDAjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBTX46+p+Po1npE6 -QLQ7mMI+83s6qDAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDANBgkq -hkiG9w0BAQsFAAOCAQEAaN0IvEC677PL/JXzMrXcyBV88IvimlYN0zCt48GYlhmx -vL1YUDFLJEB7J+dyERGE5N6BKKDGblC4WiTFgDMLcHFsMGRc0v7zKPF1PSBwRYJi -ubAmkwdunGG5pDPUYtTEDPXMlgClZ0YyqSFJMOqA4IzQg6exVjXtUxPqzxNhyC7S -vlgUwPbX46uNi581a9+Ls2V3fg0ZnhkTSctYZHGZNeh0Nsf7Am8xdUDYG/bZcVef -jbQ9gpChosdjF0Bgblo7HSUct/2Va+YlYwW+WFjJX8k4oN6ZU5W5xhdfO8Czmgwk -US5kJ/+1M0uR8zUhZHL61FbsdPxEj+fYKrHv4woo+A== ------END CERTIFICATE----- diff --git a/server_cert.pem b/server_cert.pem deleted file mode 100644 index 0afe5c63b8..0000000000 --- a/server_cert.pem +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDLjCCAhagAwIBAgIIW1mAtJWJAJYwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE -AxMVbWluaWNhIHJvb3QgY2EgNGRjYzJmMCAXDTIzMDMwNjE2NDEwNloYDzIxMjMw -MzA2MTY0MTA2WjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQCYMLJKooc+YRlKEMfeV09pX9myH34eUcUuT0fXS8lm -PlZ/NW7mm5lDwa8EUg61WuXQv2ouQDptmIcdeb/w4RW93Xflkyng1Xbd91OwQBJd -+8ZVBjzL7hSRk3QPDqx/CVBU/I1GmXKzb6cWzq1fTkOn1WLNXf21I6p7+N3qHLPF -JQeoVq1HBBFcAjTgJnpyQNvRGLDuLTK+OsWEGib2U8qrgiRdkaBLkxGXSlGABlOo -cQyW/zOhf4pwb2Z/JAge2mRW5IcexCPBWint8ydPsoJDds8j5+AyYCD6HUhHX0Ob -Qkz73OW7f2PQhuTK2uzKy0Yz6lNFt2nuzaWC04wIW3T7AgMBAAGjdjB0MA4GA1Ud -DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T -AQH/BAIwADAfBgNVHSMEGDAWgBTX46+p+Po1npE6QLQ7mMI+83s6qDAUBgNVHREE -DTALgglsb2NhbGhvc3QwDQYJKoZIhvcNAQELBQADggEBAAxrmQPG54ybKgMVliN8 -Mg5povSdPIVVnlU/HOVG9yxzAOav/xQP003M4wqpatWxI8tR1PcLuZf0EPmcdJgb -tVl9nZMVZtveQnYMlU8PpkEVu56VM4Zr3rH9liPRlr0JEAXODdKw76kWKzmdqWZ/ -rzhup3Ek7iEX6T5j/cPUvTWtMD4VEK2I7fgoKSHIX8MIVzqM7cuboGWPtS3eRNXl -MgvahA4TwLEXPEe+V1WAq6nSb4g2qSXWIDpIsy/O1WGS/zzRnKvXu9/9NkXWqZMl -C1LSpiiQUaRSglOvYf/Zx6r+4BOS4OaaArwHkecZQqBSCcBLEAyb/FaaXdBowI0U -PQ4= ------END CERTIFICATE----- diff --git a/server_key.pem b/server_key.pem deleted file mode 100644 index 24fa62a138..0000000000 --- a/server_key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAmDCySqKHPmEZShDH3ldPaV/Zsh9+HlHFLk9H10vJZj5WfzVu -5puZQ8GvBFIOtVrl0L9qLkA6bZiHHXm/8OEVvd135ZMp4NV23fdTsEASXfvGVQY8 -y+4UkZN0Dw6sfwlQVPyNRplys2+nFs6tX05Dp9VizV39tSOqe/jd6hyzxSUHqFat -RwQRXAI04CZ6ckDb0Riw7i0yvjrFhBom9lPKq4IkXZGgS5MRl0pRgAZTqHEMlv8z -oX+KcG9mfyQIHtpkVuSHHsQjwVop7fMnT7KCQ3bPI+fgMmAg+h1IR19Dm0JM+9zl -u39j0IbkytrsystGM+pTRbdp7s2lgtOMCFt0+wIDAQABAoIBADNTSO2uvlmlOXgn -DKDJZTiuYKaXxFrJTOx/REUxg+x9XYJtLMeM9jVJnpKgceFrlFHAHDkY5BuN8xNX -ugmsfz6W8BZ2eQsgMoRNIuYv1YHopUyLW/mSg1FNHzjsw/Pb2kGvIp4Kpgopv3oL -naCkrmBtsHJ+Hk/2hUpl9cE8iMwVWcVevLzyHi98jNy1IDdIPhRtl0dhMiqC5MRr -4gLJ5gNkLYX7xf3tw5Hmfk/bVNProqZXDIQVI7rFvItX586nvQ3LNQkmW/D2ShZf -3FEqMu6EdA2Ycc4UZgAlQNGV0VBrWWVXizOQ+9gjLnBk3kJjqfigCU6NG94bTJ+H -0YIhsGECgYEAwdSSyuMSOXgzZQ7Vv+GsNn/7ivi/H8eb/lDzksqS/JroA2ciAmHG -2OF30eUJKRg+STqBTpOfXgS4QUa8QLSwBSnwcw6579x9bYGUhqD2Ypaw9uCnOukA -CwwggZ9cDmF0tb5rYjqkW3bFPqkCnTGb0ylMFaYRhRDU20iG5t8PQckCgYEAyQEM -KK18FLQUKivGrQgP5Ib6IC3myzlHGxDzfobXGpaQntFnHY7Cxp/6BBtmASzt9Jxu -etnrevmzrbKqsLTJSg3ivbiq0YTLAJ1FsZrCp71dx49YR/5o9QFiq0nQoKnwUVeb -/hrDjMAokNkjFL5vouXO711GSS6YyM4WzAKZAqMCgYEAhqGxaG06jmJ4SFx6ibIl -nSFeRhQrJNbP+mCeHrrIR98NArgS/laN+Lz7LfaJW1r0gIa7pCmTi4l5thV80vDu -RlfwJOr4qaucD4Du+mg5WxdSSdiXL6sBlarRtVdMaMy2dTqTegJDgShJLxHTt/3q -P0yzBWJ5TtT3FG0XDqum/EkCgYAYNHwWWe3bQGQ9P9BI/fOL/YUZYu2sA1XAuKXZ -0rsMhJ0dwvG76XkjGhitbe82rQZqsnvLZ3qn8HHmtOFBLkQfGtT3K8nGOUuI42eF -H7HZKUCly2lCIizZdDVBkz4AWvaJlRc/3lE2Hd3Es6E52kTvROVKhdz06xuS8t5j -6twqKQKBgQC01AeiWL6Rzo+yZNzVgbpeeDogaZz5dtmURDgCYH8yFX5eoCKLHfnI -2nDIoqpaHY0LuX+dinuH+jP4tlyndbc2muXnHd9r0atytxA69ay3sSA5WFtfi4ef -ESElGO6qXEA821RpQp+2+uhL90+iC294cPqlS5LDmvTMypVDHzrxPQ== ------END RSA PRIVATE KEY----- diff --git a/sub_client.json5 b/sub_client.json5 deleted file mode 100644 index 30a688c176..0000000000 --- a/sub_client.json5 +++ /dev/null @@ -1,430 +0,0 @@ -/// This file attempts to list and document available configuration elements. -/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. -/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. -{ - /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) - /// that zenoh runtime will use. - /// If not set, a random unsigned 128bit integer will be used. - /// WARNING: this id must be unique in your zenoh network. - // id: "1234567890abcdef", - /// The node's mode (router, peer or client) - mode: "client", - /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ - metadata: { - name: "strawberry", - location: "Penny Lane" - }, - /// Which endpoints to connect to. E.g. tcp/localhost:7447. - /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. - /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: - /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 - connect: { - endpoints: [ - // "/
" - "tls/127.0.0.1:7447" - ], - }, - /// Which endpoints to listen on. E.g. tcp/localhost:7447. - /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, - /// peers, or client can use to establish a zenoh session. - /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: - /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 - listen: { - endpoints: [ - // "/
" - ], - }, - /// Configure the scouting mechanisms and their behaviours - scouting: { - /// In client mode, the period dedicated to scouting for a router before failing - timeout: 3000, - /// In peer mode, the period dedicated to scouting remote peers before attempting other operations - delay: 200, - /// The multicast scouting configuration. - multicast: { - /// Whether multicast scouting is enabled or not - enabled: true, - /// The socket which should be used for multicast scouting - address: "224.0.0.224:7446", - /// The network interface which should be used for multicast scouting - interface: "auto", // If not set or set to "auto" the interface if picked automatically - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - /// Whether or not to listen for scout messages on UDP multicast and reply to them. - listen: true, - }, - /// The gossip scouting configuration. - gossip: { - /// Whether gossip scouting is enabled or not - enabled: true, - /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. - /// When false, gossip scouting informations are only propagated to the next hop. - /// Activating multihop gossip implies more scouting traffic and a lower scalability. - /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have - /// direct connectivity with each other. - multihop: false, - /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. - /// Accepts a single value or different values for router, peer and client. - /// Each value is bit-or-like combinations of "peer", "router" and "client". - autoconnect: { router: "", peer: "router|peer" - }, - }, - }, - /// Configuration of data messages timestamps management. - timestamping: { - /// Whether data messages should be timestamped if not already. - /// Accepts a single boolean value or different values for router, peer and client. - enabled: { router: true, peer: false, client: false - }, - /// Whether data messages with timestamps in the future should be dropped or not. - /// If set to false (default), messages with timestamps in the future are retimestamped. - /// Timestamps are ignored if timestamping is disabled. - drop_future_timestamp: false, - }, - /// The default timeout to apply to queries in milliseconds. - queries_default_timeout: 10000, - /// The routing strategy to use and it's configuration. - routing: { - /// The routing strategy to use in routers and it's configuration. - router: { - /// When set to true a router will forward data between two peers - /// directly connected to it if it detects that those peers are not - /// connected to each other. - /// The failover brokering only works if gossip discovery is enabled. - peers_failover_brokering: true, - }, - /// The routing strategy to use in peers and it's configuration. - peer: { - /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). - mode: "peer_to_peer", - }, - }, - // /// The declarations aggregation strategy. - // aggregation: { - // /// A list of key-expressions for which all included subscribers will be aggregated into. - // subscribers: [ - // // key_expression - // ], - // /// A list of key-expressions for which all included publishers will be aggregated into. - // publishers: [ - // // key_expression - // ], - // }, - // /// The downsampling declaration. - // downsampling: [ - // { - // /// A list of network interfaces messages will be processed on, the rest will be passed as is. - // interfaces: [ "wlan0" ], - // /// Data flow messages will be processed on. ("egress" or "ingress") - // flow: "egress", - // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz - // rules: [ - // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, - // ], - // }, - // ], - /// Configure internal transport parameters - transport: { - unicast: { - /// Timeout in milliseconds when opening a link - accept_timeout: 10000, - /// Maximum number of zenoh session in pending state while accepting - accept_pending: 100, - /// Maximum number of sessions that can be simultaneously alive - max_sessions: 1000, - /// Maximum number of incoming links that are admitted per session - max_links: 1, - /// Enables the LowLatency transport - /// This option does not make LowLatency transport mandatory, the actual implementation of transport - /// used will depend on Establish procedure and other party's settings - /// - /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. - /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to - /// enable 'lowlatency' you need to explicitly disable 'qos'. - lowlatency: false, - /// Enables QoS on unicast communications. - qos: { - enabled: true, - }, - /// Enables compression on unicast communications. - /// Compression capabilities are negotiated during session establishment. - /// If both Zenoh nodes support compression, then compression is activated. - compression: { - enabled: false, - }, - }, - multicast: { - /// Enables QoS on multicast communication. - /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. - qos: { - enabled: false, - }, - /// Enables compression on multicast communication. - /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. - compression: { - enabled: false, - }, - }, - link: { - /// An optional whitelist of protocols to be used for accepting and opening sessions. - /// If not configured, all the supported protocols are automatically whitelisted. - /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] - /// For example, to only enable "tls" and "quic": - // protocols: ["tls", "quic"], - /// Configure the zenoh TX parameters of a link - tx: { - /// The resolution in bits to be used for the message sequence numbers. - /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. - /// Accepted values: 8bit, 16bit, 32bit, 64bit. - sequence_number_resolution: "32bit", - /// Link lease duration in milliseconds to announce to other zenoh nodes - lease: 10000, - /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive - /// messages will be sent at the configured time interval. - /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, - /// set the actual keep_alive timeout to one fourth of the lease time. - /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity - /// check which considers a link as failed when no messages are received in 3.5 times the - /// target interval. - keep_alive: 4, - /// Batch size in bytes is expressed as a 16bit unsigned integer. - /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). - /// The default batch size value is the maximum batch size: 65535. - batch_size: 65535, - /// Each zenoh link has a transmission queue that can be configured - queue: { - /// The size of each priority queue indicates the number of batches a given queue can contain. - /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. - /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, - /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. - /// If qos is false, then only the DATA priority will be allocated. - size: { - control: 1, - real_time: 1, - interactive_high: 1, - interactive_low: 1, - data_high: 2, - data: 4, - data_low: 4, - background: 4, - }, - /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. - /// Higher values lead to a more aggressive batching but it will introduce additional latency. - backoff: 100, - }, - // Number of threads dedicated to transmission - // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) - // threads: 4, - }, - /// Configure the zenoh RX parameters of a link - rx: { - /// Receiving buffer size in bytes for each link - /// The default the rx_buffer_size value is the same as the default batch size: 65335. - /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate - /// more in-flight data. This is particularly relevant when dealing with large messages. - /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. - buffer_size: 65535, - /// Maximum size of the defragmentation buffer at receiver end. - /// Fragmented messages that are larger than the configured size will be dropped. - /// The default value is 1GiB. This would work in most scenarios. - /// NOTE: reduce the value if you are operating on a memory constrained device. - max_message_size: 1073741824, - }, - /// Configure TLS specific parameters - // tls: { - // root_ca_certificate: "ca.crt" - // } - tls: { - /// Path to the certificate of the certificate authority used to validate either the server - /// or the client's keys and certificates, depending on the node's mode. If not specified - /// on router mode then the default WebPKI certificates are used instead. - root_ca_certificate: "ca.crt", - /// Path to the TLS server private key - server_private_key: null, - /// Path to the TLS server public certificate - server_certificate: null, - /// Client authentication, if true enables mTLS (mutual authentication) - client_auth: false, - /// Path to the TLS client private key - client_private_key: null, - /// Path to the TLS client public certificate - client_certificate: null, - // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. - // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your - // ca to verify that the server at baz.com is actually baz.com, let this be true (default). - server_name_verification: null, - }, - }, - /// Shared memory configuration - shared_memory: { - enabled: false, - }, - /// Access control configuration - auth: { - /// The configuration of authentification. - /// A password implies a username is required. - usrpwd: { - user: null, - password: null, - /// The path to a file containing the user password dictionary - dictionary_file: null, - }, - pubkey: { - public_key_pem: null, - private_key_pem: null, - public_key_file: null, - private_key_file: null, - key_size: null, - known_keys_file: null, - }, - }, - }, - /// Configure the Admin Space - /// Unstable: this configuration part works as advertised, but may change in a future release - adminspace: { - // read and/or write permissions on the admin space - permissions: { - read: true, - write: false, - }, - }, - /// - /// Plugins configurations - /// - // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup - // plugins_search_dirs: [], - // /// Plugins are only loaded if present in the configuration. When starting - // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. - // plugins: { - // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) - // - // /// Plugin settings may contain field `__config__` - // /// - If `__config__` is specified, it's content is merged into plugin configuration - // /// - Properties loaded from `__config__` file overrides existing properties - // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively - // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config - // /// - // /// See below exapmle of plugin configuration using `__config__` property - // - // /// Configure the REST API plugin - // rest: { - // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. - // __required__: true, // defaults to false - // /// load configuration from the file - // __config__: "./plugins/zenoh-plugin-rest/config.json5", - // /// http port to answer to rest requests - // http_port: 8000, - // }, - // - // /// Configure the storage manager plugin - // storage_manager: { - // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. - // __path__: [ - // "./target/release/libzenoh_plugin_storage_manager.so", - // "./target/release/libzenoh_plugin_storage_manager.dylib", - // ], - // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup - // backend_search_dirs: [], - // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. - // volumes: { - // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb - // influxdb: { - // url: "https://myinfluxdb.example", - // /// Some plugins may need passwords in their configuration. - // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. - // /// any value held at the key "private" will not be shown in the adminspace. - // private: { - // username: "user1", - // password: "pw1", - // }, - // }, - // influxdb2: { - // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. - // backend: "influxdb", - // private: { - // username: "user2", - // password: "pw2", - // }, - // url: "https://localhost:8086", - // }, - // }, - // - // /// Configure the storages supported by the volumes - // storages: { - // demo: { - // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. - // key_expr: "demo/memory/**", - // /// Storages also need to know which volume will be used to actually store their key-value pairs. - // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. - // volume: "memory", - // }, - // demo2: { - // key_expr: "demo/memory2/**", - // volume: "memory", - // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. - // /// Metadata includes the set of wild card updates and deletions (tombstones). - // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. - // garbage_collection: { - // /// The garbage collection event will be periodic with this duration. - // /// The duration is specified in seconds. - // period: 30, - // /// Metadata older than this parameter will be garbage collected. - // /// The duration is specified in seconds. - // lifespan: 86400, - // }, - // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. - // /// In the absence of this configuration, a normal storage is initialized - // /// Note: all the samples to be stored in replicas should be timestamped - // replica_config: { - // /// Specifying the parameters is optional, by default the values provided will be used. - // /// Time interval between different synchronization attempts in seconds - // publication_interval: 5, - // /// Expected propagation delay of the network in milliseconds - // propagation_delay: 200, - // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. - // /// Higher the frequency of updates, lower the delta should be chosen - // /// To be efficient, delta should be the time containing no more than 100,000 samples - // delta: 1000, - // } - // }, - // demo3: { - // key_expr: "demo/memory3/**", - // volume: "memory", - // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. - // /// If not configured, complete defaults to false. - // complete: "true", - // }, - // influx_demo: { - // key_expr: "demo/influxdb/**", - // /// This prefix will be stripped of the received keys when storing. - // strip_prefix: "demo/influxdb", - // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: - // volume: { - // id: "influxdb", - // db: "example", - // }, - // }, - // influx_demo2: { - // key_expr: "demo/influxdb2/**", - // strip_prefix: "demo/influxdb2", - // volume: { - // id: "influxdb2", - // db: "example", - // }, - // }, - // }, - // }, - // }, - // /// Plugin configuration example using `__config__` property - // plugins: { - // rest: { - // __config__: "./plugins/zenoh-plugin-rest/config.json5", - // }, - // storage_manager: { - // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", - // } - // }, -} \ No newline at end of file From 613086c247fadc75bfbb93b113ab6d0848760e58 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Tue, 19 Mar 2024 11:03:34 +0100 Subject: [PATCH 06/37] add extensibility --- io/zenoh-link-commons/src/unicast.rs | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs index 150169c5d3..28b7c66f5c 100644 --- a/io/zenoh-link-commons/src/unicast.rs +++ b/io/zenoh-link-commons/src/unicast.rs @@ -20,6 +20,7 @@ use core::{ ops::Deref, }; use serde::Serialize; +use std::any::{Any, TypeId}; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::ZResult; @@ -123,3 +124,57 @@ pub struct AuthIdentifier { pub username: Option, pub tls_cert_name: Option, } + +pub enum AuthIdType { + None, + Tls, + Username, +} + +pub struct AuthId<'a> { + pub auth_type: &'a Option, + pub auth_value: &'a Option>, //downcast in interceptor by auth_id_type +} + +impl AuthId<'_> { + pub fn builder() -> AuthIdBuilder { + AuthIdBuilder::default() + } + pub fn get_type() {} //gets the authId type + + pub fn get_value() {} //get the authId value to be used in ACL +} +#[derive(Default)] +pub struct AuthIdBuilder { + pub auth_type: Option, + pub auth_value: Option>, //downcast in interceptor by auth_id_type + /* + possible values for auth_value: Vec and String (as of now) + */ +} + +impl AuthIdBuilder { + fn new(&self) -> Self { + AuthIdBuilder::default() + } + + pub fn id_type(&mut self, auth_id_type: impl Into) -> &mut Self { + //adds type + self.auth_type.insert(auth_id_type.into()); + self + } + pub fn value(&mut self, auth_id_value: impl Into>) -> &mut Self { + //adds type + //needs to be downcast + self + } + + pub fn build(&mut self) -> ZResult { + let auth_type = &self.auth_type; + let auth_value = &self.auth_value; + Ok(AuthId { + auth_type, + auth_value, + }) + } +} From e83ca8196b282933f4576ca1c0982a5c4a782685 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Tue, 19 Mar 2024 11:24:25 +0100 Subject: [PATCH 07/37] add extensibility --- io/zenoh-link-commons/src/unicast.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs index 28b7c66f5c..d94a761e01 100644 --- a/io/zenoh-link-commons/src/unicast.rs +++ b/io/zenoh-link-commons/src/unicast.rs @@ -154,18 +154,18 @@ pub struct AuthIdBuilder { } impl AuthIdBuilder { - fn new(&self) -> Self { + pub fn new(&self) -> Self { AuthIdBuilder::default() } pub fn id_type(&mut self, auth_id_type: impl Into) -> &mut Self { //adds type - self.auth_type.insert(auth_id_type.into()); + let _ = self.auth_type.insert(auth_id_type.into()); self } pub fn value(&mut self, auth_id_value: impl Into>) -> &mut Self { + let _ = auth_id_value; //adds type - //needs to be downcast self } @@ -178,3 +178,17 @@ impl AuthIdBuilder { }) } } + +// pub trait AuthIdTrait { +// fn builder() -> Builder { +// Builder::default() +// } +// fn get_type() {} //gets the authId type + +// fn get_value() {} //get the authId value to be used in ACL +// } + +// +// pub trait AuthIdValue { +// //define features to restrict auth_value behaviour +// } From fa20fad66a52122429f4cb2aabf923193fe7d048 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Tue, 19 Mar 2024 18:05:34 +0100 Subject: [PATCH 08/37] add extensibility --- credentials.txt | 2 - io/zenoh-link-commons/src/unicast.rs | 57 ++++++---- io/zenoh-links/zenoh-link-quic/src/unicast.rs | 103 +++++++++++------- io/zenoh-links/zenoh-link-tls/src/unicast.rs | 63 +++++++---- 4 files changed, 141 insertions(+), 84 deletions(-) delete mode 100644 credentials.txt diff --git a/credentials.txt b/credentials.txt deleted file mode 100644 index 3045a4164c..0000000000 --- a/credentials.txt +++ /dev/null @@ -1,2 +0,0 @@ -clientusername:92df0d4f39c218607e3200bf93ccac87a80cb910e811d84b286bebe0a8860724 - \ No newline at end of file diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs index d94a761e01..673525049e 100644 --- a/io/zenoh-link-commons/src/unicast.rs +++ b/io/zenoh-link-commons/src/unicast.rs @@ -20,7 +20,7 @@ use core::{ ops::Deref, }; use serde::Serialize; -use std::any::{Any, TypeId}; +use std::any::Any; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::ZResult; @@ -125,26 +125,36 @@ pub struct AuthIdentifier { pub tls_cert_name: Option, } +//#[derive(Debug, Default, PartialEq)] +#[derive(Clone, Debug, Serialize, Eq, Hash, PartialEq)] pub enum AuthIdType { None, - Tls, + TlsCommonName, Username, } -pub struct AuthId<'a> { - pub auth_type: &'a Option, - pub auth_value: &'a Option>, //downcast in interceptor by auth_id_type +#[derive(Default, Debug, PartialEq, Eq, Hash)] +pub struct Username(String); +// /* need to put restrictions on auth_id values as well */ +// pub enum AuthIdValue { +// Tls(String), +// Username(String), +// } + +pub struct AuthId { + pub auth_type: AuthIdType, + pub auth_value: Option>, //downcast in interceptor by auth_id_type } -impl AuthId<'_> { +impl AuthId { pub fn builder() -> AuthIdBuilder { - AuthIdBuilder::default() + AuthIdBuilder::new() } pub fn get_type() {} //gets the authId type pub fn get_value() {} //get the authId value to be used in ACL } -#[derive(Default)] +#[derive(Debug)] pub struct AuthIdBuilder { pub auth_type: Option, pub auth_value: Option>, //downcast in interceptor by auth_id_type @@ -152,30 +162,37 @@ pub struct AuthIdBuilder { possible values for auth_value: Vec and String (as of now) */ } +impl Default for AuthIdBuilder { + fn default() -> Self { + Self::new() + } +} impl AuthIdBuilder { - pub fn new(&self) -> Self { - AuthIdBuilder::default() + pub fn new() -> AuthIdBuilder { + AuthIdBuilder { + auth_type: Some(AuthIdType::None), + auth_value: None, + } } - pub fn id_type(&mut self, auth_id_type: impl Into) -> &mut Self { - //adds type - let _ = self.auth_type.insert(auth_id_type.into()); + pub fn auth_type(&mut self, auth_type: AuthIdType) -> &mut Self { + self.auth_type(auth_type); self } - pub fn value(&mut self, auth_id_value: impl Into>) -> &mut Self { - let _ = auth_id_value; - //adds type + pub fn auth_value(&mut self, auth_value: Option>) -> &mut Self { + // let _ = self.auth_value.insert(auth_value.into()); + self.auth_value(auth_value); self } - pub fn build(&mut self) -> ZResult { - let auth_type = &self.auth_type; + pub fn build(&self) -> AuthId { + let auth_type = self.auth_type.clone().unwrap(); let auth_value = &self.auth_value; - Ok(AuthId { + AuthId { auth_type, auth_value, - }) + } } } diff --git a/io/zenoh-links/zenoh-link-quic/src/unicast.rs b/io/zenoh-links/zenoh-link-quic/src/unicast.rs index 13903eb1b2..3b14f46d68 100644 --- a/io/zenoh-links/zenoh-link-quic/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-quic/src/unicast.rs @@ -490,10 +490,13 @@ async fn accept_task( } async fn accept(acceptor: quinn::Accept<'_>) -> ZResult { - let qc = acceptor + let mut qc = acceptor .await .ok_or_else(|| zerror!("Can not accept QUIC connections: acceptor closed"))?; - + { + let nqc = qc.handshake_data(); + println!("handshake in accept function is {:?}", nqc.await); + } let conn = qc.await.map_err(|e| { let e = zerror!("QUIC acceptor failed: {:?}", e); log::warn!("{}", e); @@ -546,46 +549,66 @@ async fn accept_task( let mut test_auth_id: Option = None; { let new_conn = quic_conn.clone(); + let server_name = new_conn + .handshake_data() + .unwrap() + .downcast_ref::() + .unwrap() + .server_name + .as_ref() + .unwrap() + .clone(); + let protocol_deets = new_conn + .handshake_data() + .unwrap() + .downcast_ref::() + .unwrap() + .protocol + .as_ref() + .unwrap() + .clone(); + let auth_identifier = AuthIdentifier { + username: None, + tls_cert_name: Some(server_name.to_string()), + }; + println!( - "handshake information: {:?}", - new_conn - .handshake_data() - .unwrap() - .downcast_ref::() - .unwrap() - .server_name + "From conncetion, server_name {:?} and protocol_deets {:?}", + server_name, protocol_deets ); - //println!("connection info: {:?}", new_conn); - if let Some(cert_info) = new_conn.peer_identity() { - //use cert info - - match cert_info.downcast_ref::>() { - Some(serv_certs) => { - println!("the client certs were found"); - for item in serv_certs { - let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); - let subject_name = &cert - .subject - .iter_common_name() - .next() - .and_then(|cn| cn.as_str().ok()) - .unwrap(); - let auth_identifier = AuthIdentifier { - username: None, - tls_cert_name: Some(subject_name.to_string()), - }; - - println!("client side quic auth_identifier: {:?}", auth_identifier); - test_auth_id = Some(auth_identifier); - } - } - None => { - println!("no client certs found"); - } - } - } else { - println!("no certs were found"); - } + println!("client side quic auth_identifier: {:?}", auth_identifier); + test_auth_id = Some(auth_identifier); + + // if let Some(cert_info) = new_conn.peer_identity() { + // //use cert info + + // match cert_info.downcast_ref::>() { + // Some(serv_certs) => { + // println!("the client certs were found"); + // for item in serv_certs { + // let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); + // let subject_name = &cert + // .subject + // .iter_common_name() + // .next() + // .and_then(|cn| cn.as_str().ok()) + // .unwrap(); + // let auth_identifier = AuthIdentifier { + // username: None, + // tls_cert_name: Some(subject_name.to_string()), + // }; + + // println!("client side quic auth_identifier: {:?}", auth_identifier); + // test_auth_id = Some(auth_identifier); + // } + // } + // None => { + // println!("no client certs found"); + // } + // } + // } else { + // println!("no certs were found"); + // } } let dst_addr = quic_conn.remote_address(); diff --git a/io/zenoh-links/zenoh-link-tls/src/unicast.rs b/io/zenoh-links/zenoh-link-tls/src/unicast.rs index 5b744ed353..8de0a27855 100644 --- a/io/zenoh-links/zenoh-link-tls/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-tls/src/unicast.rs @@ -31,7 +31,6 @@ use async_std::task; use async_trait::async_trait; use futures::io::AsyncReadExt; use futures::io::AsyncWriteExt; -use std::convert::TryInto; use std::fmt; use std::fs::File; use std::io::{BufReader, Cursor}; @@ -39,6 +38,7 @@ use std::net::Shutdown; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::Duration; +use std::{any::Any, convert::TryInto}; use std::{cell::UnsafeCell, io}; use webpki::{ anchor_from_trusted_cert, @@ -46,15 +46,20 @@ use webpki::{ }; use x509_parser::prelude::*; use zenoh_core::zasynclock; + use zenoh_link_commons::{ - get_ip_interface_names, AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, - ListenersUnicastIP, NewLinkChannelSender, + get_ip_interface_names, AuthIdBuilder, AuthIdType, AuthIdentifier, LinkManagerUnicastTrait, + LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, }; use zenoh_protocol::core::endpoint::Config; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::{bail, zerror, ZError, ZResult}; use zenoh_sync::Signal; +#[derive(Default, Debug, PartialEq, Eq, Hash)] +pub struct TlsCommonName(String); + +//impl pub struct LinkUnicastTls { // The underlying socket as returned from the async-rustls library // NOTE: TlsStream requires &mut for read and write operations. This means @@ -317,32 +322,21 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastTls { let (_, tls_conn) = tls_stream.get_ref(); - let serv_certs = tls_conn.peer_certificates().unwrap(); - let mut test_auth_id: Option = None; - - for item in serv_certs { - let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); - let subject_name = &cert - .subject - .iter_common_name() - .next() - .and_then(|cn| cn.as_str().ok()) - .unwrap(); - let auth_identifier = AuthIdentifier { - username: None, - tls_cert_name: Some(subject_name.to_string()), - }; + let auth_identifier = get_serverside_id(tls_conn); + let subject_name = auth_identifier.unwrap().clone().tls_cert_name.unwrap(); + let auth_val: Box = Box::new(TlsCommonName(subject_name)); + let authID = AuthIdBuilder::new() + .auth_type(AuthIdType::TlsCommonName) + .auth_value(Some(auth_val)) + .build(); - println!("server side tls auth_identifier: {:?}", auth_identifier); - test_auth_id = Some(auth_identifier); - } let tls_stream = TlsStream::Client(tls_stream); let link = Arc::new(LinkUnicastTls::new( tls_stream, src_addr, dst_addr, - test_auth_id, + auth_identifier, )); Ok(LinkUnicast(link)) @@ -513,6 +507,31 @@ fn get_tls_cert_name(tls_conn: &rustls::CommonState) -> Option { }) } +fn get_serverside_id(tls_conn: &rustls::ClientConnection) -> Option { + let serv_certs = tls_conn.peer_certificates().unwrap(); + let mut test_auth_id: Option = None; + + //need the first certificate in the chain + if let Some(item) = serv_certs.iter().next() { + // for item in serv_certs { + let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); + let subject_name = &cert + .subject + .iter_common_name() + .next() + .and_then(|cn| cn.as_str().ok()) + .unwrap(); + let auth_identifier = AuthIdentifier { + username: None, + tls_cert_name: Some(subject_name.to_string()), + }; + + println!("server side tls auth_identifier: {:?}", auth_identifier); + test_auth_id = Some(auth_identifier); + } + test_auth_id +} + struct TlsServerConfig { server_config: ServerConfig, } From bc1558da7788bdd96c5d505bbd24f1d075442b10 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Wed, 20 Mar 2024 17:03:16 +0100 Subject: [PATCH 09/37] adding type constraints --- io/zenoh-link-commons/src/lib.rs | 7 +- io/zenoh-link-commons/src/unicast.rs | 82 +++++++------------ io/zenoh-links/zenoh-link-quic/src/unicast.rs | 63 +++++++------- .../zenoh-link-serial/src/unicast.rs | 9 +- io/zenoh-links/zenoh-link-tcp/src/unicast.rs | 9 +- io/zenoh-links/zenoh-link-tls/src/unicast.rs | 80 +++++++++--------- io/zenoh-links/zenoh-link-udp/src/unicast.rs | 12 +-- .../zenoh-link-unixpipe/src/unix/unicast.rs | 9 +- .../zenoh-link-unixsock_stream/src/unicast.rs | 9 +- io/zenoh-links/zenoh-link-ws/src/unicast.rs | 9 +- .../interceptor/testing_interceptor.rs | 6 +- 11 files changed, 125 insertions(+), 170 deletions(-) diff --git a/io/zenoh-link-commons/src/lib.rs b/io/zenoh-link-commons/src/lib.rs index 12b4f0cabb..df9e999395 100644 --- a/io/zenoh-link-commons/src/lib.rs +++ b/io/zenoh-link-commons/src/lib.rs @@ -48,7 +48,7 @@ pub struct Link { pub is_reliable: bool, pub is_streamed: bool, pub interfaces: Vec, - pub auth_identifier: AuthIdentifier, + pub auth_identifier: AuthId, } #[async_trait] @@ -99,10 +99,7 @@ impl From<&LinkMulticast> for Link { is_reliable: link.is_reliable(), is_streamed: false, interfaces: vec![], - auth_identifier: AuthIdentifier { - username: None, - tls_cert_name: None, - }, + auth_identifier: AuthId::None, } } } diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs index 673525049e..a7428fc718 100644 --- a/io/zenoh-link-commons/src/unicast.rs +++ b/io/zenoh-link-commons/src/unicast.rs @@ -20,7 +20,6 @@ use core::{ ops::Deref, }; use serde::Serialize; -use std::any::Any; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::ZResult; @@ -49,7 +48,7 @@ pub trait LinkUnicastTrait: Send + Sync { fn is_reliable(&self) -> bool; fn is_streamed(&self) -> bool; fn get_interface_names(&self) -> Vec; - fn get_auth_identifier(&self) -> AuthIdentifier; + fn get_auth_identifier(&self) -> AuthId; async fn write(&self, buffer: &[u8]) -> ZResult; async fn write_all(&self, buffer: &[u8]) -> ZResult<()>; async fn read(&self, buffer: &mut [u8]) -> ZResult; @@ -118,14 +117,6 @@ pub fn get_ip_interface_names(addr: &SocketAddr) -> Vec { } } -#[derive(Clone, Debug, Serialize, Hash, PartialEq, Eq)] - -pub struct AuthIdentifier { - pub username: Option, - pub tls_cert_name: Option, -} - -//#[derive(Debug, Default, PartialEq)] #[derive(Clone, Debug, Serialize, Eq, Hash, PartialEq)] pub enum AuthIdType { None, @@ -133,34 +124,33 @@ pub enum AuthIdType { Username, } -#[derive(Default, Debug, PartialEq, Eq, Hash)] -pub struct Username(String); -// /* need to put restrictions on auth_id values as well */ -// pub enum AuthIdValue { -// Tls(String), -// Username(String), -// } +#[derive(Clone, Debug, Serialize, Eq, Hash, PartialEq)] + +pub enum AuthId { + None, + TlsCommonName(String), + Username(String), +} -pub struct AuthId { - pub auth_type: AuthIdType, - pub auth_value: Option>, //downcast in interceptor by auth_id_type +pub trait AuthIdTrait { + fn get_authid(&self) -> AuthId; } impl AuthId { pub fn builder() -> AuthIdBuilder { AuthIdBuilder::new() } - pub fn get_type() {} //gets the authId type +} - pub fn get_value() {} //get the authId value to be used in ACL +impl AuthIdTrait for AuthId { + fn get_authid(&self) -> AuthId { + self.clone() + } } #[derive(Debug)] pub struct AuthIdBuilder { - pub auth_type: Option, - pub auth_value: Option>, //downcast in interceptor by auth_id_type - /* - possible values for auth_value: Vec and String (as of now) - */ + pub auth_type: AuthIdType, //HAS to be provided when building + pub auth_value: AuthId, //actual value added to the above type; is None for None type } impl Default for AuthIdBuilder { fn default() -> Self { @@ -171,41 +161,27 @@ impl Default for AuthIdBuilder { impl AuthIdBuilder { pub fn new() -> AuthIdBuilder { AuthIdBuilder { - auth_type: Some(AuthIdType::None), - auth_value: None, + auth_type: AuthIdType::None, + auth_value: AuthId::None, } } pub fn auth_type(&mut self, auth_type: AuthIdType) -> &mut Self { - self.auth_type(auth_type); + self.auth_type = auth_type; self } - pub fn auth_value(&mut self, auth_value: Option>) -> &mut Self { - // let _ = self.auth_value.insert(auth_value.into()); - self.auth_value(auth_value); + pub fn auth_value(&mut self, auth_value: String) -> &mut Self { + let value = auth_value; + + match self.auth_type { + AuthIdType::None => self.auth_value = AuthId::None, + AuthIdType::TlsCommonName => self.auth_value = AuthId::TlsCommonName(value), + AuthIdType::Username => self.auth_value = AuthId::Username(value), + }; self } pub fn build(&self) -> AuthId { - let auth_type = self.auth_type.clone().unwrap(); - let auth_value = &self.auth_value; - AuthId { - auth_type, - auth_value, - } + self.auth_value.clone() } } - -// pub trait AuthIdTrait { -// fn builder() -> Builder { -// Builder::default() -// } -// fn get_type() {} //gets the authId type - -// fn get_value() {} //get the authId value to be used in ACL -// } - -// -// pub trait AuthIdValue { -// //define features to restrict auth_value behaviour -// } diff --git a/io/zenoh-links/zenoh-link-quic/src/unicast.rs b/io/zenoh-links/zenoh-link-quic/src/unicast.rs index 3b14f46d68..0ef7f05c40 100644 --- a/io/zenoh-links/zenoh-link-quic/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-quic/src/unicast.rs @@ -1,3 +1,4 @@ +use async_rustls::server; // // Copyright (c) 2023 ZettaScale Technology // @@ -33,8 +34,8 @@ use std::sync::Arc; use std::time::Duration; use zenoh_core::zasynclock; use zenoh_link_commons::{ - get_ip_interface_names, AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, - ListenersUnicastIP, NewLinkChannelSender, + get_ip_interface_names, AuthId, AuthIdBuilder, AuthIdType, LinkManagerUnicastTrait, + LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, }; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::{bail, zerror, ZError, ZResult}; @@ -47,7 +48,7 @@ pub struct LinkUnicastQuic { dst_locator: Locator, send: AsyncMutex, recv: AsyncMutex, - auth_identifier: Option, + auth_identifier: AuthId, } impl LinkUnicastQuic { @@ -57,7 +58,7 @@ impl LinkUnicastQuic { dst_locator: Locator, send: quinn::SendStream, recv: quinn::RecvStream, - auth_identifier: Option, + auth_identifier: AuthId, ) -> LinkUnicastQuic { // Build the Quic object LinkUnicastQuic { @@ -160,14 +161,15 @@ impl LinkUnicastTrait for LinkUnicastQuic { fn is_streamed(&self) -> bool { true } - fn get_auth_identifier(&self) -> AuthIdentifier { - match &self.auth_identifier { - Some(identifier) => identifier.clone(), - None => AuthIdentifier { - username: None, - tls_cert_name: None, - }, - } + fn get_auth_identifier(&self) -> AuthId { + self.auth_identifier.clone() + // match &self.auth_identifier { + // Some(identifier) => identifier.clone(), + // None => AuthIdentifier { + // username: None, + // tls_cert_name: None, + // }, + // } } } @@ -309,7 +311,7 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastQuic { .await .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))?; - let mut test_auth_id: Option = None; + let mut auth_id = AuthId::None; let pi = &quic_conn.peer_identity().unwrap(); match pi.downcast_ref::>() { @@ -323,13 +325,10 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastQuic { .next() .and_then(|cn| cn.as_str().ok()) .unwrap(); - let auth_identifier = AuthIdentifier { - username: None, - tls_cert_name: Some(subject_name.to_string()), - }; - - println!("server side quic auth_identifier: {:?}", auth_identifier); - test_auth_id = Some(auth_identifier); + auth_id = AuthIdBuilder::new() + .auth_type(AuthIdType::TlsCommonName) + .auth_value(subject_name.to_string()) + .build(); } } None => { @@ -343,7 +342,7 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastQuic { endpoint.into(), send, recv, - test_auth_id, + auth_id, )); Ok(LinkUnicast(link)) } @@ -546,7 +545,7 @@ async fn accept_task( } }; println!("the accept function is also called before check"); - let mut test_auth_id: Option = None; + let mut auth_id = AuthId::None; { let new_conn = quic_conn.clone(); let server_name = new_conn @@ -567,17 +566,23 @@ async fn accept_task( .as_ref() .unwrap() .clone(); - let auth_identifier = AuthIdentifier { - username: None, - tls_cert_name: Some(server_name.to_string()), - }; + + auth_id = AuthIdBuilder::new() + .auth_type(AuthIdType::TlsCommonName) + .auth_value(server_name.to_string()) + .build(); + // Ok(auth_id) + // let auth_identifier = AuthId { + // username: None, + // tls_cert_name: Some(server_name.to_string()), + // }; println!( "From conncetion, server_name {:?} and protocol_deets {:?}", server_name, protocol_deets ); - println!("client side quic auth_identifier: {:?}", auth_identifier); - test_auth_id = Some(auth_identifier); + println!("client side quic auth_identifier: {:?}", auth_id); + //auth_id = Some(auth_id); // if let Some(cert_info) = new_conn.peer_identity() { // //use cert info @@ -620,7 +625,7 @@ async fn accept_task( Locator::new(QUIC_LOCATOR_PREFIX, dst_addr.to_string(), "")?, send, recv, - test_auth_id, + auth_id, )); // Communicate the new link to the initial transport manager diff --git a/io/zenoh-links/zenoh-link-serial/src/unicast.rs b/io/zenoh-links/zenoh-link-serial/src/unicast.rs index 9f28d251a1..136e743e10 100644 --- a/io/zenoh-links/zenoh-link-serial/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-serial/src/unicast.rs @@ -25,7 +25,7 @@ use std::sync::{Arc, RwLock}; use std::time::Duration; use zenoh_core::{zasynclock, zread, zwrite}; use zenoh_link_commons::{ - AuthIdentifier, ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, + AuthId, ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; use zenoh_protocol::core::{EndPoint, Locator}; @@ -206,11 +206,8 @@ impl LinkUnicastTrait for LinkUnicastSerial { fn is_streamed(&self) -> bool { false } - fn get_auth_identifier(&self) -> AuthIdentifier { - AuthIdentifier { - username: None, - tls_cert_name: None, - } + fn get_auth_identifier(&self) -> AuthId { + AuthId::None } } diff --git a/io/zenoh-links/zenoh-link-tcp/src/unicast.rs b/io/zenoh-links/zenoh-link-tcp/src/unicast.rs index 22367aa2ee..19f40f531f 100644 --- a/io/zenoh-links/zenoh-link-tcp/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-tcp/src/unicast.rs @@ -22,7 +22,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::Duration; use zenoh_link_commons::{ - get_ip_interface_names, AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, + get_ip_interface_names, AuthId, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, BIND_INTERFACE, }; use zenoh_protocol::core::{EndPoint, Locator}; @@ -156,11 +156,8 @@ impl LinkUnicastTrait for LinkUnicastTcp { fn is_streamed(&self) -> bool { true } - fn get_auth_identifier(&self) -> AuthIdentifier { - AuthIdentifier { - username: None, - tls_cert_name: None, - } + fn get_auth_identifier(&self) -> AuthId { + AuthId::None } } diff --git a/io/zenoh-links/zenoh-link-tls/src/unicast.rs b/io/zenoh-links/zenoh-link-tls/src/unicast.rs index 8de0a27855..1d82140956 100644 --- a/io/zenoh-links/zenoh-link-tls/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-tls/src/unicast.rs @@ -48,7 +48,7 @@ use x509_parser::prelude::*; use zenoh_core::zasynclock; use zenoh_link_commons::{ - get_ip_interface_names, AuthIdBuilder, AuthIdType, AuthIdentifier, LinkManagerUnicastTrait, + get_ip_interface_names, AuthId, AuthIdBuilder, AuthIdType, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, }; use zenoh_protocol::core::endpoint::Config; @@ -79,7 +79,7 @@ pub struct LinkUnicastTls { // Make sure there are no concurrent read or writes write_mtx: AsyncMutex<()>, read_mtx: AsyncMutex<()>, - auth_identifier: Option, + auth_identifier: AuthId, } unsafe impl Send for LinkUnicastTls {} @@ -90,7 +90,7 @@ impl LinkUnicastTls { socket: TlsStream, src_addr: SocketAddr, dst_addr: SocketAddr, - auth_identifier: Option, + auth_identifier: AuthId, ) -> LinkUnicastTls { let (tcp_stream, _) = socket.get_ref(); // Set the TLS nodelay option @@ -218,14 +218,15 @@ impl LinkUnicastTrait for LinkUnicastTls { true } #[inline(always)] - fn get_auth_identifier(&self) -> AuthIdentifier { - match &self.auth_identifier { - Some(identifier) => identifier.clone(), - None => AuthIdentifier { - username: None, - tls_cert_name: None, - }, - } + fn get_auth_identifier(&self) -> AuthId { + self.auth_identifier.clone() + // match &self.auth_identifier { + // Some(identifier) => identifier.clone(), + // None => AuthIdentifier { + // username: None, + // tls_cert_name: None, + // }, + // } } } @@ -322,13 +323,7 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastTls { let (_, tls_conn) = tls_stream.get_ref(); - let auth_identifier = get_serverside_id(tls_conn); - let subject_name = auth_identifier.unwrap().clone().tls_cert_name.unwrap(); - let auth_val: Box = Box::new(TlsCommonName(subject_name)); - let authID = AuthIdBuilder::new() - .auth_type(AuthIdType::TlsCommonName) - .auth_value(Some(auth_val)) - .build(); + let auth_identifier = get_serverside_id(tls_conn)?; let tls_stream = TlsStream::Client(tls_stream); @@ -466,13 +461,7 @@ async fn accept_task( let (_, tls_conn) = tls_stream.get_ref(); //let mut test_auth_id: Option = None; - let auth_identifier = get_tls_cert_name(tls_conn); - println!("client side tls auth_identifier: {:?}", auth_identifier); - // match auth_identifier { - // Some(auth_id) => println!("client's ID: {:?}", auth_id), - // None => println!("no client ID found"), - // } - + let auth_identifier = get_tls_common_name(tls_conn)?; log::debug!("Accepted TLS connection on {:?}: {:?}", src_addr, dst_addr); // Create the new link object let link = Arc::new(LinkUnicastTls::new( @@ -491,9 +480,9 @@ async fn accept_task( Ok(()) } -fn get_tls_cert_name(tls_conn: &rustls::CommonState) -> Option { - let serv_certs = tls_conn.peer_certificates()?; - let (_, cert) = X509Certificate::from_der(serv_certs[0].as_ref()).unwrap(); +fn get_tls_common_name(tls_conn: &rustls::CommonState) -> ZResult { + let serv_certs = tls_conn.peer_certificates().unwrap(); + let (_, cert) = X509Certificate::from_der(serv_certs[0].as_ref())?; let subject_name = &cert .subject .iter_common_name() @@ -501,35 +490,42 @@ fn get_tls_cert_name(tls_conn: &rustls::CommonState) -> Option { .and_then(|cn| cn.as_str().ok()) .unwrap(); - Some(AuthIdentifier { - username: None, - tls_cert_name: Some(subject_name.to_string()), - }) + let auth_id = AuthIdBuilder::new() + .auth_type(AuthIdType::TlsCommonName) + .auth_value(subject_name.to_string()) + .build(); + Ok(auth_id) } -fn get_serverside_id(tls_conn: &rustls::ClientConnection) -> Option { +fn get_serverside_id(tls_conn: &rustls::ClientConnection) -> ZResult { let serv_certs = tls_conn.peer_certificates().unwrap(); - let mut test_auth_id: Option = None; + let mut auth_id = AuthId::None; //need the first certificate in the chain if let Some(item) = serv_certs.iter().next() { // for item in serv_certs { - let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); + let (_, cert) = X509Certificate::from_der(item.as_ref())?; let subject_name = &cert .subject .iter_common_name() .next() .and_then(|cn| cn.as_str().ok()) .unwrap(); - let auth_identifier = AuthIdentifier { - username: None, - tls_cert_name: Some(subject_name.to_string()), - }; + // let auth_identifier = AuthIdentifier { + // username: None, + // tls_cert_name: Some(subject_name.to_string()), + // }; + + //build the AuthId + auth_id = AuthIdBuilder::new() + .auth_type(AuthIdType::TlsCommonName) + .auth_value(subject_name.to_string()) + .build(); - println!("server side tls auth_identifier: {:?}", auth_identifier); - test_auth_id = Some(auth_identifier); + println!("server side tls auth_identifier: {:?}", auth_id); + return Ok(auth_id); } - test_auth_id + Ok(auth_id) } struct TlsServerConfig { diff --git a/io/zenoh-links/zenoh-link-udp/src/unicast.rs b/io/zenoh-links/zenoh-link-udp/src/unicast.rs index 2dde7bc085..a731604d8a 100644 --- a/io/zenoh-links/zenoh-link-udp/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-udp/src/unicast.rs @@ -27,9 +27,8 @@ use std::sync::{Arc, Mutex, Weak}; use std::time::Duration; use zenoh_core::{zasynclock, zlock}; use zenoh_link_commons::{ - get_ip_interface_names, AuthIdentifier, ConstructibleLinkManagerUnicast, - LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, - NewLinkChannelSender, BIND_INTERFACE, + get_ip_interface_names, AuthId, ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, + LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, BIND_INTERFACE, }; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::{bail, zerror, Error as ZError, ZResult}; @@ -221,11 +220,8 @@ impl LinkUnicastTrait for LinkUnicastUdp { fn is_streamed(&self) -> bool { false } - fn get_auth_identifier(&self) -> AuthIdentifier { - AuthIdentifier { - username: None, - tls_cert_name: None, - } + fn get_auth_identifier(&self) -> AuthId { + AuthId::None } } diff --git a/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs b/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs index 0fb4e7d2ef..275be98dab 100644 --- a/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs +++ b/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs @@ -35,7 +35,7 @@ use zenoh_protocol::core::{EndPoint, Locator}; use unix_named_pipe::{create, open_write}; use zenoh_link_commons::{ - AuthIdentifier, ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, + AuthId, ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; use zenoh_result::{bail, ZResult}; @@ -508,11 +508,8 @@ impl LinkUnicastTrait for UnicastPipe { fn is_streamed(&self) -> bool { true } - fn get_auth_identifier(&self) -> AuthIdentifier { - AuthIdentifier { - username: None, - tls_cert_name: None, - } + fn get_auth_identifier(&self) -> AuthId { + AuthId::None } } diff --git a/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs b/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs index 3111108438..c4f8256b84 100644 --- a/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs @@ -31,7 +31,7 @@ use std::time::Duration; use uuid::Uuid; use zenoh_core::{zread, zwrite}; use zenoh_link_commons::{ - AuthIdentifier, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, + AuthId, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::{zerror, ZResult}; @@ -131,11 +131,8 @@ impl LinkUnicastTrait for LinkUnicastUnixSocketStream { fn is_streamed(&self) -> bool { true } - fn get_auth_identifier(&self) -> AuthIdentifier { - AuthIdentifier { - username: None, - tls_cert_name: None, - } + fn get_auth_identifier(&self) -> AuthId { + AuthId::None } } diff --git a/io/zenoh-links/zenoh-link-ws/src/unicast.rs b/io/zenoh-links/zenoh-link-ws/src/unicast.rs index 33862dc89c..ba0e81d178 100644 --- a/io/zenoh-links/zenoh-link-ws/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-ws/src/unicast.rs @@ -32,7 +32,7 @@ use tokio_tungstenite::accept_async; use tokio_tungstenite::tungstenite::Message; use tokio_tungstenite::{MaybeTlsStream, WebSocketStream}; use zenoh_core::{zasynclock, zread, zwrite}; -use zenoh_link_commons::AuthIdentifier; +use zenoh_link_commons::AuthId; use zenoh_link_commons::{ LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; @@ -224,11 +224,8 @@ impl LinkUnicastTrait for LinkUnicastWs { fn is_streamed(&self) -> bool { false } - fn get_auth_identifier(&self) -> AuthIdentifier { - AuthIdentifier { - username: None, - tls_cert_name: None, - } + fn get_auth_identifier(&self) -> AuthId { + AuthId::None } } diff --git a/zenoh/src/net/routing/interceptor/testing_interceptor.rs b/zenoh/src/net/routing/interceptor/testing_interceptor.rs index e667d9330b..4c81439653 100644 --- a/zenoh/src/net/routing/interceptor/testing_interceptor.rs +++ b/zenoh/src/net/routing/interceptor/testing_interceptor.rs @@ -1,7 +1,7 @@ use crate::KeyExpr; use std::any::Any; -use zenoh_link::AuthIdentifier; +use zenoh_link::AuthId; use zenoh_protocol::network::NetworkMessage; use zenoh_result::ZResult; use zenoh_transport::{multicast::TransportMulticast, unicast::TransportUnicast}; @@ -16,10 +16,10 @@ use super::{ pub(crate) struct TestInterceptor {} struct EgressTestInterceptor { - _auth_id: Option, + _auth_id: Option, } struct IngressTestInterceptor { - _auth_id: Option, + _auth_id: Option, } pub(crate) fn new_test_interceptor() -> ZResult> { From 294e0c5dcd1084dca2653f9c40a1480c1d034602 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Fri, 22 Mar 2024 17:39:41 +0100 Subject: [PATCH 10/37] adding level abstraction for authentication info --- io/zenoh-link-commons/src/lib.rs | 4 +- io/zenoh-link-commons/src/unicast.rs | 109 ++++++++----- io/zenoh-links/zenoh-link-quic/src/unicast.rs | 150 +++++------------- .../zenoh-link-serial/src/unicast.rs | 7 +- io/zenoh-links/zenoh-link-tcp/src/unicast.rs | 6 +- io/zenoh-links/zenoh-link-tls/src/unicast.rs | 122 +++++++------- io/zenoh-links/zenoh-link-udp/src/unicast.rs | 7 +- .../zenoh-link-unixpipe/src/unix/unicast.rs | 7 +- .../zenoh-link-unixsock_stream/src/unicast.rs | 7 +- io/zenoh-links/zenoh-link-ws/src/unicast.rs | 7 +- io/zenoh-transport/src/lib.rs | 1 - .../src/unicast/authentication.rs | 18 +++ .../src/unicast/lowlatency/transport.rs | 5 + io/zenoh-transport/src/unicast/mod.rs | 13 +- .../src/unicast/transport_unicast_inner.rs | 1 + .../src/unicast/universal/transport.rs | 9 ++ .../interceptor/testing_interceptor.rs | 12 +- 17 files changed, 237 insertions(+), 248 deletions(-) create mode 100644 io/zenoh-transport/src/unicast/authentication.rs diff --git a/io/zenoh-link-commons/src/lib.rs b/io/zenoh-link-commons/src/lib.rs index df9e999395..d0210cea62 100644 --- a/io/zenoh-link-commons/src/lib.rs +++ b/io/zenoh-link-commons/src/lib.rs @@ -48,7 +48,7 @@ pub struct Link { pub is_reliable: bool, pub is_streamed: bool, pub interfaces: Vec, - pub auth_identifier: AuthId, + pub auth_identifier: LinkAuthId, } #[async_trait] @@ -99,7 +99,7 @@ impl From<&LinkMulticast> for Link { is_reliable: link.is_reliable(), is_streamed: false, interfaces: vec![], - auth_identifier: AuthId::None, + auth_identifier: LinkAuthId::default(), } } } diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs index a7428fc718..3722702266 100644 --- a/io/zenoh-link-commons/src/unicast.rs +++ b/io/zenoh-link-commons/src/unicast.rs @@ -22,7 +22,6 @@ use core::{ use serde::Serialize; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::ZResult; - pub type LinkManagerUnicast = Arc; #[async_trait] pub trait LinkManagerUnicastTrait: Send + Sync { @@ -48,7 +47,7 @@ pub trait LinkUnicastTrait: Send + Sync { fn is_reliable(&self) -> bool; fn is_streamed(&self) -> bool; fn get_interface_names(&self) -> Vec; - fn get_auth_identifier(&self) -> AuthId; + fn get_auth_identifier(&self) -> LinkAuthId; async fn write(&self, buffer: &[u8]) -> ZResult; async fn write_all(&self, buffer: &[u8]) -> ZResult<()>; async fn read(&self, buffer: &mut [u8]) -> ZResult; @@ -116,72 +115,96 @@ pub fn get_ip_interface_names(addr: &SocketAddr) -> Vec { } } } +#[derive(Clone, Debug, Serialize, Hash, PartialEq, Eq)] -#[derive(Clone, Debug, Serialize, Eq, Hash, PartialEq)] -pub enum AuthIdType { +pub enum LinkAuthType { + Tls, + Quic, None, - TlsCommonName, - Username, } +#[derive(Clone, Debug, Serialize, Hash, PartialEq, Eq)] -#[derive(Clone, Debug, Serialize, Eq, Hash, PartialEq)] - -pub enum AuthId { - None, - TlsCommonName(String), - Username(String), +pub struct LinkAuthId { + auth_type: LinkAuthType, + auth_value: Option, } -pub trait AuthIdTrait { - fn get_authid(&self) -> AuthId; -} - -impl AuthId { - pub fn builder() -> AuthIdBuilder { - AuthIdBuilder::new() +impl LinkAuthId { + pub fn get_type(&self) -> &LinkAuthType { + &self.auth_type + } + pub fn get_value(&self) -> &Option { + &self.auth_value } } - -impl AuthIdTrait for AuthId { - fn get_authid(&self) -> AuthId { - self.clone() +impl Default for LinkAuthId { + fn default() -> Self { + LinkAuthId { + auth_type: LinkAuthType::None, + auth_value: None, + } } } + +// #[derive(Clone, Debug, Serialize, Eq, Hash, PartialEq)] +// pub enum AuthIdType { +// None, +// TlsCommonName, +// Username, +// } + +// #[derive(Clone, Debug, Serialize, Eq, Hash, PartialEq)] + +// pub enum AuthId { +// None, +// TlsCommonName(String), +// Username(String), +// } + +// impl AuthId { +// pub fn builder() -> LinkAuthIdBuilder { +// LinkAuthIdBuilder::new() +// } +// } #[derive(Debug)] -pub struct AuthIdBuilder { - pub auth_type: AuthIdType, //HAS to be provided when building - pub auth_value: AuthId, //actual value added to the above type; is None for None type +pub struct LinkAuthIdBuilder { + pub auth_type: LinkAuthType, //HAS to be provided when building + pub auth_value: Option, //actual value added to the above type; is None for None type } -impl Default for AuthIdBuilder { +impl Default for LinkAuthIdBuilder { fn default() -> Self { Self::new() } } -impl AuthIdBuilder { - pub fn new() -> AuthIdBuilder { - AuthIdBuilder { - auth_type: AuthIdType::None, - auth_value: AuthId::None, +impl LinkAuthIdBuilder { + pub fn new() -> LinkAuthIdBuilder { + LinkAuthIdBuilder { + auth_type: LinkAuthType::None, + auth_value: None, } } - pub fn auth_type(&mut self, auth_type: AuthIdType) -> &mut Self { + pub fn auth_type(&mut self, auth_type: LinkAuthType) -> &mut Self { self.auth_type = auth_type; self } - pub fn auth_value(&mut self, auth_value: String) -> &mut Self { - let value = auth_value; - - match self.auth_type { - AuthIdType::None => self.auth_value = AuthId::None, - AuthIdType::TlsCommonName => self.auth_value = AuthId::TlsCommonName(value), - AuthIdType::Username => self.auth_value = AuthId::Username(value), - }; + pub fn auth_value(&mut self, auth_value: Option) -> &mut Self { + self.auth_value = auth_value; + // let value = auth_value; + + // match self.auth_type { + // LinkAuthType::None => self.auth_value = LinkAuthId::None, + // LinkAuthType::Tls => self.auth_value = LinkAuthId::TlsCommonName(value), + // LinkAuthType::Quic => self.auth_value = AuthId::Username(value), + // }; self } - pub fn build(&self) -> AuthId { - self.auth_value.clone() + pub fn build(&self) -> LinkAuthId { + LinkAuthId { + auth_type: self.auth_type.clone(), + auth_value: self.auth_value.clone(), + } } } diff --git a/io/zenoh-links/zenoh-link-quic/src/unicast.rs b/io/zenoh-links/zenoh-link-quic/src/unicast.rs index 0ef7f05c40..3112840140 100644 --- a/io/zenoh-links/zenoh-link-quic/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-quic/src/unicast.rs @@ -1,4 +1,3 @@ -use async_rustls::server; // // Copyright (c) 2023 ZettaScale Technology // @@ -34,7 +33,7 @@ use std::sync::Arc; use std::time::Duration; use zenoh_core::zasynclock; use zenoh_link_commons::{ - get_ip_interface_names, AuthId, AuthIdBuilder, AuthIdType, LinkManagerUnicastTrait, + get_ip_interface_names, LinkAuthId, LinkAuthIdBuilder, LinkAuthType, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, }; use zenoh_protocol::core::{EndPoint, Locator}; @@ -48,7 +47,7 @@ pub struct LinkUnicastQuic { dst_locator: Locator, send: AsyncMutex, recv: AsyncMutex, - auth_identifier: AuthId, + auth_identifier: LinkAuthId, } impl LinkUnicastQuic { @@ -58,7 +57,7 @@ impl LinkUnicastQuic { dst_locator: Locator, send: quinn::SendStream, recv: quinn::RecvStream, - auth_identifier: AuthId, + auth_identifier: LinkAuthId, ) -> LinkUnicastQuic { // Build the Quic object LinkUnicastQuic { @@ -161,15 +160,8 @@ impl LinkUnicastTrait for LinkUnicastQuic { fn is_streamed(&self) -> bool { true } - fn get_auth_identifier(&self) -> AuthId { + fn get_auth_identifier(&self) -> LinkAuthId { self.auth_identifier.clone() - // match &self.auth_identifier { - // Some(identifier) => identifier.clone(), - // None => AuthIdentifier { - // username: None, - // tls_cert_name: None, - // }, - // } } } @@ -311,30 +303,7 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastQuic { .await .map_err(|e| zerror!("Can not create a new QUIC link bound to {}: {}", host, e))?; - let mut auth_id = AuthId::None; - - let pi = &quic_conn.peer_identity().unwrap(); - match pi.downcast_ref::>() { - Some(serv_certs) => { - println!("the server certs were found"); - for item in serv_certs { - let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); - let subject_name = &cert - .subject - .iter_common_name() - .next() - .and_then(|cn| cn.as_str().ok()) - .unwrap(); - auth_id = AuthIdBuilder::new() - .auth_type(AuthIdType::TlsCommonName) - .auth_value(subject_name.to_string()) - .build(); - } - } - None => { - println!("no server certs found"); - } - } + let auth_id = get_tls_cert_name(quic_conn.clone())?; let link = Arc::new(LinkUnicastQuic::new( quic_conn, @@ -342,7 +311,7 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastQuic { endpoint.into(), send, recv, - auth_id, + auth_id.into(), )); Ok(LinkUnicast(link)) } @@ -544,78 +513,7 @@ async fn accept_task( continue; } }; - println!("the accept function is also called before check"); - let mut auth_id = AuthId::None; - { - let new_conn = quic_conn.clone(); - let server_name = new_conn - .handshake_data() - .unwrap() - .downcast_ref::() - .unwrap() - .server_name - .as_ref() - .unwrap() - .clone(); - let protocol_deets = new_conn - .handshake_data() - .unwrap() - .downcast_ref::() - .unwrap() - .protocol - .as_ref() - .unwrap() - .clone(); - - auth_id = AuthIdBuilder::new() - .auth_type(AuthIdType::TlsCommonName) - .auth_value(server_name.to_string()) - .build(); - // Ok(auth_id) - // let auth_identifier = AuthId { - // username: None, - // tls_cert_name: Some(server_name.to_string()), - // }; - - println!( - "From conncetion, server_name {:?} and protocol_deets {:?}", - server_name, protocol_deets - ); - println!("client side quic auth_identifier: {:?}", auth_id); - //auth_id = Some(auth_id); - - // if let Some(cert_info) = new_conn.peer_identity() { - // //use cert info - - // match cert_info.downcast_ref::>() { - // Some(serv_certs) => { - // println!("the client certs were found"); - // for item in serv_certs { - // let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); - // let subject_name = &cert - // .subject - // .iter_common_name() - // .next() - // .and_then(|cn| cn.as_str().ok()) - // .unwrap(); - // let auth_identifier = AuthIdentifier { - // username: None, - // tls_cert_name: Some(subject_name.to_string()), - // }; - - // println!("client side quic auth_identifier: {:?}", auth_identifier); - // test_auth_id = Some(auth_identifier); - // } - // } - // None => { - // println!("no client certs found"); - // } - // } - // } else { - // println!("no certs were found"); - // } - } - + let auth_id = get_tls_cert_name(quic_conn.clone())?; let dst_addr = quic_conn.remote_address(); log::debug!("Accepted QUIC connection on {:?}: {:?}", src_addr, dst_addr); // Create the new link object @@ -625,7 +523,7 @@ async fn accept_task( Locator::new(QUIC_LOCATOR_PREFIX, dst_addr.to_string(), "")?, send, recv, - auth_id, + auth_id.into(), )); // Communicate the new link to the initial transport manager @@ -636,3 +534,35 @@ async fn accept_task( Ok(()) } + +fn get_tls_cert_name(conn: quinn::Connection) -> ZResult { + let mut auth_id = QuicAuthId { auth_value: None }; + if let Some(pi) = conn.peer_identity() { + let serv_certs = pi.downcast::>().unwrap(); + if let Some(item) = serv_certs.iter().next() { + let (_, cert) = X509Certificate::from_der(item.as_ref()).unwrap(); + let subject_name = cert + .subject + .iter_common_name() + .next() + .and_then(|cn| cn.as_str().ok()) + .unwrap(); + auth_id = QuicAuthId { + auth_value: Some(subject_name.to_string()), + }; + } + } + Ok(auth_id) +} + +struct QuicAuthId { + auth_value: Option, +} +impl From for LinkAuthId { + fn from(value: QuicAuthId) -> Self { + LinkAuthIdBuilder::new() + .auth_type(LinkAuthType::Quic) + .auth_value(value.auth_value.clone()) + .build() + } +} diff --git a/io/zenoh-links/zenoh-link-serial/src/unicast.rs b/io/zenoh-links/zenoh-link-serial/src/unicast.rs index 136e743e10..159f4ab8c4 100644 --- a/io/zenoh-links/zenoh-link-serial/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-serial/src/unicast.rs @@ -25,7 +25,7 @@ use std::sync::{Arc, RwLock}; use std::time::Duration; use zenoh_core::{zasynclock, zread, zwrite}; use zenoh_link_commons::{ - AuthId, ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, + ConstructibleLinkManagerUnicast, LinkAuthId, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; use zenoh_protocol::core::{EndPoint, Locator}; @@ -206,8 +206,9 @@ impl LinkUnicastTrait for LinkUnicastSerial { fn is_streamed(&self) -> bool { false } - fn get_auth_identifier(&self) -> AuthId { - AuthId::None + #[inline(always)] + fn get_auth_identifier(&self) -> LinkAuthId { + LinkAuthId::default() } } diff --git a/io/zenoh-links/zenoh-link-tcp/src/unicast.rs b/io/zenoh-links/zenoh-link-tcp/src/unicast.rs index 19f40f531f..8c98b5ba90 100644 --- a/io/zenoh-links/zenoh-link-tcp/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-tcp/src/unicast.rs @@ -22,7 +22,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::Duration; use zenoh_link_commons::{ - get_ip_interface_names, AuthId, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, + get_ip_interface_names, LinkAuthId, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, BIND_INTERFACE, }; use zenoh_protocol::core::{EndPoint, Locator}; @@ -156,8 +156,8 @@ impl LinkUnicastTrait for LinkUnicastTcp { fn is_streamed(&self) -> bool { true } - fn get_auth_identifier(&self) -> AuthId { - AuthId::None + fn get_auth_identifier(&self) -> LinkAuthId { + LinkAuthId::default() } } diff --git a/io/zenoh-links/zenoh-link-tls/src/unicast.rs b/io/zenoh-links/zenoh-link-tls/src/unicast.rs index 1d82140956..244b7d1a8c 100644 --- a/io/zenoh-links/zenoh-link-tls/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-tls/src/unicast.rs @@ -31,6 +31,7 @@ use async_std::task; use async_trait::async_trait; use futures::io::AsyncReadExt; use futures::io::AsyncWriteExt; +use std::convert::TryInto; use std::fmt; use std::fs::File; use std::io::{BufReader, Cursor}; @@ -38,7 +39,6 @@ use std::net::Shutdown; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::Duration; -use std::{any::Any, convert::TryInto}; use std::{cell::UnsafeCell, io}; use webpki::{ anchor_from_trusted_cert, @@ -48,7 +48,7 @@ use x509_parser::prelude::*; use zenoh_core::zasynclock; use zenoh_link_commons::{ - get_ip_interface_names, AuthId, AuthIdBuilder, AuthIdType, LinkManagerUnicastTrait, + get_ip_interface_names, LinkAuthId, LinkAuthIdBuilder, LinkAuthType, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, }; use zenoh_protocol::core::endpoint::Config; @@ -79,7 +79,7 @@ pub struct LinkUnicastTls { // Make sure there are no concurrent read or writes write_mtx: AsyncMutex<()>, read_mtx: AsyncMutex<()>, - auth_identifier: AuthId, + auth_identifier: LinkAuthId, } unsafe impl Send for LinkUnicastTls {} @@ -90,7 +90,7 @@ impl LinkUnicastTls { socket: TlsStream, src_addr: SocketAddr, dst_addr: SocketAddr, - auth_identifier: AuthId, + auth_identifier: LinkAuthId, ) -> LinkUnicastTls { let (tcp_stream, _) = socket.get_ref(); // Set the TLS nodelay option @@ -218,15 +218,8 @@ impl LinkUnicastTrait for LinkUnicastTls { true } #[inline(always)] - fn get_auth_identifier(&self) -> AuthId { + fn get_auth_identifier(&self) -> LinkAuthId { self.auth_identifier.clone() - // match &self.auth_identifier { - // Some(identifier) => identifier.clone(), - // None => AuthIdentifier { - // username: None, - // tls_cert_name: None, - // }, - // } } } @@ -331,7 +324,7 @@ impl LinkManagerUnicastTrait for LinkManagerUnicastTls { tls_stream, src_addr, dst_addr, - auth_identifier, + auth_identifier.into(), )); Ok(LinkUnicast(link)) @@ -468,7 +461,7 @@ async fn accept_task( tls_stream, src_addr, dst_addr, - auth_identifier, + auth_identifier.into(), )); // Communicate the new link to the initial transport manager @@ -479,55 +472,6 @@ async fn accept_task( Ok(()) } - -fn get_tls_common_name(tls_conn: &rustls::CommonState) -> ZResult { - let serv_certs = tls_conn.peer_certificates().unwrap(); - let (_, cert) = X509Certificate::from_der(serv_certs[0].as_ref())?; - let subject_name = &cert - .subject - .iter_common_name() - .next() - .and_then(|cn| cn.as_str().ok()) - .unwrap(); - - let auth_id = AuthIdBuilder::new() - .auth_type(AuthIdType::TlsCommonName) - .auth_value(subject_name.to_string()) - .build(); - Ok(auth_id) -} - -fn get_serverside_id(tls_conn: &rustls::ClientConnection) -> ZResult { - let serv_certs = tls_conn.peer_certificates().unwrap(); - let mut auth_id = AuthId::None; - - //need the first certificate in the chain - if let Some(item) = serv_certs.iter().next() { - // for item in serv_certs { - let (_, cert) = X509Certificate::from_der(item.as_ref())?; - let subject_name = &cert - .subject - .iter_common_name() - .next() - .and_then(|cn| cn.as_str().ok()) - .unwrap(); - // let auth_identifier = AuthIdentifier { - // username: None, - // tls_cert_name: Some(subject_name.to_string()), - // }; - - //build the AuthId - auth_id = AuthIdBuilder::new() - .auth_type(AuthIdType::TlsCommonName) - .auth_value(subject_name.to_string()) - .build(); - - println!("server side tls auth_identifier: {:?}", auth_id); - return Ok(auth_id); - } - Ok(auth_id) -} - struct TlsServerConfig { server_config: ServerConfig, } @@ -882,3 +826,55 @@ fn load_default_webpki_certs() -> RootCertStore { })); root_cert_store } + +fn get_tls_common_name(tls_conn: &rustls::CommonState) -> ZResult { + if let Some(serv_certs) = tls_conn.peer_certificates() { + let (_, cert) = X509Certificate::from_der(serv_certs[0].as_ref())?; + let subject_name = &cert + .subject + .iter_common_name() + .next() + .and_then(|cn| cn.as_str().ok()) + .unwrap(); + + Ok(TlsAuthId { + auth_value: Some(subject_name.to_string()), + }) + } else { + Ok(TlsAuthId { auth_value: None }) + } +} + +fn get_serverside_id(tls_conn: &rustls::ClientConnection) -> ZResult { + let serv_certs = tls_conn.peer_certificates().unwrap(); + let mut auth_id = TlsAuthId { auth_value: None }; + + //need the first certificate in the chain os no need for looping + if let Some(item) = serv_certs.iter().next() { + let (_, cert) = X509Certificate::from_der(item.as_ref())?; + let subject_name = &cert + .subject + .iter_common_name() + .next() + .and_then(|cn| cn.as_str().ok()) + .unwrap(); + + auth_id = TlsAuthId { + auth_value: Some(subject_name.to_string()), + }; + return Ok(auth_id); + } + Ok(auth_id) +} + +struct TlsAuthId { + auth_value: Option, +} +impl From for LinkAuthId { + fn from(value: TlsAuthId) -> Self { + LinkAuthIdBuilder::new() + .auth_type(LinkAuthType::Tls) + .auth_value(value.auth_value.clone()) + .build() + } +} diff --git a/io/zenoh-links/zenoh-link-udp/src/unicast.rs b/io/zenoh-links/zenoh-link-udp/src/unicast.rs index a731604d8a..f65da5866a 100644 --- a/io/zenoh-links/zenoh-link-udp/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-udp/src/unicast.rs @@ -27,7 +27,7 @@ use std::sync::{Arc, Mutex, Weak}; use std::time::Duration; use zenoh_core::{zasynclock, zlock}; use zenoh_link_commons::{ - get_ip_interface_names, AuthId, ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, + get_ip_interface_names, ConstructibleLinkManagerUnicast, LinkAuthId, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, BIND_INTERFACE, }; use zenoh_protocol::core::{EndPoint, Locator}; @@ -220,8 +220,9 @@ impl LinkUnicastTrait for LinkUnicastUdp { fn is_streamed(&self) -> bool { false } - fn get_auth_identifier(&self) -> AuthId { - AuthId::None + #[inline(always)] + fn get_auth_identifier(&self) -> LinkAuthId { + LinkAuthId::default() } } diff --git a/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs b/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs index 275be98dab..f25564af09 100644 --- a/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs +++ b/io/zenoh-links/zenoh-link-unixpipe/src/unix/unicast.rs @@ -35,7 +35,7 @@ use zenoh_protocol::core::{EndPoint, Locator}; use unix_named_pipe::{create, open_write}; use zenoh_link_commons::{ - AuthId, ConstructibleLinkManagerUnicast, LinkManagerUnicastTrait, LinkUnicast, + ConstructibleLinkManagerUnicast, LinkAuthId, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; use zenoh_result::{bail, ZResult}; @@ -508,8 +508,9 @@ impl LinkUnicastTrait for UnicastPipe { fn is_streamed(&self) -> bool { true } - fn get_auth_identifier(&self) -> AuthId { - AuthId::None + #[inline(always)] + fn get_auth_identifier(&self) -> LinkAuthId { + LinkAuthId::default() } } diff --git a/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs b/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs index c4f8256b84..c263082b65 100644 --- a/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-unixsock_stream/src/unicast.rs @@ -31,7 +31,7 @@ use std::time::Duration; use uuid::Uuid; use zenoh_core::{zread, zwrite}; use zenoh_link_commons::{ - AuthId, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, + LinkAuthId, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; use zenoh_protocol::core::{EndPoint, Locator}; use zenoh_result::{zerror, ZResult}; @@ -131,8 +131,9 @@ impl LinkUnicastTrait for LinkUnicastUnixSocketStream { fn is_streamed(&self) -> bool { true } - fn get_auth_identifier(&self) -> AuthId { - AuthId::None + #[inline(always)] + fn get_auth_identifier(&self) -> LinkAuthId { + LinkAuthId::default() } } diff --git a/io/zenoh-links/zenoh-link-ws/src/unicast.rs b/io/zenoh-links/zenoh-link-ws/src/unicast.rs index ba0e81d178..d0ebef6db5 100644 --- a/io/zenoh-links/zenoh-link-ws/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-ws/src/unicast.rs @@ -32,7 +32,7 @@ use tokio_tungstenite::accept_async; use tokio_tungstenite::tungstenite::Message; use tokio_tungstenite::{MaybeTlsStream, WebSocketStream}; use zenoh_core::{zasynclock, zread, zwrite}; -use zenoh_link_commons::AuthId; +use zenoh_link_commons::LinkAuthId; use zenoh_link_commons::{ LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; @@ -224,8 +224,9 @@ impl LinkUnicastTrait for LinkUnicastWs { fn is_streamed(&self) -> bool { false } - fn get_auth_identifier(&self) -> AuthId { - AuthId::None + #[inline(always)] + fn get_auth_identifier(&self) -> LinkAuthId { + LinkAuthId::default() } } diff --git a/io/zenoh-transport/src/lib.rs b/io/zenoh-transport/src/lib.rs index 5e00bed2e7..5f267b1dda 100644 --- a/io/zenoh-transport/src/lib.rs +++ b/io/zenoh-transport/src/lib.rs @@ -37,7 +37,6 @@ use zenoh_link::Link; use zenoh_protocol::core::{WhatAmI, ZenohId}; use zenoh_protocol::network::NetworkMessage; use zenoh_result::ZResult; - /*************************************/ /* TRANSPORT */ /*************************************/ diff --git a/io/zenoh-transport/src/unicast/authentication.rs b/io/zenoh-transport/src/unicast/authentication.rs new file mode 100644 index 0000000000..ee38a23faa --- /dev/null +++ b/io/zenoh-transport/src/unicast/authentication.rs @@ -0,0 +1,18 @@ +use zenoh_link::{LinkAuthId, LinkAuthType}; + +#[derive(Debug)] +pub enum AuthId { + CertCommonName(String), + Username(String), + None, +} +impl From for AuthId { + fn from(lid: LinkAuthId) -> Self { + match (lid.get_type(), lid.get_value()) { + (LinkAuthType::Tls | LinkAuthType::Quic, Some(auth_value)) => { + AuthId::CertCommonName(auth_value.clone()) + } + _ => AuthId::None, + } + } +} diff --git a/io/zenoh-transport/src/unicast/lowlatency/transport.rs b/io/zenoh-transport/src/unicast/lowlatency/transport.rs index afc7d3c849..b935c5929f 100644 --- a/io/zenoh-transport/src/unicast/lowlatency/transport.rs +++ b/io/zenoh-transport/src/unicast/lowlatency/transport.rs @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // +use super::super::authentication::AuthId; #[cfg(feature = "stats")] use crate::stats::TransportStats; use crate::{ @@ -181,6 +182,10 @@ impl TransportUnicastTrait for TransportUnicastLowlatency { self.config.zid } + fn get_auth_ids(&self) -> Vec { + vec![] + } + fn get_whatami(&self) -> WhatAmI { self.config.whatami } diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 55226f287c..da99331b32 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -11,21 +11,21 @@ // Contributors: // ZettaScale Zenoh Team, // +pub mod authentication; pub mod establishment; pub(crate) mod link; pub(crate) mod lowlatency; pub(crate) mod manager; -pub(crate) mod transport_unicast_inner; -pub(crate) mod universal; - #[cfg(feature = "test")] pub mod test_helpers; +pub(crate) mod transport_unicast_inner; +pub(crate) mod universal; #[cfg(feature = "shared-memory")] pub(crate) mod shared_memory_unicast; +use self::authentication::AuthId; use self::transport_unicast_inner::TransportUnicastTrait; - use super::{TransportPeer, TransportPeerEventHandler}; #[cfg(feature = "transport_multilink")] use establishment::ext::auth::ZPublicKey; @@ -115,6 +115,11 @@ impl TransportUnicast { Ok(transport.get_links()) } + pub fn get_auth_ids(&self) -> ZResult> { + let transport = self.get_inner()?; + Ok(transport.get_auth_ids()) + } + #[inline(always)] pub fn schedule(&self, message: NetworkMessage) -> ZResult<()> { let transport = self.get_inner()?; diff --git a/io/zenoh-transport/src/unicast/transport_unicast_inner.rs b/io/zenoh-transport/src/unicast/transport_unicast_inner.rs index 92093959dd..d6c8b0cbcd 100644 --- a/io/zenoh-transport/src/unicast/transport_unicast_inner.rs +++ b/io/zenoh-transport/src/unicast/transport_unicast_inner.rs @@ -55,6 +55,7 @@ pub(crate) trait TransportUnicastTrait: Send + Sync { fn get_whatami(&self) -> WhatAmI; fn get_callback(&self) -> Option>; fn get_links(&self) -> Vec; + fn get_auth_ids(&self) -> Vec; #[cfg(feature = "shared-memory")] fn is_shm(&self) -> bool; fn is_qos(&self) -> bool; diff --git a/io/zenoh-transport/src/unicast/universal/transport.rs b/io/zenoh-transport/src/unicast/universal/transport.rs index 942b723365..9f4a3f5030 100644 --- a/io/zenoh-transport/src/unicast/universal/transport.rs +++ b/io/zenoh-transport/src/unicast/universal/transport.rs @@ -11,6 +11,7 @@ // Contributors: // ZettaScale Zenoh Team, // +use super::super::authentication::AuthId; #[cfg(feature = "stats")] use crate::stats::TransportStats; use crate::{ @@ -30,6 +31,7 @@ use std::sync::{Arc, RwLock}; use std::time::Duration; use zenoh_core::{zasynclock, zcondfeat, zread, zwrite}; use zenoh_link::Link; + use zenoh_protocol::{ core::{Priority, WhatAmI, ZenohId}, network::NetworkMessage, @@ -434,6 +436,13 @@ impl TransportUnicastTrait for TransportUnicastUniversal { zread!(self.links).iter().map(|l| l.link.link()).collect() } + fn get_auth_ids(&self) -> Vec { + //convert local_value to authId?? + zread!(self.links) + .iter() + .map(|l| l.link.link().auth_identifier.into()) + .collect() + } /*************************************/ /* TX */ /*************************************/ diff --git a/zenoh/src/net/routing/interceptor/testing_interceptor.rs b/zenoh/src/net/routing/interceptor/testing_interceptor.rs index 4c81439653..38a9407c80 100644 --- a/zenoh/src/net/routing/interceptor/testing_interceptor.rs +++ b/zenoh/src/net/routing/interceptor/testing_interceptor.rs @@ -1,13 +1,12 @@ use crate::KeyExpr; use std::any::Any; -use zenoh_link::AuthId; +use crate::net::routing::RoutingContext; use zenoh_protocol::network::NetworkMessage; use zenoh_result::ZResult; +use zenoh_transport::unicast::authentication::AuthId; use zenoh_transport::{multicast::TransportMulticast, unicast::TransportUnicast}; -use crate::net::routing::RoutingContext; - use super::{ EgressInterceptor, IngressInterceptor, InterceptorFactory, InterceptorFactoryTrait, InterceptorTrait, @@ -32,12 +31,11 @@ impl InterceptorFactoryTrait for TestInterceptor { &self, transport: &TransportUnicast, ) -> (Option, Option) { - if let Ok(links) = transport.get_links() { - for link in links { - println!("value recevied in interceptor {:?}", link.auth_identifier); + if let Ok(ids) = transport.get_auth_ids() { + for id in ids { + println!("value recevied in interceptor {:?}", id); } } - ( Some(Box::new(IngressTestInterceptor { _auth_id: None })), Some(Box::new(EgressTestInterceptor { _auth_id: None })), From f51276407bd290179a5eb51b54d42dbb70ea9626 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Mon, 25 Mar 2024 18:17:41 +0100 Subject: [PATCH 11/37] adding username authentication --- io/zenoh-link-commons/src/unicast.rs | 27 ------------------- .../src/unicast/authentication.rs | 4 +-- .../src/unicast/establishment/accept.rs | 23 +++++++++++++--- .../src/unicast/establishment/ext/auth/mod.rs | 9 ++++--- .../unicast/establishment/ext/auth/usrpwd.rs | 7 ++--- .../src/unicast/establishment/open.rs | 3 +++ io/zenoh-transport/src/unicast/mod.rs | 2 ++ .../src/unicast/universal/transport.rs | 16 ++++++++--- .../interceptor/testing_interceptor.rs | 13 ++++++++- 9 files changed, 61 insertions(+), 43 deletions(-) diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs index 3722702266..9bc6f18743 100644 --- a/io/zenoh-link-commons/src/unicast.rs +++ b/io/zenoh-link-commons/src/unicast.rs @@ -146,26 +146,6 @@ impl Default for LinkAuthId { } } -// #[derive(Clone, Debug, Serialize, Eq, Hash, PartialEq)] -// pub enum AuthIdType { -// None, -// TlsCommonName, -// Username, -// } - -// #[derive(Clone, Debug, Serialize, Eq, Hash, PartialEq)] - -// pub enum AuthId { -// None, -// TlsCommonName(String), -// Username(String), -// } - -// impl AuthId { -// pub fn builder() -> LinkAuthIdBuilder { -// LinkAuthIdBuilder::new() -// } -// } #[derive(Debug)] pub struct LinkAuthIdBuilder { pub auth_type: LinkAuthType, //HAS to be provided when building @@ -191,13 +171,6 @@ impl LinkAuthIdBuilder { } pub fn auth_value(&mut self, auth_value: Option) -> &mut Self { self.auth_value = auth_value; - // let value = auth_value; - - // match self.auth_type { - // LinkAuthType::None => self.auth_value = LinkAuthId::None, - // LinkAuthType::Tls => self.auth_value = LinkAuthId::TlsCommonName(value), - // LinkAuthType::Quic => self.auth_value = AuthId::Username(value), - // }; self } diff --git a/io/zenoh-transport/src/unicast/authentication.rs b/io/zenoh-transport/src/unicast/authentication.rs index ee38a23faa..fb48d8603f 100644 --- a/io/zenoh-transport/src/unicast/authentication.rs +++ b/io/zenoh-transport/src/unicast/authentication.rs @@ -1,9 +1,9 @@ use zenoh_link::{LinkAuthId, LinkAuthType}; -#[derive(Debug)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum AuthId { CertCommonName(String), - Username(String), + Username(Vec), None, } impl From for AuthId { diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 72e676f6ec..c2e4a6280b 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -16,6 +16,7 @@ use crate::unicast::shared_memory_unicast::Challenge; use crate::{ common::batch::BatchConfig, unicast::{ + authentication::AuthId, establishment::{compute_sn, ext, AcceptFsm, Cookie, Zenoh080Cookie}, link::{ LinkUnicastWithOpenAck, TransportLinkUnicast, TransportLinkUnicastConfig, @@ -105,6 +106,7 @@ struct RecvOpenSynOut { other_whatami: WhatAmI, other_lease: Duration, other_initial_sn: TransportSn, + other_auth_id: crate::unicast::authentication::AuthId, } // OpenAck @@ -468,11 +470,17 @@ impl<'a, 'b: 'a> AcceptFsm for &'a mut AcceptLink<'b> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Auth + let mut auth_id = AuthId::None; + #[cfg(feature = "transport_auth")] - self.ext_auth - .recv_open_syn((&mut state.link.ext_auth, open_syn.ext_auth)) - .await - .map_err(|e| (e, Some(close::reason::GENERIC)))?; + { + let inner_auth_id = self + .ext_auth + .recv_open_syn((&mut state.link.ext_auth, open_syn.ext_auth)) + .await + .map_err(|e| (e, Some(close::reason::GENERIC)))?; + auth_id = inner_auth_id; + } // Extension MultiLink #[cfg(feature = "transport_multilink")] @@ -499,6 +507,7 @@ impl<'a, 'b: 'a> AcceptFsm for &'a mut AcceptLink<'b> { other_whatami: cookie.whatami, other_lease: open_syn.lease, other_initial_sn: open_syn.initial_sn, + other_auth_id: auth_id, }; Ok((state, output)) } @@ -587,6 +596,7 @@ impl<'a, 'b: 'a> AcceptFsm for &'a mut AcceptLink<'b> { } pub(crate) async fn accept_link(link: LinkUnicast, manager: &TransportManager) -> ZResult<()> { + println!("accept link is called"); let mtu = link.get_mtu(); let is_streamed = link.is_streamed(); let config = TransportLinkUnicastConfig { @@ -688,6 +698,10 @@ pub(crate) async fn accept_link(link: LinkUnicast, manager: &TransportManager) - }; let (mut state, osyn_out) = step!(fsm.recv_open_syn(osyn_in).await); + println!( + "output of opensyn validation is {:?}", + osyn_out.other_auth_id + ); // Create the OpenAck but not send it yet let oack_in = SendOpenAckIn { mine_zid: manager.config.zid, @@ -708,6 +722,7 @@ pub(crate) async fn accept_link(link: LinkUnicast, manager: &TransportManager) - #[cfg(feature = "shared-memory")] is_shm: state.transport.ext_shm.is_shm(), is_lowlatency: state.transport.ext_lowlatency.is_lowlatency(), + auth_id: osyn_out.other_auth_id, }; let a_config = TransportLinkUnicastConfig { diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs index 99a11ee3a9..3837006572 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs @@ -16,6 +16,7 @@ pub(crate) mod pubkey; #[cfg(feature = "auth_usrpwd")] pub(crate) mod usrpwd; +use crate::unicast::authentication::AuthId; use crate::unicast::establishment::{AcceptFsm, OpenFsm}; use async_std::sync::{Mutex, RwLock}; use async_trait::async_trait; @@ -573,12 +574,13 @@ impl<'a> AcceptFsm for &'a AuthFsm<'a> { } type RecvOpenSynIn = (&'a mut StateAccept, Option); - type RecvOpenSynOut = (); + type RecvOpenSynOut = AuthId; async fn recv_open_syn( self, input: Self::RecvOpenSynIn, ) -> Result { const S: &str = "Auth extension - Recv OpenSyn."; + let mut auth_id = AuthId::None; let (state, ext) = input; let ext = ext.unwrap_or(init::ext::Auth::new(ZBuf::empty())); @@ -606,14 +608,15 @@ impl<'a> AcceptFsm for &'a AuthFsm<'a> { match (self.usrpwd.as_ref(), state.usrpwd.as_mut()) { (Some(e), Some(s)) => { let x = ztake!(exts, id::USRPWD); - e.recv_open_syn((s, ztryinto!(x, S))).await?; + let username = e.recv_open_syn((s, ztryinto!(x, S))).await?; + auth_id = AuthId::Username(username); } (None, None) => {} _ => bail!("{S} Invalid UsrPwd configuration."), } } - Ok(()) + Ok(auth_id) } type SendOpenAckIn = &'a StateAccept; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs index 5cbe122edd..e8e285f529 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs @@ -159,6 +159,7 @@ impl StateOpen { pub(crate) struct StateAccept { nonce: u64, } +pub(crate) struct Username(Vec); impl StateAccept { pub(crate) fn new(prng: &mut R) -> Self @@ -403,7 +404,7 @@ impl<'a> AcceptFsm for &'a AuthUsrPwdFsm<'a> { } type RecvOpenSynIn = (&'a mut StateAccept, Option); - type RecvOpenSynOut = (); + type RecvOpenSynOut = Vec; //value of userid is returned if recvopensynout is processed as valid async fn recv_open_syn( self, input: Self::RecvOpenSynIn, @@ -433,8 +434,8 @@ impl<'a> AcceptFsm for &'a AuthUsrPwdFsm<'a> { if hmac != open_syn.hmac { bail!("{S} Invalid password."); } - - Ok(()) + let username = open_syn.user.to_owned(); + Ok(username) } type SendOpenAckIn = &'a StateAccept; diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index c3f1bfbb8a..79cd6ce586 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -16,6 +16,7 @@ use crate::unicast::shared_memory_unicast::Challenge; use crate::{ common::batch::BatchConfig, unicast::{ + authentication::AuthId, establishment::{compute_sn, ext, OpenFsm}, link::{ LinkUnicastWithOpenAck, TransportLinkUnicast, TransportLinkUnicastConfig, @@ -621,6 +622,8 @@ pub(crate) async fn open_link( #[cfg(feature = "shared-memory")] is_shm: state.transport.ext_shm.is_shm(), is_lowlatency: state.transport.ext_lowlatency.is_lowlatency(), + #[cfg(feature = "transport_auth")] + auth_id: AuthId::None, }; let o_config = TransportLinkUnicastConfig { diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index da99331b32..e2a34ac9d0 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -56,6 +56,8 @@ pub(crate) struct TransportConfigUnicast { #[cfg(feature = "shared-memory")] pub(crate) is_shm: bool, pub(crate) is_lowlatency: bool, + #[cfg(feature = "transport_auth")] + pub(crate) auth_id: AuthId, } /// [`TransportUnicast`] is the transport handler returned diff --git a/io/zenoh-transport/src/unicast/universal/transport.rs b/io/zenoh-transport/src/unicast/universal/transport.rs index 9f4a3f5030..4244c2f411 100644 --- a/io/zenoh-transport/src/unicast/universal/transport.rs +++ b/io/zenoh-transport/src/unicast/universal/transport.rs @@ -84,6 +84,8 @@ pub(crate) struct TransportUnicastUniversal { // Transport statistics #[cfg(feature = "stats")] pub(super) stats: Arc, + // #[cfg(feature = "transport_auth")] + // pub(super) transport_auth_id: Arc, } impl TransportUnicastUniversal { @@ -128,6 +130,8 @@ impl TransportUnicastUniversal { alive: Arc::new(AsyncMutex::new(false)), #[cfg(feature = "stats")] stats, + // #[cfg(feature = "transport_auth")] + // transport_auth_id: Arc::new(AuthId::None), }); Ok(t) @@ -437,11 +441,17 @@ impl TransportUnicastTrait for TransportUnicastUniversal { } fn get_auth_ids(&self) -> Vec { - //convert local_value to authId?? - zread!(self.links) + //convert link auth ids to authId + #[allow(unused_mut)] + let mut auth_ids: Vec = zread!(self.links) .iter() .map(|l| l.link.link().auth_identifier.into()) - .collect() + .collect(); + // convert transport auth ids to authId + #[cfg(feature = "transport_auth")] + auth_ids.push(self.config.auth_id.clone()); + // auth_ids.push((*self.transport_auth_id).clone()); + auth_ids } /*************************************/ /* TX */ diff --git a/zenoh/src/net/routing/interceptor/testing_interceptor.rs b/zenoh/src/net/routing/interceptor/testing_interceptor.rs index 38a9407c80..4a8be11403 100644 --- a/zenoh/src/net/routing/interceptor/testing_interceptor.rs +++ b/zenoh/src/net/routing/interceptor/testing_interceptor.rs @@ -31,9 +31,20 @@ impl InterceptorFactoryTrait for TestInterceptor { &self, transport: &TransportUnicast, ) -> (Option, Option) { + //transport.get_zid() if let Ok(ids) = transport.get_auth_ids() { for id in ids { - println!("value recevied in interceptor {:?}", id); + match id { + AuthId::CertCommonName(name) => { + println!("certificate common name {}", name) + } + AuthId::Username(name) => { + println!("user name {}", std::str::from_utf8(&name).unwrap()) + } + AuthId::None => { + println!("No id was found, switch to interface values"); + } + } } } ( From 8d048f4403430841453c4efb9df2ca5a234dad64 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Tue, 26 Mar 2024 11:23:04 +0100 Subject: [PATCH 12/37] cleaning code --- .gitignore | 8 ++------ io/zenoh-transport/src/unicast/establishment/accept.rs | 6 +++--- .../src/unicast/establishment/ext/auth/usrpwd.rs | 2 ++ io/zenoh-transport/src/unicast/establishment/open.rs | 1 + zenoh/src/net/routing/interceptor/testing_interceptor.rs | 4 +++- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 9240486e57..26b9c6592c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,9 +21,5 @@ cargo-timing*.html -# remove secret files - -*.pem -*.crt -*.key -*.json5 \ No newline at end of file +#ignore test data +tests \ No newline at end of file diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index c2e4a6280b..a31ed1af50 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -470,16 +470,16 @@ impl<'a, 'b: 'a> AcceptFsm for &'a mut AcceptLink<'b> { .map_err(|e| (e, Some(close::reason::GENERIC)))?; // Extension Auth + #[allow(unused_mut, unused_assignments)] let mut auth_id = AuthId::None; #[cfg(feature = "transport_auth")] { - let inner_auth_id = self + auth_id = self .ext_auth .recv_open_syn((&mut state.link.ext_auth, open_syn.ext_auth)) .await .map_err(|e| (e, Some(close::reason::GENERIC)))?; - auth_id = inner_auth_id; } // Extension MultiLink @@ -596,7 +596,6 @@ impl<'a, 'b: 'a> AcceptFsm for &'a mut AcceptLink<'b> { } pub(crate) async fn accept_link(link: LinkUnicast, manager: &TransportManager) -> ZResult<()> { - println!("accept link is called"); let mtu = link.get_mtu(); let is_streamed = link.is_streamed(); let config = TransportLinkUnicastConfig { @@ -722,6 +721,7 @@ pub(crate) async fn accept_link(link: LinkUnicast, manager: &TransportManager) - #[cfg(feature = "shared-memory")] is_shm: state.transport.ext_shm.is_shm(), is_lowlatency: state.transport.ext_lowlatency.is_lowlatency(), + #[cfg(feature = "transport_auth")] auth_id: osyn_out.other_auth_id, }; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs index e8e285f529..010bdbbb77 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs @@ -159,6 +159,8 @@ impl StateOpen { pub(crate) struct StateAccept { nonce: u64, } + +#[allow(dead_code)] pub(crate) struct Username(Vec); impl StateAccept { diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index 79cd6ce586..af5cdc6301 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -13,6 +13,7 @@ // #[cfg(feature = "shared-memory")] use crate::unicast::shared_memory_unicast::Challenge; +#[allow(unused_imports)] use crate::{ common::batch::BatchConfig, unicast::{ diff --git a/zenoh/src/net/routing/interceptor/testing_interceptor.rs b/zenoh/src/net/routing/interceptor/testing_interceptor.rs index 4a8be11403..3210ed3792 100644 --- a/zenoh/src/net/routing/interceptor/testing_interceptor.rs +++ b/zenoh/src/net/routing/interceptor/testing_interceptor.rs @@ -32,11 +32,13 @@ impl InterceptorFactoryTrait for TestInterceptor { transport: &TransportUnicast, ) -> (Option, Option) { //transport.get_zid() + let mut subject_name = vec![]; if let Ok(ids) = transport.get_auth_ids() { for id in ids { match id { AuthId::CertCommonName(name) => { - println!("certificate common name {}", name) + println!("certificate common name {}", name); + subject_name.push("name"); } AuthId::Username(name) => { println!("user name {}", std::str::from_utf8(&name).unwrap()) From 8ed23615cc0eb0840d1c5edf9552bcc2d0fcffc4 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Wed, 27 Mar 2024 12:50:27 +0100 Subject: [PATCH 13/37] added cfg checks for auth_usrpwd --- .../src/unicast/authentication.rs | 24 ++++++++++++++++++- .../src/unicast/establishment/accept.rs | 21 ++++++++-------- .../src/unicast/establishment/ext/auth/mod.rs | 12 ++++++---- .../unicast/establishment/ext/auth/usrpwd.rs | 3 ++- .../src/unicast/establishment/open.rs | 6 +++-- io/zenoh-transport/src/unicast/mod.rs | 6 +++-- .../src/unicast/universal/transport.rs | 13 ++++------ .../interceptor/testing_interceptor.rs | 4 ++-- 8 files changed, 56 insertions(+), 33 deletions(-) diff --git a/io/zenoh-transport/src/unicast/authentication.rs b/io/zenoh-transport/src/unicast/authentication.rs index fb48d8603f..4018a7dcd6 100644 --- a/io/zenoh-transport/src/unicast/authentication.rs +++ b/io/zenoh-transport/src/unicast/authentication.rs @@ -1,9 +1,11 @@ +#[cfg(feature = "auth_usrpwd")] +use super::establishment::ext::auth::UsrPwdId; use zenoh_link::{LinkAuthId, LinkAuthType}; #[derive(Clone, Debug, PartialEq, Eq)] pub enum AuthId { CertCommonName(String), - Username(Vec), + Username(String), None, } impl From for AuthId { @@ -16,3 +18,23 @@ impl From for AuthId { } } } +#[cfg(feature = "auth_usrpwd")] +impl From for AuthId { + fn from(user_password_id: UsrPwdId) -> Self { + // pub(crate) struct UsrPwdId(pub Option>); + match user_password_id.0 { + Some(username) => { + //do something + //convert username from vecu8 to string + match std::str::from_utf8(&username) { + Ok(name) => AuthId::Username(name.to_owned()), + Err(e) => { + log::error!("Error in extracting username {}", e); + AuthId::None + } + } + } + None => AuthId::None, + } + } +} diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index a31ed1af50..af73ed3bb7 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -11,12 +11,13 @@ // Contributors: // ZettaScale Zenoh Team, // +#[cfg(feature = "auth_usrpwd")] +use super::ext::auth::UsrPwdId; #[cfg(feature = "shared-memory")] use crate::unicast::shared_memory_unicast::Challenge; use crate::{ common::batch::BatchConfig, unicast::{ - authentication::AuthId, establishment::{compute_sn, ext, AcceptFsm, Cookie, Zenoh080Cookie}, link::{ LinkUnicastWithOpenAck, TransportLinkUnicast, TransportLinkUnicastConfig, @@ -106,7 +107,8 @@ struct RecvOpenSynOut { other_whatami: WhatAmI, other_lease: Duration, other_initial_sn: TransportSn, - other_auth_id: crate::unicast::authentication::AuthId, + #[cfg(feature = "auth_usrpwd")] + other_auth_id: UsrPwdId, } // OpenAck @@ -471,11 +473,12 @@ impl<'a, 'b: 'a> AcceptFsm for &'a mut AcceptLink<'b> { // Extension Auth #[allow(unused_mut, unused_assignments)] - let mut auth_id = AuthId::None; + #[cfg(feature = "auth_usrpwd")] + let mut user_pawssword_id = UsrPwdId(None); #[cfg(feature = "transport_auth")] { - auth_id = self + user_pawssword_id = self .ext_auth .recv_open_syn((&mut state.link.ext_auth, open_syn.ext_auth)) .await @@ -507,7 +510,8 @@ impl<'a, 'b: 'a> AcceptFsm for &'a mut AcceptLink<'b> { other_whatami: cookie.whatami, other_lease: open_syn.lease, other_initial_sn: open_syn.initial_sn, - other_auth_id: auth_id, + #[cfg(feature = "transport_auth")] + other_auth_id: user_pawssword_id, }; Ok((state, output)) } @@ -696,11 +700,6 @@ pub(crate) async fn accept_link(link: LinkUnicast, manager: &TransportManager) - cookie_nonce: iack_out.cookie_nonce, }; let (mut state, osyn_out) = step!(fsm.recv_open_syn(osyn_in).await); - - println!( - "output of opensyn validation is {:?}", - osyn_out.other_auth_id - ); // Create the OpenAck but not send it yet let oack_in = SendOpenAckIn { mine_zid: manager.config.zid, @@ -721,7 +720,7 @@ pub(crate) async fn accept_link(link: LinkUnicast, manager: &TransportManager) - #[cfg(feature = "shared-memory")] is_shm: state.transport.ext_shm.is_shm(), is_lowlatency: state.transport.ext_lowlatency.is_lowlatency(), - #[cfg(feature = "transport_auth")] + #[cfg(feature = "auth_usrpwd")] auth_id: osyn_out.other_auth_id, }; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs index 3837006572..ef5e418dcb 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs @@ -16,7 +16,6 @@ pub(crate) mod pubkey; #[cfg(feature = "auth_usrpwd")] pub(crate) mod usrpwd; -use crate::unicast::authentication::AuthId; use crate::unicast::establishment::{AcceptFsm, OpenFsm}; use async_std::sync::{Mutex, RwLock}; use async_trait::async_trait; @@ -574,13 +573,16 @@ impl<'a> AcceptFsm for &'a AuthFsm<'a> { } type RecvOpenSynIn = (&'a mut StateAccept, Option); - type RecvOpenSynOut = AuthId; + #[cfg(feature = "auth_usrpwd")] + + type RecvOpenSynOut = UsrPwdId; async fn recv_open_syn( self, input: Self::RecvOpenSynIn, ) -> Result { const S: &str = "Auth extension - Recv OpenSyn."; - let mut auth_id = AuthId::None; + #[cfg(feature = "transport_auth")] + let mut user_passwd_id = UsrPwdId(None); let (state, ext) = input; let ext = ext.unwrap_or(init::ext::Auth::new(ZBuf::empty())); @@ -609,14 +611,14 @@ impl<'a> AcceptFsm for &'a AuthFsm<'a> { (Some(e), Some(s)) => { let x = ztake!(exts, id::USRPWD); let username = e.recv_open_syn((s, ztryinto!(x, S))).await?; - auth_id = AuthId::Username(username); + user_passwd_id = UsrPwdId(Some(username)); } (None, None) => {} _ => bail!("{S} Invalid UsrPwd configuration."), } } - Ok(auth_id) + Ok(user_passwd_id) } type SendOpenAckIn = &'a StateAccept; diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs index 010bdbbb77..a78dd43415 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs @@ -161,7 +161,8 @@ pub(crate) struct StateAccept { } #[allow(dead_code)] -pub(crate) struct Username(Vec); +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) struct UsrPwdId(pub Option>); impl StateAccept { pub(crate) fn new(prng: &mut R) -> Self diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index af5cdc6301..604cc203d2 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -1,3 +1,5 @@ +#[cfg(feature = "auth_usrpwd")] +use crate::unicast::establishment::ext::auth::UsrPwdId; // // Copyright (c) 2022 ZettaScale Technology // @@ -623,8 +625,8 @@ pub(crate) async fn open_link( #[cfg(feature = "shared-memory")] is_shm: state.transport.ext_shm.is_shm(), is_lowlatency: state.transport.ext_lowlatency.is_lowlatency(), - #[cfg(feature = "transport_auth")] - auth_id: AuthId::None, + #[cfg(feature = "auth_usrpwd")] + auth_id: UsrPwdId(None), }; let o_config = TransportLinkUnicastConfig { diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index e2a34ac9d0..1615463f0a 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -25,6 +25,8 @@ pub(crate) mod universal; pub(crate) mod shared_memory_unicast; use self::authentication::AuthId; +#[cfg(feature = "auth_usrpwd")] +use self::establishment::ext::auth::UsrPwdId; use self::transport_unicast_inner::TransportUnicastTrait; use super::{TransportPeer, TransportPeerEventHandler}; #[cfg(feature = "transport_multilink")] @@ -56,8 +58,8 @@ pub(crate) struct TransportConfigUnicast { #[cfg(feature = "shared-memory")] pub(crate) is_shm: bool, pub(crate) is_lowlatency: bool, - #[cfg(feature = "transport_auth")] - pub(crate) auth_id: AuthId, + #[cfg(feature = "auth_usrpwd")] + pub(crate) auth_id: UsrPwdId, } /// [`TransportUnicast`] is the transport handler returned diff --git a/io/zenoh-transport/src/unicast/universal/transport.rs b/io/zenoh-transport/src/unicast/universal/transport.rs index 4244c2f411..5318a4afe5 100644 --- a/io/zenoh-transport/src/unicast/universal/transport.rs +++ b/io/zenoh-transport/src/unicast/universal/transport.rs @@ -84,8 +84,6 @@ pub(crate) struct TransportUnicastUniversal { // Transport statistics #[cfg(feature = "stats")] pub(super) stats: Arc, - // #[cfg(feature = "transport_auth")] - // pub(super) transport_auth_id: Arc, } impl TransportUnicastUniversal { @@ -130,8 +128,6 @@ impl TransportUnicastUniversal { alive: Arc::new(AsyncMutex::new(false)), #[cfg(feature = "stats")] stats, - // #[cfg(feature = "transport_auth")] - // transport_auth_id: Arc::new(AuthId::None), }); Ok(t) @@ -441,16 +437,15 @@ impl TransportUnicastTrait for TransportUnicastUniversal { } fn get_auth_ids(&self) -> Vec { - //convert link auth ids to authId + //convert link level auth ids to AuthId #[allow(unused_mut)] let mut auth_ids: Vec = zread!(self.links) .iter() .map(|l| l.link.link().auth_identifier.into()) .collect(); - // convert transport auth ids to authId - #[cfg(feature = "transport_auth")] - auth_ids.push(self.config.auth_id.clone()); - // auth_ids.push((*self.transport_auth_id).clone()); + // convert usrpwd auth id to AuthId + #[cfg(feature = "auth_usrpwd")] + auth_ids.push(self.config.auth_id.clone().into()); auth_ids } /*************************************/ diff --git a/zenoh/src/net/routing/interceptor/testing_interceptor.rs b/zenoh/src/net/routing/interceptor/testing_interceptor.rs index 3210ed3792..cb6bfe5a4c 100644 --- a/zenoh/src/net/routing/interceptor/testing_interceptor.rs +++ b/zenoh/src/net/routing/interceptor/testing_interceptor.rs @@ -31,7 +31,7 @@ impl InterceptorFactoryTrait for TestInterceptor { &self, transport: &TransportUnicast, ) -> (Option, Option) { - //transport.get_zid() + //build a subject map here let mut subject_name = vec![]; if let Ok(ids) = transport.get_auth_ids() { for id in ids { @@ -41,7 +41,7 @@ impl InterceptorFactoryTrait for TestInterceptor { subject_name.push("name"); } AuthId::Username(name) => { - println!("user name {}", std::str::from_utf8(&name).unwrap()) + println!("user name {}", name) } AuthId::None => { println!("No id was found, switch to interface values"); From 29760c00629b0a872f97db7b73e852e027d4d55c Mon Sep 17 00:00:00 2001 From: snehilzs Date: Wed, 13 Mar 2024 12:01:01 +0100 Subject: [PATCH 14/37] adding test files --- ca.crt | 21 +++ myserver.crt | 22 +++ myserver.key | 28 +++ pub_client.json5 | 431 +++++++++++++++++++++++++++++++++++++++++++++++ router.json5 | 431 +++++++++++++++++++++++++++++++++++++++++++++++ sub_client.json5 | 431 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 1364 insertions(+) create mode 100644 ca.crt create mode 100644 myserver.crt create mode 100644 myserver.key create mode 100644 pub_client.json5 create mode 100644 router.json5 create mode 100644 sub_client.json5 diff --git a/ca.crt b/ca.crt new file mode 100644 index 0000000000..50b4d876ca --- /dev/null +++ b/ca.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUO1x6LAlICgKs5+pYUTo4CughfKEwDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTExNDM0MjNaFw0yNTAzMTExNDM0MjNaMFQxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRgwFgYDVQQDDA96 +c190ZXN0X3Jvb3RfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3 +pFWM+IJNsRCYHt1v/TliecppwVZV+ZHfFw9JKN9ev4K/fWHUiAOwp91MOLxbaYKd +C6dxW28YVGltoGz3kUZJZcJRQVso1jXv24Op4muOsiYXukLc4TU2F6dG1XqkLt5t +svsYAQFf1uK3//QZFVRBosJEn+jjiJ4XCvt49mnPRolp1pNKX0z31mZO6bSly6c9 +OVlJMjWpDCYSOuf6qZZ36fa9eSut2bRJIPY0QCsgnqYBTnIEhksS+3jy6Qt+QpLz +95pFdLbW/MW4XKpaDltyYkO6QrBekF6uWRlvyAHU+NqvXZ4F/3Z5l26qLuBcsLPJ +kyawkO+yNIDxORmQgMczAgMBAAGjUzBRMB0GA1UdDgQWBBThgotd9ws2ryEEaKp2 ++RMOWV8D7jAfBgNVHSMEGDAWgBThgotd9ws2ryEEaKp2+RMOWV8D7jAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA9QoPv78hGmvmqF4GZeqrOBKQB +N/H5wL7f8H6BXU/wpNo2nnWOJn3u37lT+zivAdGEv+x+GeKekcugKBCSluhBLpVb +VNXe4WwMm5FBuO2NRBN2nblTMm1kEO00nVk1/yNo4hI8mj7d4YLU62d7324osNpF +wHqu6B0/c99JeKRvODGswyff1i8rJ1jpcgk/JmHg7UQBHEIkn0cRR0f9W3Mxv6b5 +ZeowRe81neWNkC6IMiMmzA0iHGkhoUMA15qG1ZKOr1XR364LH5BfNNpzAWYwkvJs +0JFrrdw+rm+cRJWs55yiyCCs7pyg1IJkY/o8bifdCOUgIyonzffwREk3+kZR +-----END CERTIFICATE----- diff --git a/myserver.crt b/myserver.crt new file mode 100644 index 0000000000..a68071aa18 --- /dev/null +++ b/myserver.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDmDCCAoCgAwIBAgIUFMs3tKqT0Cvz3r0aSN9KSVPCsfkwDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTExNDQ0MzZaFw0yNTAzMTExNDQ0MzZaMFQxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRgwFgYDVQQDDA90 +ZXN0X3Rsc19zZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCh +86dsAI7FzJxhKykW5uzHuz9NGbmzq8G9ndUdIwTHYmawTTgr3NCBAYEF1+iOo6y9 +8yUUsTyN3bqx3biFVQHWVP6iHI7WPBazFOZOyyjc3gcRD6M5LVPBIc5Ar+zcKNzL +b8ZTW4G1T4fye5XXPS+Zu2IHjIBAPoXQVhKZjWfmpPmloF+hphF5l8L7ilDfsj3o +1qo88XzGVUjkR5fF5UE/6iuiiipXsLRtEvsYSYMvvLuKWGN+e0t3JwvfH0JnAURK +/KKOixhqnbGcnrwVY1bzgFo3u9NSQjjYREvu6QBEthuLtPkc+PCR+DxjBmdh1der +7Bwwnfa3AgKbbtoZhlkPAgMBAAGjYjBgMB4GA1UdEQQXMBWCE25ld190ZXN0X3Rs +c19zZXJ2ZXIwHQYDVR0OBBYEFG2WT0EOXqPY2QiWTxtb/detOQUDMB8GA1UdIwQY +MBaAFOGCi133CzavIQRoqnb5Ew5ZXwPuMA0GCSqGSIb3DQEBCwUAA4IBAQBKvVh0 +uzdlPkGrkU56hVOvNe2QqKXHbz0xRVeNn/rXItUnV3YbzuiNpyjkHGPBMsDtgri2 +YUf0dKfVr8+Zyr0Yc/Nhbe2gWezGMnoOo9dw6An0r4vSYmJdSaO/s5hH7/orHQxS +zCRN+6iwURT6r1quJDxJLcsA6nzOvLdQnMxTKcak/V6A7eBpoUINdFVNhvPoXMDd +PVaju1U00SEbun8Qgeh/yWz4CPQYgQqKUORkPf0ToK5V3jrbIuW9VfQi8VcOzCn9 +YPihAEzkhh+PG8FYwK3vc6u2qKNlcbEuMu6rOQTUDWAi6+PJY5ClHQYdnb4/ThjT +vcP3w3j3YhSd/9iA +-----END CERTIFICATE----- diff --git a/myserver.key b/myserver.key new file mode 100644 index 0000000000..3cad67bdc9 --- /dev/null +++ b/myserver.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCh86dsAI7FzJxh +KykW5uzHuz9NGbmzq8G9ndUdIwTHYmawTTgr3NCBAYEF1+iOo6y98yUUsTyN3bqx +3biFVQHWVP6iHI7WPBazFOZOyyjc3gcRD6M5LVPBIc5Ar+zcKNzLb8ZTW4G1T4fy +e5XXPS+Zu2IHjIBAPoXQVhKZjWfmpPmloF+hphF5l8L7ilDfsj3o1qo88XzGVUjk +R5fF5UE/6iuiiipXsLRtEvsYSYMvvLuKWGN+e0t3JwvfH0JnAURK/KKOixhqnbGc +nrwVY1bzgFo3u9NSQjjYREvu6QBEthuLtPkc+PCR+DxjBmdh1der7Bwwnfa3AgKb +btoZhlkPAgMBAAECggEAP5vQA8L6UKUrPJzzoAumL1KTq8gxYGjTCRMvS6jf7SHw +fElwCQZLHIhHMVDahf+yTs7rnwN36a6Pb+HKYg//zzuF4Y0+6tUiA0dvp73yuEE6 +XFCchs4PSdlpxY1zhgtEoWCu8DmOKfTpS+uPcEEXa5WmDJn6G4GTFD9iQc5A410D +oBf0ONw7X8nE1ZBZr6dpJBdsP68pRJC8BfhTH/dS3d4I4JYb2BgLER1ZbMqfFeW/ +sAZ3FKKETdYvCgLb380/Xpb08FRAHlQ1MowEpfe2sNBqsnkHjESExMIP8Ne7O+ts +9IUIGHZkKIl9u/B/RHCve8Db3GM9F/lMjJ9p84FEXQKBgQDTzYX+9FyAZt5NGPwW +5mTqlh5EHLZzgnVGo2DySu0Zi7MN/YYKV1wAT3i6cTATMjjdSYu2u6L1VYhfIYYq +43MIcsHe7XMAQxbQ6l6oULUa77huMzC0Js0l08kV/ERkH0/nUS9JRp5FJUKR7mkH +Am2dz040MceQMITzCewwskf+jQKBgQDDvxgxBTNJYF3tN3uNLBPRcib0Kk+p2LfW +oDv43++MiyqkTejJJqMDHtYsXNivH6T7CE2U0Qf+2MonAzoVnNsEAfonS19okn8c +LqkMlTZmiT9Tld+h+pcAsf7lYYXSuZv10lgXSN2nj8LBm/EM130ShzyrM58vCGRC +/fDPu9ZNCwKBgQCnuWdVILlnzQ5ZS2HF2Kktw7cwBPTOwA6S46pP9NmRkzk16QAO +jGOEs2pNanjBmtHBGw6SpEBFu3gErY2LxRZBKG8yVCLvoDEfO5m9/DuOmysXyV3W +K6vlOrNQv7aA+vLRoU6q3ktTQlBXM87kCB46DAJH/uuj2WhO9hqd7XBpuQKBgFCG +/9vCyOuJ0noxVgmotWp3rKDL+0PjXRXVi3aCIZlO8zbuujJuS6eP+wn7FEVPHl8L +dmcfa0ujQd60zCNyCQPoEFI0BscNZW9hnrgHdn7OPZgUUxDe91oY38TbzuL26rtB +Um4Z0t4JHVTq40qmJ9UEf6fqr7T4nc6Vi4jaPHorAoGAL1hVy8oYAKtJCTlRQalw +apM3ZJUlTK7qfkjajPEvmhuHntplHDkGEe5ZROUu3zluDiS7MHzOYtunitoMaZbG +cRMO34aDO/UXoLdUWabuk81e3/AWgs6wHVFBOpRAYKAQzigrmXanMclwiL0V5T9K +IgP5i6aUi4zduiV1YLHj4UA= +-----END PRIVATE KEY----- diff --git a/pub_client.json5 b/pub_client.json5 new file mode 100644 index 0000000000..b75f75fa16 --- /dev/null +++ b/pub_client.json5 @@ -0,0 +1,431 @@ +/// This file attempts to list and document available configuration elements. +/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. +/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. +{ + /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) + /// that zenoh runtime will use. + /// If not set, a random unsigned 128bit integer will be used. + /// WARNING: this id must be unique in your zenoh network. + // id: "1234567890abcdef", + /// The node's mode (router, peer or client) + mode: "client", + /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ + metadata: { + name: "strawberry", + location: "Penny Lane" + }, + /// Which endpoints to connect to. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: + /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 + connect: { + endpoints: [ + // "/
" + "quic/127.0.0.1:7447" + + ], + }, + /// Which endpoints to listen on. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, + /// peers, or client can use to establish a zenoh session. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: + /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 + listen: { + endpoints: [ + // "/
" + ], + }, + /// Configure the scouting mechanisms and their behaviours + scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 3000, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 200, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: true, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: true, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: true, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + /// Configuration of data messages timestamps management. + timestamping: { + /// Whether data messages should be timestamped if not already. + /// Accepts a single boolean value or different values for router, peer and client. + enabled: { router: true, peer: false, client: false + }, + /// Whether data messages with timestamps in the future should be dropped or not. + /// If set to false (default), messages with timestamps in the future are retimestamped. + /// Timestamps are ignored if timestamping is disabled. + drop_future_timestamp: false, + }, + /// The default timeout to apply to queries in milliseconds. + queries_default_timeout: 10000, + /// The routing strategy to use and it's configuration. + routing: { + /// The routing strategy to use in routers and it's configuration. + router: { + /// When set to true a router will forward data between two peers + /// directly connected to it if it detects that those peers are not + /// connected to each other. + /// The failover brokering only works if gossip discovery is enabled. + peers_failover_brokering: true, + }, + /// The routing strategy to use in peers and it's configuration. + peer: { + /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). + mode: "peer_to_peer", + }, + }, + // /// The declarations aggregation strategy. + // aggregation: { + // /// A list of key-expressions for which all included subscribers will be aggregated into. + // subscribers: [ + // // key_expression + // ], + // /// A list of key-expressions for which all included publishers will be aggregated into. + // publishers: [ + // // key_expression + // ], + // }, + // /// The downsampling declaration. + // downsampling: [ + // { + // /// A list of network interfaces messages will be processed on, the rest will be passed as is. + // interfaces: [ "wlan0" ], + // /// Data flow messages will be processed on. ("egress" or "ingress") + // flow: "egress", + // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz + // rules: [ + // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, + // ], + // }, + // ], + /// Configure internal transport parameters + transport: { + unicast: { + /// Timeout in milliseconds when opening a link + accept_timeout: 10000, + /// Maximum number of zenoh session in pending state while accepting + accept_pending: 100, + /// Maximum number of sessions that can be simultaneously alive + max_sessions: 1000, + /// Maximum number of incoming links that are admitted per session + max_links: 1, + /// Enables the LowLatency transport + /// This option does not make LowLatency transport mandatory, the actual implementation of transport + /// used will depend on Establish procedure and other party's settings + /// + /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. + /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to + /// enable 'lowlatency' you need to explicitly disable 'qos'. + lowlatency: false, + /// Enables QoS on unicast communications. + qos: { + enabled: true, + }, + /// Enables compression on unicast communications. + /// Compression capabilities are negotiated during session establishment. + /// If both Zenoh nodes support compression, then compression is activated. + compression: { + enabled: false, + }, + }, + multicast: { + /// Enables QoS on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + qos: { + enabled: false, + }, + /// Enables compression on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + compression: { + enabled: false, + }, + }, + link: { + /// An optional whitelist of protocols to be used for accepting and opening sessions. + /// If not configured, all the supported protocols are automatically whitelisted. + /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + /// For example, to only enable "tls" and "quic": + // protocols: ["tls", "quic"], + /// Configure the zenoh TX parameters of a link + tx: { + /// The resolution in bits to be used for the message sequence numbers. + /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: "32bit", + /// Link lease duration in milliseconds to announce to other zenoh nodes + lease: 10000, + /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive + /// messages will be sent at the configured time interval. + /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, + /// set the actual keep_alive timeout to one fourth of the lease time. + /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity + /// check which considers a link as failed when no messages are received in 3.5 times the + /// target interval. + keep_alive: 4, + /// Batch size in bytes is expressed as a 16bit unsigned integer. + /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). + /// The default batch size value is the maximum batch size: 65535. + batch_size: 65535, + /// Each zenoh link has a transmission queue that can be configured + queue: { + /// The size of each priority queue indicates the number of batches a given queue can contain. + /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. + /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, + /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. + /// If qos is false, then only the DATA priority will be allocated. + size: { + control: 1, + real_time: 1, + interactive_high: 1, + interactive_low: 1, + data_high: 2, + data: 4, + data_low: 4, + background: 4, + }, + /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. + /// Higher values lead to a more aggressive batching but it will introduce additional latency. + backoff: 100, + }, + // Number of threads dedicated to transmission + // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) + // threads: 4, + }, + /// Configure the zenoh RX parameters of a link + rx: { + /// Receiving buffer size in bytes for each link + /// The default the rx_buffer_size value is the same as the default batch size: 65335. + /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate + /// more in-flight data. This is particularly relevant when dealing with large messages. + /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. + buffer_size: 65535, + /// Maximum size of the defragmentation buffer at receiver end. + /// Fragmented messages that are larger than the configured size will be dropped. + /// The default value is 1GiB. This would work in most scenarios. + /// NOTE: reduce the value if you are operating on a memory constrained device. + max_message_size: 1073741824, + }, + /// Configure TLS specific parameters + tls: { + root_ca_certificate: "ca.crt" + } + // tls: { + // /// Path to the certificate of the certificate authority used to validate either the server + // /// or the client's keys and certificates, depending on the node's mode. If not specified + // /// on router mode then the default WebPKI certificates are used instead. + // root_ca_certificate: null, + // /// Path to the TLS server private key + // server_private_key: null, + // /// Path to the TLS server public certificate + // server_certificate: null, + // /// Client authentication, if true enables mTLS (mutual authentication) + // client_auth: false, + // /// Path to the TLS client private key + // client_private_key: null, + // /// Path to the TLS client public certificate + // client_certificate: null, + // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + // server_name_verification: null, + // }, + }, + /// Shared memory configuration + shared_memory: { + enabled: false, + }, + /// Access control configuration + auth: { + /// The configuration of authentification. + /// A password implies a username is required. + usrpwd: { + user: null, + password: null, + /// The path to a file containing the user password dictionary + dictionary_file: null, + }, + pubkey: { + public_key_pem: null, + private_key_pem: null, + public_key_file: null, + private_key_file: null, + key_size: null, + known_keys_file: null, + }, + }, + }, + /// Configure the Admin Space + /// Unstable: this configuration part works as advertised, but may change in a future release + adminspace: { + // read and/or write permissions on the admin space + permissions: { + read: true, + write: false, + }, + }, + /// + /// Plugins configurations + /// + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // plugins_search_dirs: [], + // /// Plugins are only loaded if present in the configuration. When starting + // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. + // plugins: { + // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) + // + // /// Plugin settings may contain field `__config__` + // /// - If `__config__` is specified, it's content is merged into plugin configuration + // /// - Properties loaded from `__config__` file overrides existing properties + // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively + // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config + // /// + // /// See below exapmle of plugin configuration using `__config__` property + // + // /// Configure the REST API plugin + // rest: { + // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. + // __required__: true, // defaults to false + // /// load configuration from the file + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // /// http port to answer to rest requests + // http_port: 8000, + // }, + // + // /// Configure the storage manager plugin + // storage_manager: { + // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. + // __path__: [ + // "./target/release/libzenoh_plugin_storage_manager.so", + // "./target/release/libzenoh_plugin_storage_manager.dylib", + // ], + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // backend_search_dirs: [], + // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. + // volumes: { + // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb + // influxdb: { + // url: "https://myinfluxdb.example", + // /// Some plugins may need passwords in their configuration. + // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. + // /// any value held at the key "private" will not be shown in the adminspace. + // private: { + // username: "user1", + // password: "pw1", + // }, + // }, + // influxdb2: { + // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. + // backend: "influxdb", + // private: { + // username: "user2", + // password: "pw2", + // }, + // url: "https://localhost:8086", + // }, + // }, + // + // /// Configure the storages supported by the volumes + // storages: { + // demo: { + // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. + // key_expr: "demo/memory/**", + // /// Storages also need to know which volume will be used to actually store their key-value pairs. + // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. + // volume: "memory", + // }, + // demo2: { + // key_expr: "demo/memory2/**", + // volume: "memory", + // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. + // /// Metadata includes the set of wild card updates and deletions (tombstones). + // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. + // garbage_collection: { + // /// The garbage collection event will be periodic with this duration. + // /// The duration is specified in seconds. + // period: 30, + // /// Metadata older than this parameter will be garbage collected. + // /// The duration is specified in seconds. + // lifespan: 86400, + // }, + // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. + // /// In the absence of this configuration, a normal storage is initialized + // /// Note: all the samples to be stored in replicas should be timestamped + // replica_config: { + // /// Specifying the parameters is optional, by default the values provided will be used. + // /// Time interval between different synchronization attempts in seconds + // publication_interval: 5, + // /// Expected propagation delay of the network in milliseconds + // propagation_delay: 200, + // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. + // /// Higher the frequency of updates, lower the delta should be chosen + // /// To be efficient, delta should be the time containing no more than 100,000 samples + // delta: 1000, + // } + // }, + // demo3: { + // key_expr: "demo/memory3/**", + // volume: "memory", + // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. + // /// If not configured, complete defaults to false. + // complete: "true", + // }, + // influx_demo: { + // key_expr: "demo/influxdb/**", + // /// This prefix will be stripped of the received keys when storing. + // strip_prefix: "demo/influxdb", + // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: + // volume: { + // id: "influxdb", + // db: "example", + // }, + // }, + // influx_demo2: { + // key_expr: "demo/influxdb2/**", + // strip_prefix: "demo/influxdb2", + // volume: { + // id: "influxdb2", + // db: "example", + // }, + // }, + // }, + // }, + // }, + // /// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // } + // }, +} \ No newline at end of file diff --git a/router.json5 b/router.json5 new file mode 100644 index 0000000000..46817ee4b4 --- /dev/null +++ b/router.json5 @@ -0,0 +1,431 @@ +/// This file attempts to list and document available configuration elements. +/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. +/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. +{ + /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) + /// that zenoh runtime will use. + /// If not set, a random unsigned 128bit integer will be used. + /// WARNING: this id must be unique in your zenoh network. + // id: "1234567890abcdef", + /// The node's mode (router, peer or client) + mode: "router", + /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ + metadata: { + name: "strawberry", + location: "Penny Lane" + }, + /// Which endpoints to connect to. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: + /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 + connect: { + endpoints: [ + // "/
" + ], + }, + /// Which endpoints to listen on. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, + /// peers, or client can use to establish a zenoh session. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: + /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 + listen: { + endpoints: [ + // "/
" + "quic/127.0.0.1:7447" + ], + }, + /// Configure the scouting mechanisms and their behaviours + scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 3000, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 200, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: true, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: true, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: true, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + /// Configuration of data messages timestamps management. + timestamping: { + /// Whether data messages should be timestamped if not already. + /// Accepts a single boolean value or different values for router, peer and client. + enabled: { router: true, peer: false, client: false + }, + /// Whether data messages with timestamps in the future should be dropped or not. + /// If set to false (default), messages with timestamps in the future are retimestamped. + /// Timestamps are ignored if timestamping is disabled. + drop_future_timestamp: false, + }, + /// The default timeout to apply to queries in milliseconds. + queries_default_timeout: 10000, + /// The routing strategy to use and it's configuration. + routing: { + /// The routing strategy to use in routers and it's configuration. + router: { + /// When set to true a router will forward data between two peers + /// directly connected to it if it detects that those peers are not + /// connected to each other. + /// The failover brokering only works if gossip discovery is enabled. + peers_failover_brokering: true, + }, + /// The routing strategy to use in peers and it's configuration. + peer: { + /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). + mode: "peer_to_peer", + }, + }, + // /// The declarations aggregation strategy. + // aggregation: { + // /// A list of key-expressions for which all included subscribers will be aggregated into. + // subscribers: [ + // // key_expression + // ], + // /// A list of key-expressions for which all included publishers will be aggregated into. + // publishers: [ + // // key_expression + // ], + // }, + // /// The downsampling declaration. + // downsampling: [ + // { + // /// A list of network interfaces messages will be processed on, the rest will be passed as is. + // interfaces: [ "wlan0" ], + // /// Data flow messages will be processed on. ("egress" or "ingress") + // flow: "egress", + // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz + // rules: [ + // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, + // ], + // }, + // ], + /// Configure internal transport parameters + transport: { + unicast: { + /// Timeout in milliseconds when opening a link + accept_timeout: 10000, + /// Maximum number of zenoh session in pending state while accepting + accept_pending: 100, + /// Maximum number of sessions that can be simultaneously alive + max_sessions: 1000, + /// Maximum number of incoming links that are admitted per session + max_links: 1, + /// Enables the LowLatency transport + /// This option does not make LowLatency transport mandatory, the actual implementation of transport + /// used will depend on Establish procedure and other party's settings + /// + /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. + /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to + /// enable 'lowlatency' you need to explicitly disable 'qos'. + lowlatency: false, + /// Enables QoS on unicast communications. + qos: { + enabled: true, + }, + /// Enables compression on unicast communications. + /// Compression capabilities are negotiated during session establishment. + /// If both Zenoh nodes support compression, then compression is activated. + compression: { + enabled: false, + }, + }, + multicast: { + /// Enables QoS on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + qos: { + enabled: false, + }, + /// Enables compression on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + compression: { + enabled: false, + }, + }, + link: { + /// An optional whitelist of protocols to be used for accepting and opening sessions. + /// If not configured, all the supported protocols are automatically whitelisted. + /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + /// For example, to only enable "tls" and "quic": + // protocols: ["tls", "quic"], + /// Configure the zenoh TX parameters of a link + tx: { + /// The resolution in bits to be used for the message sequence numbers. + /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: "32bit", + /// Link lease duration in milliseconds to announce to other zenoh nodes + lease: 10000, + /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive + /// messages will be sent at the configured time interval. + /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, + /// set the actual keep_alive timeout to one fourth of the lease time. + /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity + /// check which considers a link as failed when no messages are received in 3.5 times the + /// target interval. + keep_alive: 4, + /// Batch size in bytes is expressed as a 16bit unsigned integer. + /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). + /// The default batch size value is the maximum batch size: 65535. + batch_size: 65535, + /// Each zenoh link has a transmission queue that can be configured + queue: { + /// The size of each priority queue indicates the number of batches a given queue can contain. + /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. + /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, + /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. + /// If qos is false, then only the DATA priority will be allocated. + size: { + control: 1, + real_time: 1, + interactive_high: 1, + interactive_low: 1, + data_high: 2, + data: 4, + data_low: 4, + background: 4, + }, + /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. + /// Higher values lead to a more aggressive batching but it will introduce additional latency. + backoff: 100, + }, + // Number of threads dedicated to transmission + // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) + // threads: 4, + }, + /// Configure the zenoh RX parameters of a link + rx: { + /// Receiving buffer size in bytes for each link + /// The default the rx_buffer_size value is the same as the default batch size: 65335. + /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate + /// more in-flight data. This is particularly relevant when dealing with large messages. + /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. + buffer_size: 65535, + /// Maximum size of the defragmentation buffer at receiver end. + /// Fragmented messages that are larger than the configured size will be dropped. + /// The default value is 1GiB. This would work in most scenarios. + /// NOTE: reduce the value if you are operating on a memory constrained device. + max_message_size: 1073741824, + }, + /// Configure TLS specific parameters + tls: { + server_private_key: "myserver.key", + server_certificate: "myserver.crt" + } + // tls: { + // /// Path to the certificate of the certificate authority used to validate either the server + // /// or the client's keys and certificates, depending on the node's mode. If not specified + // /// on router mode then the default WebPKI certificates are used instead. + // root_ca_certificate: null, + // /// Path to the TLS server private key + // server_private_key: null, + // /// Path to the TLS server public certificate + // server_certificate: null, + // /// Client authentication, if true enables mTLS (mutual authentication) + // client_auth: false, + // /// Path to the TLS client private key + // client_private_key: null, + // /// Path to the TLS client public certificate + // client_certificate: null, + // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + // server_name_verification: null, + // }, + }, + /// Shared memory configuration + shared_memory: { + enabled: false, + }, + /// Access control configuration + auth: { + /// The configuration of authentication. + /// A password implies a username is required. + usrpwd: { + user: null, + password: null, + /// The path to a file containing the user password dictionary + dictionary_file: null, + }, + pubkey: { + public_key_pem: null, + private_key_pem: null, + public_key_file: null, + private_key_file: null, + key_size: null, + known_keys_file: null, + }, + }, + }, + /// Configure the Admin Space + /// Unstable: this configuration part works as advertised, but may change in a future release + adminspace: { + // read and/or write permissions on the admin space + permissions: { + read: true, + write: false, + }, + }, + /// + /// Plugins configurations + /// + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // plugins_search_dirs: [], + // /// Plugins are only loaded if present in the configuration. When starting + // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. + // plugins: { + // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) + // + // /// Plugin settings may contain field `__config__` + // /// - If `__config__` is specified, it's content is merged into plugin configuration + // /// - Properties loaded from `__config__` file overrides existing properties + // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively + // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config + // /// + // /// See below exapmle of plugin configuration using `__config__` property + // + // /// Configure the REST API plugin + // rest: { + // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. + // __required__: true, // defaults to false + // /// load configuration from the file + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // /// http port to answer to rest requests + // http_port: 8000, + // }, + // + // /// Configure the storage manager plugin + // storage_manager: { + // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. + // __path__: [ + // "./target/release/libzenoh_plugin_storage_manager.so", + // "./target/release/libzenoh_plugin_storage_manager.dylib", + // ], + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // backend_search_dirs: [], + // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. + // volumes: { + // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb + // influxdb: { + // url: "https://myinfluxdb.example", + // /// Some plugins may need passwords in their configuration. + // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. + // /// any value held at the key "private" will not be shown in the adminspace. + // private: { + // username: "user1", + // password: "pw1", + // }, + // }, + // influxdb2: { + // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. + // backend: "influxdb", + // private: { + // username: "user2", + // password: "pw2", + // }, + // url: "https://localhost:8086", + // }, + // }, + // + // /// Configure the storages supported by the volumes + // storages: { + // demo: { + // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. + // key_expr: "demo/memory/**", + // /// Storages also need to know which volume will be used to actually store their key-value pairs. + // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. + // volume: "memory", + // }, + // demo2: { + // key_expr: "demo/memory2/**", + // volume: "memory", + // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. + // /// Metadata includes the set of wild card updates and deletions (tombstones). + // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. + // garbage_collection: { + // /// The garbage collection event will be periodic with this duration. + // /// The duration is specified in seconds. + // period: 30, + // /// Metadata older than this parameter will be garbage collected. + // /// The duration is specified in seconds. + // lifespan: 86400, + // }, + // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. + // /// In the absence of this configuration, a normal storage is initialized + // /// Note: all the samples to be stored in replicas should be timestamped + // replica_config: { + // /// Specifying the parameters is optional, by default the values provided will be used. + // /// Time interval between different synchronization attempts in seconds + // publication_interval: 5, + // /// Expected propagation delay of the network in milliseconds + // propagation_delay: 200, + // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. + // /// Higher the frequency of updates, lower the delta should be chosen + // /// To be efficient, delta should be the time containing no more than 100,000 samples + // delta: 1000, + // } + // }, + // demo3: { + // key_expr: "demo/memory3/**", + // volume: "memory", + // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. + // /// If not configured, complete defaults to false. + // complete: "true", + // }, + // influx_demo: { + // key_expr: "demo/influxdb/**", + // /// This prefix will be stripped of the received keys when storing. + // strip_prefix: "demo/influxdb", + // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: + // volume: { + // id: "influxdb", + // db: "example", + // }, + // }, + // influx_demo2: { + // key_expr: "demo/influxdb2/**", + // strip_prefix: "demo/influxdb2", + // volume: { + // id: "influxdb2", + // db: "example", + // }, + // }, + // }, + // }, + // }, + // /// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // } + // }, +} \ No newline at end of file diff --git a/sub_client.json5 b/sub_client.json5 new file mode 100644 index 0000000000..b75f75fa16 --- /dev/null +++ b/sub_client.json5 @@ -0,0 +1,431 @@ +/// This file attempts to list and document available configuration elements. +/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. +/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. +{ + /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) + /// that zenoh runtime will use. + /// If not set, a random unsigned 128bit integer will be used. + /// WARNING: this id must be unique in your zenoh network. + // id: "1234567890abcdef", + /// The node's mode (router, peer or client) + mode: "client", + /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ + metadata: { + name: "strawberry", + location: "Penny Lane" + }, + /// Which endpoints to connect to. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: + /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 + connect: { + endpoints: [ + // "/
" + "quic/127.0.0.1:7447" + + ], + }, + /// Which endpoints to listen on. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, + /// peers, or client can use to establish a zenoh session. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: + /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 + listen: { + endpoints: [ + // "/
" + ], + }, + /// Configure the scouting mechanisms and their behaviours + scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 3000, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 200, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: true, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: true, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: true, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + /// Configuration of data messages timestamps management. + timestamping: { + /// Whether data messages should be timestamped if not already. + /// Accepts a single boolean value or different values for router, peer and client. + enabled: { router: true, peer: false, client: false + }, + /// Whether data messages with timestamps in the future should be dropped or not. + /// If set to false (default), messages with timestamps in the future are retimestamped. + /// Timestamps are ignored if timestamping is disabled. + drop_future_timestamp: false, + }, + /// The default timeout to apply to queries in milliseconds. + queries_default_timeout: 10000, + /// The routing strategy to use and it's configuration. + routing: { + /// The routing strategy to use in routers and it's configuration. + router: { + /// When set to true a router will forward data between two peers + /// directly connected to it if it detects that those peers are not + /// connected to each other. + /// The failover brokering only works if gossip discovery is enabled. + peers_failover_brokering: true, + }, + /// The routing strategy to use in peers and it's configuration. + peer: { + /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). + mode: "peer_to_peer", + }, + }, + // /// The declarations aggregation strategy. + // aggregation: { + // /// A list of key-expressions for which all included subscribers will be aggregated into. + // subscribers: [ + // // key_expression + // ], + // /// A list of key-expressions for which all included publishers will be aggregated into. + // publishers: [ + // // key_expression + // ], + // }, + // /// The downsampling declaration. + // downsampling: [ + // { + // /// A list of network interfaces messages will be processed on, the rest will be passed as is. + // interfaces: [ "wlan0" ], + // /// Data flow messages will be processed on. ("egress" or "ingress") + // flow: "egress", + // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz + // rules: [ + // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, + // ], + // }, + // ], + /// Configure internal transport parameters + transport: { + unicast: { + /// Timeout in milliseconds when opening a link + accept_timeout: 10000, + /// Maximum number of zenoh session in pending state while accepting + accept_pending: 100, + /// Maximum number of sessions that can be simultaneously alive + max_sessions: 1000, + /// Maximum number of incoming links that are admitted per session + max_links: 1, + /// Enables the LowLatency transport + /// This option does not make LowLatency transport mandatory, the actual implementation of transport + /// used will depend on Establish procedure and other party's settings + /// + /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. + /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to + /// enable 'lowlatency' you need to explicitly disable 'qos'. + lowlatency: false, + /// Enables QoS on unicast communications. + qos: { + enabled: true, + }, + /// Enables compression on unicast communications. + /// Compression capabilities are negotiated during session establishment. + /// If both Zenoh nodes support compression, then compression is activated. + compression: { + enabled: false, + }, + }, + multicast: { + /// Enables QoS on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + qos: { + enabled: false, + }, + /// Enables compression on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + compression: { + enabled: false, + }, + }, + link: { + /// An optional whitelist of protocols to be used for accepting and opening sessions. + /// If not configured, all the supported protocols are automatically whitelisted. + /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + /// For example, to only enable "tls" and "quic": + // protocols: ["tls", "quic"], + /// Configure the zenoh TX parameters of a link + tx: { + /// The resolution in bits to be used for the message sequence numbers. + /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: "32bit", + /// Link lease duration in milliseconds to announce to other zenoh nodes + lease: 10000, + /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive + /// messages will be sent at the configured time interval. + /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, + /// set the actual keep_alive timeout to one fourth of the lease time. + /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity + /// check which considers a link as failed when no messages are received in 3.5 times the + /// target interval. + keep_alive: 4, + /// Batch size in bytes is expressed as a 16bit unsigned integer. + /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). + /// The default batch size value is the maximum batch size: 65535. + batch_size: 65535, + /// Each zenoh link has a transmission queue that can be configured + queue: { + /// The size of each priority queue indicates the number of batches a given queue can contain. + /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. + /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, + /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. + /// If qos is false, then only the DATA priority will be allocated. + size: { + control: 1, + real_time: 1, + interactive_high: 1, + interactive_low: 1, + data_high: 2, + data: 4, + data_low: 4, + background: 4, + }, + /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. + /// Higher values lead to a more aggressive batching but it will introduce additional latency. + backoff: 100, + }, + // Number of threads dedicated to transmission + // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) + // threads: 4, + }, + /// Configure the zenoh RX parameters of a link + rx: { + /// Receiving buffer size in bytes for each link + /// The default the rx_buffer_size value is the same as the default batch size: 65335. + /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate + /// more in-flight data. This is particularly relevant when dealing with large messages. + /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. + buffer_size: 65535, + /// Maximum size of the defragmentation buffer at receiver end. + /// Fragmented messages that are larger than the configured size will be dropped. + /// The default value is 1GiB. This would work in most scenarios. + /// NOTE: reduce the value if you are operating on a memory constrained device. + max_message_size: 1073741824, + }, + /// Configure TLS specific parameters + tls: { + root_ca_certificate: "ca.crt" + } + // tls: { + // /// Path to the certificate of the certificate authority used to validate either the server + // /// or the client's keys and certificates, depending on the node's mode. If not specified + // /// on router mode then the default WebPKI certificates are used instead. + // root_ca_certificate: null, + // /// Path to the TLS server private key + // server_private_key: null, + // /// Path to the TLS server public certificate + // server_certificate: null, + // /// Client authentication, if true enables mTLS (mutual authentication) + // client_auth: false, + // /// Path to the TLS client private key + // client_private_key: null, + // /// Path to the TLS client public certificate + // client_certificate: null, + // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + // server_name_verification: null, + // }, + }, + /// Shared memory configuration + shared_memory: { + enabled: false, + }, + /// Access control configuration + auth: { + /// The configuration of authentification. + /// A password implies a username is required. + usrpwd: { + user: null, + password: null, + /// The path to a file containing the user password dictionary + dictionary_file: null, + }, + pubkey: { + public_key_pem: null, + private_key_pem: null, + public_key_file: null, + private_key_file: null, + key_size: null, + known_keys_file: null, + }, + }, + }, + /// Configure the Admin Space + /// Unstable: this configuration part works as advertised, but may change in a future release + adminspace: { + // read and/or write permissions on the admin space + permissions: { + read: true, + write: false, + }, + }, + /// + /// Plugins configurations + /// + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // plugins_search_dirs: [], + // /// Plugins are only loaded if present in the configuration. When starting + // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. + // plugins: { + // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) + // + // /// Plugin settings may contain field `__config__` + // /// - If `__config__` is specified, it's content is merged into plugin configuration + // /// - Properties loaded from `__config__` file overrides existing properties + // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively + // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config + // /// + // /// See below exapmle of plugin configuration using `__config__` property + // + // /// Configure the REST API plugin + // rest: { + // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. + // __required__: true, // defaults to false + // /// load configuration from the file + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // /// http port to answer to rest requests + // http_port: 8000, + // }, + // + // /// Configure the storage manager plugin + // storage_manager: { + // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. + // __path__: [ + // "./target/release/libzenoh_plugin_storage_manager.so", + // "./target/release/libzenoh_plugin_storage_manager.dylib", + // ], + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // backend_search_dirs: [], + // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. + // volumes: { + // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb + // influxdb: { + // url: "https://myinfluxdb.example", + // /// Some plugins may need passwords in their configuration. + // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. + // /// any value held at the key "private" will not be shown in the adminspace. + // private: { + // username: "user1", + // password: "pw1", + // }, + // }, + // influxdb2: { + // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. + // backend: "influxdb", + // private: { + // username: "user2", + // password: "pw2", + // }, + // url: "https://localhost:8086", + // }, + // }, + // + // /// Configure the storages supported by the volumes + // storages: { + // demo: { + // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. + // key_expr: "demo/memory/**", + // /// Storages also need to know which volume will be used to actually store their key-value pairs. + // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. + // volume: "memory", + // }, + // demo2: { + // key_expr: "demo/memory2/**", + // volume: "memory", + // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. + // /// Metadata includes the set of wild card updates and deletions (tombstones). + // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. + // garbage_collection: { + // /// The garbage collection event will be periodic with this duration. + // /// The duration is specified in seconds. + // period: 30, + // /// Metadata older than this parameter will be garbage collected. + // /// The duration is specified in seconds. + // lifespan: 86400, + // }, + // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. + // /// In the absence of this configuration, a normal storage is initialized + // /// Note: all the samples to be stored in replicas should be timestamped + // replica_config: { + // /// Specifying the parameters is optional, by default the values provided will be used. + // /// Time interval between different synchronization attempts in seconds + // publication_interval: 5, + // /// Expected propagation delay of the network in milliseconds + // propagation_delay: 200, + // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. + // /// Higher the frequency of updates, lower the delta should be chosen + // /// To be efficient, delta should be the time containing no more than 100,000 samples + // delta: 1000, + // } + // }, + // demo3: { + // key_expr: "demo/memory3/**", + // volume: "memory", + // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. + // /// If not configured, complete defaults to false. + // complete: "true", + // }, + // influx_demo: { + // key_expr: "demo/influxdb/**", + // /// This prefix will be stripped of the received keys when storing. + // strip_prefix: "demo/influxdb", + // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: + // volume: { + // id: "influxdb", + // db: "example", + // }, + // }, + // influx_demo2: { + // key_expr: "demo/influxdb2/**", + // strip_prefix: "demo/influxdb2", + // volume: { + // id: "influxdb2", + // db: "example", + // }, + // }, + // }, + // }, + // }, + // /// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // } + // }, +} \ No newline at end of file From 39ec2bf5198df950c923f4ea822990644b5d13e3 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Mon, 22 Apr 2024 18:36:03 +0200 Subject: [PATCH 15/37] fix error due to vsock --- io/zenoh-links/zenoh-link-vsock/src/unicast.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/io/zenoh-links/zenoh-link-vsock/src/unicast.rs b/io/zenoh-links/zenoh-link-vsock/src/unicast.rs index 2700fcf04d..13bc579138 100644 --- a/io/zenoh-links/zenoh-link-vsock/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-vsock/src/unicast.rs @@ -188,6 +188,10 @@ impl LinkUnicastTrait for LinkUnicastVsock { fn is_streamed(&self) -> bool { true } + #[inline(always)] + fn get_auth_identifier(&self) -> LinkAuthId { + LinkAuthId::default() + } } impl fmt::Display for LinkUnicastVsock { From e43aa77ef5d8fe47036e866202bb1b2959a3b51e Mon Sep 17 00:00:00 2001 From: snehilzs Date: Tue, 23 Apr 2024 11:36:55 +0200 Subject: [PATCH 16/37] fix test error --- io/zenoh-links/zenoh-link-vsock/src/unicast.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/io/zenoh-links/zenoh-link-vsock/src/unicast.rs b/io/zenoh-links/zenoh-link-vsock/src/unicast.rs index 13bc579138..807ad63dde 100644 --- a/io/zenoh-links/zenoh-link-vsock/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-vsock/src/unicast.rs @@ -24,6 +24,7 @@ use tokio::sync::RwLock as AsyncRwLock; use tokio::task::JoinHandle; use tokio_util::sync::CancellationToken; use zenoh_core::{zasyncread, zasyncwrite}; +use zenoh_link_commons::LinkAuthId; use zenoh_link_commons::{ LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; From 0b6b80f4218101db98e0e177dfba13282536f7c2 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Thu, 25 Apr 2024 09:06:07 +0200 Subject: [PATCH 17/37] access auth ids in acl interceptor --- commons/zenoh-config/src/lib.rs | 2 + .../net/routing/interceptor/access_control.rs | 33 +++++++ zenoh/src/net/routing/interceptor/mod.rs | 3 - .../interceptor/testing_interceptor.rs | 98 ------------------- 4 files changed, 35 insertions(+), 101 deletions(-) delete mode 100644 zenoh/src/net/routing/interceptor/testing_interceptor.rs diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index 00ba5bca73..112419cec4 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -123,6 +123,8 @@ pub struct PolicyRule { #[serde(rename_all = "snake_case")] pub enum Subject { Interface(String), + CertCommonName(String), + Username(String), } #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, Hash, PartialEq)] diff --git a/zenoh/src/net/routing/interceptor/access_control.rs b/zenoh/src/net/routing/interceptor/access_control.rs index 1b0876160a..ddaa4d8d72 100644 --- a/zenoh/src/net/routing/interceptor/access_control.rs +++ b/zenoh/src/net/routing/interceptor/access_control.rs @@ -31,6 +31,8 @@ use zenoh_protocol::{ network::{Declare, DeclareBody, NetworkBody, NetworkMessage, Push, Request}, zenoh::{PushBody, RequestBody}, }; +use zenoh_transport::unicast::authentication::AuthId; + use zenoh_result::ZResult; use zenoh_transport::{multicast::TransportMulticast, unicast::TransportUnicast}; pub struct AclEnforcer { @@ -44,11 +46,13 @@ pub struct Interface { struct EgressAclEnforcer { policy_enforcer: Arc, interface_list: Vec, + auth_ids: Vec, zid: ZenohId, } struct IngressAclEnforcer { policy_enforcer: Arc, interface_list: Vec, + auth_ids: Vec, zid: ZenohId, } @@ -80,6 +84,23 @@ impl InterceptorFactoryTrait for AclEnforcer { &self, transport: &TransportUnicast, ) -> (Option, Option) { + let mut auth_ids = vec![]; + if let Ok(ids) = transport.get_auth_ids() { + auth_ids = ids.clone(); + // for id in ids { + // match id { + // AuthId::CertCommonName(name) => { + // println!("certificate common name {}", name); + // } + // AuthId::Username(name) => { + // println!("user name {}", name); + // } + // AuthId::None => { + // println!("No id was found, will use interface values"); + // } + // } + // } + } match transport.get_zid() { Ok(zid) => { let mut interface_list: Vec = Vec::new(); @@ -107,11 +128,13 @@ impl InterceptorFactoryTrait for AclEnforcer { policy_enforcer: self.enforcer.clone(), interface_list: interface_list.clone(), zid, + auth_ids: auth_ids.clone(), }); let egress_interceptor = Box::new(EgressAclEnforcer { policy_enforcer: self.enforcer.clone(), interface_list: interface_list.clone(), zid, + auth_ids, }); match ( self.enforcer.interface_enabled.ingress, @@ -285,9 +308,12 @@ pub trait AclActionMethods { fn interface_list(&self) -> Vec; fn zid(&self) -> ZenohId; fn flow(&self) -> InterceptorFlow; + fn auth_ids(&self) -> Vec; fn action(&self, action: Action, log_msg: &str, key_expr: &str) -> Permission { let policy_enforcer = self.policy_enforcer(); let interface_list = self.interface_list(); + let auth_ids = self.auth_ids(); + println!("auth_ids are : {:?}", auth_ids); let zid = self.zid(); let mut decision = policy_enforcer.default_permission; for subject in &interface_list { @@ -347,6 +373,10 @@ impl AclActionMethods for EgressAclEnforcer { fn flow(&self) -> InterceptorFlow { InterceptorFlow::Egress } + + fn auth_ids(&self) -> Vec { + self.auth_ids.clone() + } } impl AclActionMethods for IngressAclEnforcer { @@ -364,4 +394,7 @@ impl AclActionMethods for IngressAclEnforcer { fn flow(&self) -> InterceptorFlow { InterceptorFlow::Ingress } + fn auth_ids(&self) -> Vec { + self.auth_ids.clone() + } } diff --git a/zenoh/src/net/routing/interceptor/mod.rs b/zenoh/src/net/routing/interceptor/mod.rs index 1ba14c7d8d..ef8e6e0fb1 100644 --- a/zenoh/src/net/routing/interceptor/mod.rs +++ b/zenoh/src/net/routing/interceptor/mod.rs @@ -32,9 +32,7 @@ use zenoh_result::ZResult; use zenoh_transport::{multicast::TransportMulticast, unicast::TransportUnicast}; pub mod downsampling; -pub mod testing_interceptor; use crate::net::routing::interceptor::downsampling::downsampling_interceptor_factories; -use crate::net::routing::interceptor::testing_interceptor::new_test_interceptor; pub(crate) trait InterceptorTrait { fn compute_keyexpr_cache(&self, key_expr: &KeyExpr<'_>) -> Option>; @@ -67,7 +65,6 @@ pub(crate) fn interceptor_factories(config: &Config) -> ZResult, -} -struct IngressTestInterceptor { - _auth_id: Option, -} - -pub(crate) fn new_test_interceptor() -> ZResult> { - let res: Vec = vec![Box::new(TestInterceptor {})]; - Ok(res) -} - -impl InterceptorFactoryTrait for TestInterceptor { - fn new_transport_unicast( - &self, - transport: &TransportUnicast, - ) -> (Option, Option) { - //build a subject map here - let mut subject_name = vec![]; - if let Ok(ids) = transport.get_auth_ids() { - for id in ids { - match id { - AuthId::CertCommonName(name) => { - println!("certificate common name {}", name); - subject_name.push("name"); - } - AuthId::Username(name) => { - println!("user name {}", name) - } - AuthId::None => { - println!("No id was found, switch to interface values"); - } - } - } - } - ( - Some(Box::new(IngressTestInterceptor { _auth_id: None })), - Some(Box::new(EgressTestInterceptor { _auth_id: None })), - ) - } - - fn new_transport_multicast( - &self, - _transport: &TransportMulticast, - ) -> Option { - None - } - - fn new_peer_multicast(&self, _transport: &TransportMulticast) -> Option { - None - } -} - -impl InterceptorTrait for IngressTestInterceptor { - fn compute_keyexpr_cache(&self, key_expr: &KeyExpr<'_>) -> Option> { - let _ = key_expr; - None - } - fn intercept<'a>( - &self, - ctx: RoutingContext, - cache: Option<&Box>, - ) -> Option> { - let _ = cache; - Some(ctx) - } -} - -impl InterceptorTrait for EgressTestInterceptor { - fn compute_keyexpr_cache(&self, key_expr: &KeyExpr<'_>) -> Option> { - let _ = key_expr; - None - } - fn intercept<'a>( - &self, - ctx: RoutingContext, - cache: Option<&Box>, - ) -> Option> { - let _ = cache; - Some(ctx) - } -} From 427733b93db02e4588bcac5b9ecd739d9321a347 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Thu, 25 Apr 2024 10:14:15 +0200 Subject: [PATCH 18/37] add authentication support in acl --- commons/zenoh-config/src/lib.rs | 4 +- .../net/routing/interceptor/access_control.rs | 80 ++++++++----------- .../net/routing/interceptor/authorization.rs | 46 ++++++++--- 3 files changed, 71 insertions(+), 59 deletions(-) diff --git a/commons/zenoh-config/src/lib.rs b/commons/zenoh-config/src/lib.rs index 112419cec4..3e9277a368 100644 --- a/commons/zenoh-config/src/lib.rs +++ b/commons/zenoh-config/src/lib.rs @@ -102,7 +102,9 @@ pub struct DownsamplingItemConf { #[derive(Serialize, Debug, Deserialize, Clone)] pub struct AclConfigRules { - pub interfaces: Vec, + pub interfaces: Option>, + pub cert_common_names: Option>, + pub usernames: Option>, pub key_exprs: Vec, pub actions: Vec, pub flows: Vec, diff --git a/zenoh/src/net/routing/interceptor/access_control.rs b/zenoh/src/net/routing/interceptor/access_control.rs index ddaa4d8d72..e3edb05e3d 100644 --- a/zenoh/src/net/routing/interceptor/access_control.rs +++ b/zenoh/src/net/routing/interceptor/access_control.rs @@ -39,20 +39,19 @@ pub struct AclEnforcer { enforcer: Arc, } #[derive(Clone, Debug)] -pub struct Interface { +pub struct AuthnSubject { id: usize, name: String, } + struct EgressAclEnforcer { policy_enforcer: Arc, - interface_list: Vec, - auth_ids: Vec, + subject: Vec, zid: ZenohId, } struct IngressAclEnforcer { policy_enforcer: Arc, - interface_list: Vec, - auth_ids: Vec, + subject: Vec, zid: ZenohId, } @@ -84,26 +83,29 @@ impl InterceptorFactoryTrait for AclEnforcer { &self, transport: &TransportUnicast, ) -> (Option, Option) { - let mut auth_ids = vec![]; + let mut authn_ids = vec![]; if let Ok(ids) = transport.get_auth_ids() { - auth_ids = ids.clone(); - // for id in ids { - // match id { - // AuthId::CertCommonName(name) => { - // println!("certificate common name {}", name); - // } - // AuthId::Username(name) => { - // println!("user name {}", name); - // } - // AuthId::None => { - // println!("No id was found, will use interface values"); - // } - // } - // } + let enforcer = self.enforcer.clone(); + for auth_id in ids { + match auth_id { + AuthId::CertCommonName(name) => { + let subject = &Subject::CertCommonName(name.clone()); + if let Some(val) = enforcer.subject_map.get(subject) { + authn_ids.push(AuthnSubject { id: *val, name }); + } + } + AuthId::Username(name) => { + let subject = &Subject::Username(name.clone()); + if let Some(val) = enforcer.subject_map.get(subject) { + authn_ids.push(AuthnSubject { id: *val, name }); + } + } + AuthId::None => {} + } + } } match transport.get_zid() { Ok(zid) => { - let mut interface_list: Vec = Vec::new(); match transport.get_links() { Ok(links) => { for link in links { @@ -111,7 +113,7 @@ impl InterceptorFactoryTrait for AclEnforcer { for face in link.interfaces { let subject = &Subject::Interface(face.clone()); if let Some(val) = enforcer.subject_map.get(subject) { - interface_list.push(Interface { + authn_ids.push(AuthnSubject { id: *val, name: face, }); @@ -126,15 +128,13 @@ impl InterceptorFactoryTrait for AclEnforcer { } let ingress_interceptor = Box::new(IngressAclEnforcer { policy_enforcer: self.enforcer.clone(), - interface_list: interface_list.clone(), zid, - auth_ids: auth_ids.clone(), + subject: authn_ids.clone(), }); let egress_interceptor = Box::new(EgressAclEnforcer { policy_enforcer: self.enforcer.clone(), - interface_list: interface_list.clone(), zid, - auth_ids, + subject: authn_ids, }); match ( self.enforcer.interface_enabled.ingress, @@ -305,18 +305,15 @@ impl InterceptorTrait for EgressAclEnforcer { } pub trait AclActionMethods { fn policy_enforcer(&self) -> Arc; - fn interface_list(&self) -> Vec; fn zid(&self) -> ZenohId; fn flow(&self) -> InterceptorFlow; - fn auth_ids(&self) -> Vec; + fn authn_ids(&self) -> Vec; fn action(&self, action: Action, log_msg: &str, key_expr: &str) -> Permission { let policy_enforcer = self.policy_enforcer(); - let interface_list = self.interface_list(); - let auth_ids = self.auth_ids(); - println!("auth_ids are : {:?}", auth_ids); + let authn_ids: Vec = self.authn_ids(); let zid = self.zid(); let mut decision = policy_enforcer.default_permission; - for subject in &interface_list { + for subject in &authn_ids { match policy_enforcer.policy_decision_point(subject.id, self.flow(), action, key_expr) { Ok(Permission::Allow) => { tracing::trace!( @@ -362,20 +359,14 @@ impl AclActionMethods for EgressAclEnforcer { fn policy_enforcer(&self) -> Arc { self.policy_enforcer.clone() } - - fn interface_list(&self) -> Vec { - self.interface_list.clone() - } - fn zid(&self) -> ZenohId { self.zid } fn flow(&self) -> InterceptorFlow { InterceptorFlow::Egress } - - fn auth_ids(&self) -> Vec { - self.auth_ids.clone() + fn authn_ids(&self) -> Vec { + self.subject.clone() } } @@ -383,18 +374,13 @@ impl AclActionMethods for IngressAclEnforcer { fn policy_enforcer(&self) -> Arc { self.policy_enforcer.clone() } - - fn interface_list(&self) -> Vec { - self.interface_list.clone() - } - fn zid(&self) -> ZenohId { self.zid } fn flow(&self) -> InterceptorFlow { InterceptorFlow::Ingress } - fn auth_ids(&self) -> Vec { - self.auth_ids.clone() + fn authn_ids(&self) -> Vec { + self.subject.clone() } } diff --git a/zenoh/src/net/routing/interceptor/authorization.rs b/zenoh/src/net/routing/interceptor/authorization.rs index 61c1cba217..1f4cb84d2b 100644 --- a/zenoh/src/net/routing/interceptor/authorization.rs +++ b/zenoh/src/net/routing/interceptor/authorization.rs @@ -199,17 +199,41 @@ impl PolicyEnforcer { ) -> ZResult { let mut policy_rules: Vec = Vec::new(); for config_rule in config_rule_set { - for subject in &config_rule.interfaces { - for flow in &config_rule.flows { - for action in &config_rule.actions { - for key_expr in &config_rule.key_exprs { - policy_rules.push(PolicyRule { - subject: Subject::Interface(subject.clone()), - key_expr: key_expr.clone(), - action: *action, - permission: config_rule.permission, - flow: *flow, - }) + for flow in &config_rule.flows { + for action in &config_rule.actions { + for key_expr in &config_rule.key_exprs { + if let Some(interface_list) = config_rule.interfaces.clone() { + for interface_subject in interface_list { + policy_rules.push(PolicyRule { + subject: Subject::Interface(interface_subject.clone()), + key_expr: key_expr.clone(), + action: *action, + permission: config_rule.permission, + flow: *flow, + }); + } + } + if let Some(cert_name_list) = config_rule.cert_common_names.clone() { + for cert_name_subject in cert_name_list { + policy_rules.push(PolicyRule { + subject: Subject::CertCommonName(cert_name_subject.clone()), + key_expr: key_expr.clone(), + action: *action, + permission: config_rule.permission, + flow: *flow, + }); + } + } + if let Some(username_list) = config_rule.usernames.clone() { + for username_subject in username_list { + policy_rules.push(PolicyRule { + subject: Subject::Username(username_subject.clone()), + key_expr: key_expr.clone(), + action: *action, + permission: config_rule.permission, + flow: *flow, + }); + } } } } From 78eacc94329ca246c9f0bbdc1697610cbf3aba32 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Thu, 25 Apr 2024 22:28:02 +0200 Subject: [PATCH 19/37] added Subject --- .../net/routing/interceptor/access_control.rs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/zenoh/src/net/routing/interceptor/access_control.rs b/zenoh/src/net/routing/interceptor/access_control.rs index e3edb05e3d..45929b3364 100644 --- a/zenoh/src/net/routing/interceptor/access_control.rs +++ b/zenoh/src/net/routing/interceptor/access_control.rs @@ -39,19 +39,19 @@ pub struct AclEnforcer { enforcer: Arc, } #[derive(Clone, Debug)] -pub struct AuthnSubject { +pub struct AuthSubject { id: usize, name: String, } struct EgressAclEnforcer { policy_enforcer: Arc, - subject: Vec, + subject: Vec, zid: ZenohId, } struct IngressAclEnforcer { policy_enforcer: Arc, - subject: Vec, + subject: Vec, zid: ZenohId, } @@ -91,13 +91,13 @@ impl InterceptorFactoryTrait for AclEnforcer { AuthId::CertCommonName(name) => { let subject = &Subject::CertCommonName(name.clone()); if let Some(val) = enforcer.subject_map.get(subject) { - authn_ids.push(AuthnSubject { id: *val, name }); + authn_ids.push(AuthSubject { id: *val, name }); } } AuthId::Username(name) => { let subject = &Subject::Username(name.clone()); if let Some(val) = enforcer.subject_map.get(subject) { - authn_ids.push(AuthnSubject { id: *val, name }); + authn_ids.push(AuthSubject { id: *val, name }); } } AuthId::None => {} @@ -113,7 +113,7 @@ impl InterceptorFactoryTrait for AclEnforcer { for face in link.interfaces { let subject = &Subject::Interface(face.clone()); if let Some(val) = enforcer.subject_map.get(subject) { - authn_ids.push(AuthnSubject { + authn_ids.push(AuthSubject { id: *val, name: face, }); @@ -307,10 +307,10 @@ pub trait AclActionMethods { fn policy_enforcer(&self) -> Arc; fn zid(&self) -> ZenohId; fn flow(&self) -> InterceptorFlow; - fn authn_ids(&self) -> Vec; + fn authn_ids(&self) -> Vec; fn action(&self, action: Action, log_msg: &str, key_expr: &str) -> Permission { let policy_enforcer = self.policy_enforcer(); - let authn_ids: Vec = self.authn_ids(); + let authn_ids: Vec = self.authn_ids(); let zid = self.zid(); let mut decision = policy_enforcer.default_permission; for subject in &authn_ids { @@ -365,7 +365,7 @@ impl AclActionMethods for EgressAclEnforcer { fn flow(&self) -> InterceptorFlow { InterceptorFlow::Egress } - fn authn_ids(&self) -> Vec { + fn authn_ids(&self) -> Vec { self.subject.clone() } } @@ -380,7 +380,7 @@ impl AclActionMethods for IngressAclEnforcer { fn flow(&self) -> InterceptorFlow { InterceptorFlow::Ingress } - fn authn_ids(&self) -> Vec { + fn authn_ids(&self) -> Vec { self.subject.clone() } } From 7ba77b6e04546a1910080ed899f1a2cce8ea56e4 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Wed, 13 Mar 2024 12:01:01 +0100 Subject: [PATCH 20/37] adding test files --- ca.crt | 21 +++ myserver.crt | 22 +++ myserver.key | 28 +++ pub_client.json5 | 431 +++++++++++++++++++++++++++++++++++++++++++++++ router.json5 | 431 +++++++++++++++++++++++++++++++++++++++++++++++ sub_client.json5 | 431 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 1364 insertions(+) create mode 100644 ca.crt create mode 100644 myserver.crt create mode 100644 myserver.key create mode 100644 pub_client.json5 create mode 100644 router.json5 create mode 100644 sub_client.json5 diff --git a/ca.crt b/ca.crt new file mode 100644 index 0000000000..50b4d876ca --- /dev/null +++ b/ca.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUO1x6LAlICgKs5+pYUTo4CughfKEwDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTExNDM0MjNaFw0yNTAzMTExNDM0MjNaMFQxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRgwFgYDVQQDDA96 +c190ZXN0X3Jvb3RfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3 +pFWM+IJNsRCYHt1v/TliecppwVZV+ZHfFw9JKN9ev4K/fWHUiAOwp91MOLxbaYKd +C6dxW28YVGltoGz3kUZJZcJRQVso1jXv24Op4muOsiYXukLc4TU2F6dG1XqkLt5t +svsYAQFf1uK3//QZFVRBosJEn+jjiJ4XCvt49mnPRolp1pNKX0z31mZO6bSly6c9 +OVlJMjWpDCYSOuf6qZZ36fa9eSut2bRJIPY0QCsgnqYBTnIEhksS+3jy6Qt+QpLz +95pFdLbW/MW4XKpaDltyYkO6QrBekF6uWRlvyAHU+NqvXZ4F/3Z5l26qLuBcsLPJ +kyawkO+yNIDxORmQgMczAgMBAAGjUzBRMB0GA1UdDgQWBBThgotd9ws2ryEEaKp2 ++RMOWV8D7jAfBgNVHSMEGDAWgBThgotd9ws2ryEEaKp2+RMOWV8D7jAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA9QoPv78hGmvmqF4GZeqrOBKQB +N/H5wL7f8H6BXU/wpNo2nnWOJn3u37lT+zivAdGEv+x+GeKekcugKBCSluhBLpVb +VNXe4WwMm5FBuO2NRBN2nblTMm1kEO00nVk1/yNo4hI8mj7d4YLU62d7324osNpF +wHqu6B0/c99JeKRvODGswyff1i8rJ1jpcgk/JmHg7UQBHEIkn0cRR0f9W3Mxv6b5 +ZeowRe81neWNkC6IMiMmzA0iHGkhoUMA15qG1ZKOr1XR364LH5BfNNpzAWYwkvJs +0JFrrdw+rm+cRJWs55yiyCCs7pyg1IJkY/o8bifdCOUgIyonzffwREk3+kZR +-----END CERTIFICATE----- diff --git a/myserver.crt b/myserver.crt new file mode 100644 index 0000000000..a68071aa18 --- /dev/null +++ b/myserver.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDmDCCAoCgAwIBAgIUFMs3tKqT0Cvz3r0aSN9KSVPCsfkwDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTExNDQ0MzZaFw0yNTAzMTExNDQ0MzZaMFQxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRgwFgYDVQQDDA90 +ZXN0X3Rsc19zZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCh +86dsAI7FzJxhKykW5uzHuz9NGbmzq8G9ndUdIwTHYmawTTgr3NCBAYEF1+iOo6y9 +8yUUsTyN3bqx3biFVQHWVP6iHI7WPBazFOZOyyjc3gcRD6M5LVPBIc5Ar+zcKNzL +b8ZTW4G1T4fye5XXPS+Zu2IHjIBAPoXQVhKZjWfmpPmloF+hphF5l8L7ilDfsj3o +1qo88XzGVUjkR5fF5UE/6iuiiipXsLRtEvsYSYMvvLuKWGN+e0t3JwvfH0JnAURK +/KKOixhqnbGcnrwVY1bzgFo3u9NSQjjYREvu6QBEthuLtPkc+PCR+DxjBmdh1der +7Bwwnfa3AgKbbtoZhlkPAgMBAAGjYjBgMB4GA1UdEQQXMBWCE25ld190ZXN0X3Rs +c19zZXJ2ZXIwHQYDVR0OBBYEFG2WT0EOXqPY2QiWTxtb/detOQUDMB8GA1UdIwQY +MBaAFOGCi133CzavIQRoqnb5Ew5ZXwPuMA0GCSqGSIb3DQEBCwUAA4IBAQBKvVh0 +uzdlPkGrkU56hVOvNe2QqKXHbz0xRVeNn/rXItUnV3YbzuiNpyjkHGPBMsDtgri2 +YUf0dKfVr8+Zyr0Yc/Nhbe2gWezGMnoOo9dw6An0r4vSYmJdSaO/s5hH7/orHQxS +zCRN+6iwURT6r1quJDxJLcsA6nzOvLdQnMxTKcak/V6A7eBpoUINdFVNhvPoXMDd +PVaju1U00SEbun8Qgeh/yWz4CPQYgQqKUORkPf0ToK5V3jrbIuW9VfQi8VcOzCn9 +YPihAEzkhh+PG8FYwK3vc6u2qKNlcbEuMu6rOQTUDWAi6+PJY5ClHQYdnb4/ThjT +vcP3w3j3YhSd/9iA +-----END CERTIFICATE----- diff --git a/myserver.key b/myserver.key new file mode 100644 index 0000000000..3cad67bdc9 --- /dev/null +++ b/myserver.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCh86dsAI7FzJxh +KykW5uzHuz9NGbmzq8G9ndUdIwTHYmawTTgr3NCBAYEF1+iOo6y98yUUsTyN3bqx +3biFVQHWVP6iHI7WPBazFOZOyyjc3gcRD6M5LVPBIc5Ar+zcKNzLb8ZTW4G1T4fy +e5XXPS+Zu2IHjIBAPoXQVhKZjWfmpPmloF+hphF5l8L7ilDfsj3o1qo88XzGVUjk +R5fF5UE/6iuiiipXsLRtEvsYSYMvvLuKWGN+e0t3JwvfH0JnAURK/KKOixhqnbGc +nrwVY1bzgFo3u9NSQjjYREvu6QBEthuLtPkc+PCR+DxjBmdh1der7Bwwnfa3AgKb +btoZhlkPAgMBAAECggEAP5vQA8L6UKUrPJzzoAumL1KTq8gxYGjTCRMvS6jf7SHw +fElwCQZLHIhHMVDahf+yTs7rnwN36a6Pb+HKYg//zzuF4Y0+6tUiA0dvp73yuEE6 +XFCchs4PSdlpxY1zhgtEoWCu8DmOKfTpS+uPcEEXa5WmDJn6G4GTFD9iQc5A410D +oBf0ONw7X8nE1ZBZr6dpJBdsP68pRJC8BfhTH/dS3d4I4JYb2BgLER1ZbMqfFeW/ +sAZ3FKKETdYvCgLb380/Xpb08FRAHlQ1MowEpfe2sNBqsnkHjESExMIP8Ne7O+ts +9IUIGHZkKIl9u/B/RHCve8Db3GM9F/lMjJ9p84FEXQKBgQDTzYX+9FyAZt5NGPwW +5mTqlh5EHLZzgnVGo2DySu0Zi7MN/YYKV1wAT3i6cTATMjjdSYu2u6L1VYhfIYYq +43MIcsHe7XMAQxbQ6l6oULUa77huMzC0Js0l08kV/ERkH0/nUS9JRp5FJUKR7mkH +Am2dz040MceQMITzCewwskf+jQKBgQDDvxgxBTNJYF3tN3uNLBPRcib0Kk+p2LfW +oDv43++MiyqkTejJJqMDHtYsXNivH6T7CE2U0Qf+2MonAzoVnNsEAfonS19okn8c +LqkMlTZmiT9Tld+h+pcAsf7lYYXSuZv10lgXSN2nj8LBm/EM130ShzyrM58vCGRC +/fDPu9ZNCwKBgQCnuWdVILlnzQ5ZS2HF2Kktw7cwBPTOwA6S46pP9NmRkzk16QAO +jGOEs2pNanjBmtHBGw6SpEBFu3gErY2LxRZBKG8yVCLvoDEfO5m9/DuOmysXyV3W +K6vlOrNQv7aA+vLRoU6q3ktTQlBXM87kCB46DAJH/uuj2WhO9hqd7XBpuQKBgFCG +/9vCyOuJ0noxVgmotWp3rKDL+0PjXRXVi3aCIZlO8zbuujJuS6eP+wn7FEVPHl8L +dmcfa0ujQd60zCNyCQPoEFI0BscNZW9hnrgHdn7OPZgUUxDe91oY38TbzuL26rtB +Um4Z0t4JHVTq40qmJ9UEf6fqr7T4nc6Vi4jaPHorAoGAL1hVy8oYAKtJCTlRQalw +apM3ZJUlTK7qfkjajPEvmhuHntplHDkGEe5ZROUu3zluDiS7MHzOYtunitoMaZbG +cRMO34aDO/UXoLdUWabuk81e3/AWgs6wHVFBOpRAYKAQzigrmXanMclwiL0V5T9K +IgP5i6aUi4zduiV1YLHj4UA= +-----END PRIVATE KEY----- diff --git a/pub_client.json5 b/pub_client.json5 new file mode 100644 index 0000000000..b75f75fa16 --- /dev/null +++ b/pub_client.json5 @@ -0,0 +1,431 @@ +/// This file attempts to list and document available configuration elements. +/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. +/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. +{ + /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) + /// that zenoh runtime will use. + /// If not set, a random unsigned 128bit integer will be used. + /// WARNING: this id must be unique in your zenoh network. + // id: "1234567890abcdef", + /// The node's mode (router, peer or client) + mode: "client", + /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ + metadata: { + name: "strawberry", + location: "Penny Lane" + }, + /// Which endpoints to connect to. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: + /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 + connect: { + endpoints: [ + // "/
" + "quic/127.0.0.1:7447" + + ], + }, + /// Which endpoints to listen on. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, + /// peers, or client can use to establish a zenoh session. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: + /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 + listen: { + endpoints: [ + // "/
" + ], + }, + /// Configure the scouting mechanisms and their behaviours + scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 3000, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 200, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: true, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: true, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: true, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + /// Configuration of data messages timestamps management. + timestamping: { + /// Whether data messages should be timestamped if not already. + /// Accepts a single boolean value or different values for router, peer and client. + enabled: { router: true, peer: false, client: false + }, + /// Whether data messages with timestamps in the future should be dropped or not. + /// If set to false (default), messages with timestamps in the future are retimestamped. + /// Timestamps are ignored if timestamping is disabled. + drop_future_timestamp: false, + }, + /// The default timeout to apply to queries in milliseconds. + queries_default_timeout: 10000, + /// The routing strategy to use and it's configuration. + routing: { + /// The routing strategy to use in routers and it's configuration. + router: { + /// When set to true a router will forward data between two peers + /// directly connected to it if it detects that those peers are not + /// connected to each other. + /// The failover brokering only works if gossip discovery is enabled. + peers_failover_brokering: true, + }, + /// The routing strategy to use in peers and it's configuration. + peer: { + /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). + mode: "peer_to_peer", + }, + }, + // /// The declarations aggregation strategy. + // aggregation: { + // /// A list of key-expressions for which all included subscribers will be aggregated into. + // subscribers: [ + // // key_expression + // ], + // /// A list of key-expressions for which all included publishers will be aggregated into. + // publishers: [ + // // key_expression + // ], + // }, + // /// The downsampling declaration. + // downsampling: [ + // { + // /// A list of network interfaces messages will be processed on, the rest will be passed as is. + // interfaces: [ "wlan0" ], + // /// Data flow messages will be processed on. ("egress" or "ingress") + // flow: "egress", + // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz + // rules: [ + // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, + // ], + // }, + // ], + /// Configure internal transport parameters + transport: { + unicast: { + /// Timeout in milliseconds when opening a link + accept_timeout: 10000, + /// Maximum number of zenoh session in pending state while accepting + accept_pending: 100, + /// Maximum number of sessions that can be simultaneously alive + max_sessions: 1000, + /// Maximum number of incoming links that are admitted per session + max_links: 1, + /// Enables the LowLatency transport + /// This option does not make LowLatency transport mandatory, the actual implementation of transport + /// used will depend on Establish procedure and other party's settings + /// + /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. + /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to + /// enable 'lowlatency' you need to explicitly disable 'qos'. + lowlatency: false, + /// Enables QoS on unicast communications. + qos: { + enabled: true, + }, + /// Enables compression on unicast communications. + /// Compression capabilities are negotiated during session establishment. + /// If both Zenoh nodes support compression, then compression is activated. + compression: { + enabled: false, + }, + }, + multicast: { + /// Enables QoS on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + qos: { + enabled: false, + }, + /// Enables compression on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + compression: { + enabled: false, + }, + }, + link: { + /// An optional whitelist of protocols to be used for accepting and opening sessions. + /// If not configured, all the supported protocols are automatically whitelisted. + /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + /// For example, to only enable "tls" and "quic": + // protocols: ["tls", "quic"], + /// Configure the zenoh TX parameters of a link + tx: { + /// The resolution in bits to be used for the message sequence numbers. + /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: "32bit", + /// Link lease duration in milliseconds to announce to other zenoh nodes + lease: 10000, + /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive + /// messages will be sent at the configured time interval. + /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, + /// set the actual keep_alive timeout to one fourth of the lease time. + /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity + /// check which considers a link as failed when no messages are received in 3.5 times the + /// target interval. + keep_alive: 4, + /// Batch size in bytes is expressed as a 16bit unsigned integer. + /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). + /// The default batch size value is the maximum batch size: 65535. + batch_size: 65535, + /// Each zenoh link has a transmission queue that can be configured + queue: { + /// The size of each priority queue indicates the number of batches a given queue can contain. + /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. + /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, + /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. + /// If qos is false, then only the DATA priority will be allocated. + size: { + control: 1, + real_time: 1, + interactive_high: 1, + interactive_low: 1, + data_high: 2, + data: 4, + data_low: 4, + background: 4, + }, + /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. + /// Higher values lead to a more aggressive batching but it will introduce additional latency. + backoff: 100, + }, + // Number of threads dedicated to transmission + // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) + // threads: 4, + }, + /// Configure the zenoh RX parameters of a link + rx: { + /// Receiving buffer size in bytes for each link + /// The default the rx_buffer_size value is the same as the default batch size: 65335. + /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate + /// more in-flight data. This is particularly relevant when dealing with large messages. + /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. + buffer_size: 65535, + /// Maximum size of the defragmentation buffer at receiver end. + /// Fragmented messages that are larger than the configured size will be dropped. + /// The default value is 1GiB. This would work in most scenarios. + /// NOTE: reduce the value if you are operating on a memory constrained device. + max_message_size: 1073741824, + }, + /// Configure TLS specific parameters + tls: { + root_ca_certificate: "ca.crt" + } + // tls: { + // /// Path to the certificate of the certificate authority used to validate either the server + // /// or the client's keys and certificates, depending on the node's mode. If not specified + // /// on router mode then the default WebPKI certificates are used instead. + // root_ca_certificate: null, + // /// Path to the TLS server private key + // server_private_key: null, + // /// Path to the TLS server public certificate + // server_certificate: null, + // /// Client authentication, if true enables mTLS (mutual authentication) + // client_auth: false, + // /// Path to the TLS client private key + // client_private_key: null, + // /// Path to the TLS client public certificate + // client_certificate: null, + // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + // server_name_verification: null, + // }, + }, + /// Shared memory configuration + shared_memory: { + enabled: false, + }, + /// Access control configuration + auth: { + /// The configuration of authentification. + /// A password implies a username is required. + usrpwd: { + user: null, + password: null, + /// The path to a file containing the user password dictionary + dictionary_file: null, + }, + pubkey: { + public_key_pem: null, + private_key_pem: null, + public_key_file: null, + private_key_file: null, + key_size: null, + known_keys_file: null, + }, + }, + }, + /// Configure the Admin Space + /// Unstable: this configuration part works as advertised, but may change in a future release + adminspace: { + // read and/or write permissions on the admin space + permissions: { + read: true, + write: false, + }, + }, + /// + /// Plugins configurations + /// + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // plugins_search_dirs: [], + // /// Plugins are only loaded if present in the configuration. When starting + // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. + // plugins: { + // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) + // + // /// Plugin settings may contain field `__config__` + // /// - If `__config__` is specified, it's content is merged into plugin configuration + // /// - Properties loaded from `__config__` file overrides existing properties + // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively + // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config + // /// + // /// See below exapmle of plugin configuration using `__config__` property + // + // /// Configure the REST API plugin + // rest: { + // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. + // __required__: true, // defaults to false + // /// load configuration from the file + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // /// http port to answer to rest requests + // http_port: 8000, + // }, + // + // /// Configure the storage manager plugin + // storage_manager: { + // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. + // __path__: [ + // "./target/release/libzenoh_plugin_storage_manager.so", + // "./target/release/libzenoh_plugin_storage_manager.dylib", + // ], + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // backend_search_dirs: [], + // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. + // volumes: { + // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb + // influxdb: { + // url: "https://myinfluxdb.example", + // /// Some plugins may need passwords in their configuration. + // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. + // /// any value held at the key "private" will not be shown in the adminspace. + // private: { + // username: "user1", + // password: "pw1", + // }, + // }, + // influxdb2: { + // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. + // backend: "influxdb", + // private: { + // username: "user2", + // password: "pw2", + // }, + // url: "https://localhost:8086", + // }, + // }, + // + // /// Configure the storages supported by the volumes + // storages: { + // demo: { + // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. + // key_expr: "demo/memory/**", + // /// Storages also need to know which volume will be used to actually store their key-value pairs. + // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. + // volume: "memory", + // }, + // demo2: { + // key_expr: "demo/memory2/**", + // volume: "memory", + // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. + // /// Metadata includes the set of wild card updates and deletions (tombstones). + // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. + // garbage_collection: { + // /// The garbage collection event will be periodic with this duration. + // /// The duration is specified in seconds. + // period: 30, + // /// Metadata older than this parameter will be garbage collected. + // /// The duration is specified in seconds. + // lifespan: 86400, + // }, + // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. + // /// In the absence of this configuration, a normal storage is initialized + // /// Note: all the samples to be stored in replicas should be timestamped + // replica_config: { + // /// Specifying the parameters is optional, by default the values provided will be used. + // /// Time interval between different synchronization attempts in seconds + // publication_interval: 5, + // /// Expected propagation delay of the network in milliseconds + // propagation_delay: 200, + // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. + // /// Higher the frequency of updates, lower the delta should be chosen + // /// To be efficient, delta should be the time containing no more than 100,000 samples + // delta: 1000, + // } + // }, + // demo3: { + // key_expr: "demo/memory3/**", + // volume: "memory", + // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. + // /// If not configured, complete defaults to false. + // complete: "true", + // }, + // influx_demo: { + // key_expr: "demo/influxdb/**", + // /// This prefix will be stripped of the received keys when storing. + // strip_prefix: "demo/influxdb", + // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: + // volume: { + // id: "influxdb", + // db: "example", + // }, + // }, + // influx_demo2: { + // key_expr: "demo/influxdb2/**", + // strip_prefix: "demo/influxdb2", + // volume: { + // id: "influxdb2", + // db: "example", + // }, + // }, + // }, + // }, + // }, + // /// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // } + // }, +} \ No newline at end of file diff --git a/router.json5 b/router.json5 new file mode 100644 index 0000000000..46817ee4b4 --- /dev/null +++ b/router.json5 @@ -0,0 +1,431 @@ +/// This file attempts to list and document available configuration elements. +/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. +/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. +{ + /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) + /// that zenoh runtime will use. + /// If not set, a random unsigned 128bit integer will be used. + /// WARNING: this id must be unique in your zenoh network. + // id: "1234567890abcdef", + /// The node's mode (router, peer or client) + mode: "router", + /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ + metadata: { + name: "strawberry", + location: "Penny Lane" + }, + /// Which endpoints to connect to. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: + /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 + connect: { + endpoints: [ + // "/
" + ], + }, + /// Which endpoints to listen on. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, + /// peers, or client can use to establish a zenoh session. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: + /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 + listen: { + endpoints: [ + // "/
" + "quic/127.0.0.1:7447" + ], + }, + /// Configure the scouting mechanisms and their behaviours + scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 3000, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 200, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: true, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: true, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: true, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + /// Configuration of data messages timestamps management. + timestamping: { + /// Whether data messages should be timestamped if not already. + /// Accepts a single boolean value or different values for router, peer and client. + enabled: { router: true, peer: false, client: false + }, + /// Whether data messages with timestamps in the future should be dropped or not. + /// If set to false (default), messages with timestamps in the future are retimestamped. + /// Timestamps are ignored if timestamping is disabled. + drop_future_timestamp: false, + }, + /// The default timeout to apply to queries in milliseconds. + queries_default_timeout: 10000, + /// The routing strategy to use and it's configuration. + routing: { + /// The routing strategy to use in routers and it's configuration. + router: { + /// When set to true a router will forward data between two peers + /// directly connected to it if it detects that those peers are not + /// connected to each other. + /// The failover brokering only works if gossip discovery is enabled. + peers_failover_brokering: true, + }, + /// The routing strategy to use in peers and it's configuration. + peer: { + /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). + mode: "peer_to_peer", + }, + }, + // /// The declarations aggregation strategy. + // aggregation: { + // /// A list of key-expressions for which all included subscribers will be aggregated into. + // subscribers: [ + // // key_expression + // ], + // /// A list of key-expressions for which all included publishers will be aggregated into. + // publishers: [ + // // key_expression + // ], + // }, + // /// The downsampling declaration. + // downsampling: [ + // { + // /// A list of network interfaces messages will be processed on, the rest will be passed as is. + // interfaces: [ "wlan0" ], + // /// Data flow messages will be processed on. ("egress" or "ingress") + // flow: "egress", + // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz + // rules: [ + // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, + // ], + // }, + // ], + /// Configure internal transport parameters + transport: { + unicast: { + /// Timeout in milliseconds when opening a link + accept_timeout: 10000, + /// Maximum number of zenoh session in pending state while accepting + accept_pending: 100, + /// Maximum number of sessions that can be simultaneously alive + max_sessions: 1000, + /// Maximum number of incoming links that are admitted per session + max_links: 1, + /// Enables the LowLatency transport + /// This option does not make LowLatency transport mandatory, the actual implementation of transport + /// used will depend on Establish procedure and other party's settings + /// + /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. + /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to + /// enable 'lowlatency' you need to explicitly disable 'qos'. + lowlatency: false, + /// Enables QoS on unicast communications. + qos: { + enabled: true, + }, + /// Enables compression on unicast communications. + /// Compression capabilities are negotiated during session establishment. + /// If both Zenoh nodes support compression, then compression is activated. + compression: { + enabled: false, + }, + }, + multicast: { + /// Enables QoS on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + qos: { + enabled: false, + }, + /// Enables compression on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + compression: { + enabled: false, + }, + }, + link: { + /// An optional whitelist of protocols to be used for accepting and opening sessions. + /// If not configured, all the supported protocols are automatically whitelisted. + /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + /// For example, to only enable "tls" and "quic": + // protocols: ["tls", "quic"], + /// Configure the zenoh TX parameters of a link + tx: { + /// The resolution in bits to be used for the message sequence numbers. + /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: "32bit", + /// Link lease duration in milliseconds to announce to other zenoh nodes + lease: 10000, + /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive + /// messages will be sent at the configured time interval. + /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, + /// set the actual keep_alive timeout to one fourth of the lease time. + /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity + /// check which considers a link as failed when no messages are received in 3.5 times the + /// target interval. + keep_alive: 4, + /// Batch size in bytes is expressed as a 16bit unsigned integer. + /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). + /// The default batch size value is the maximum batch size: 65535. + batch_size: 65535, + /// Each zenoh link has a transmission queue that can be configured + queue: { + /// The size of each priority queue indicates the number of batches a given queue can contain. + /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. + /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, + /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. + /// If qos is false, then only the DATA priority will be allocated. + size: { + control: 1, + real_time: 1, + interactive_high: 1, + interactive_low: 1, + data_high: 2, + data: 4, + data_low: 4, + background: 4, + }, + /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. + /// Higher values lead to a more aggressive batching but it will introduce additional latency. + backoff: 100, + }, + // Number of threads dedicated to transmission + // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) + // threads: 4, + }, + /// Configure the zenoh RX parameters of a link + rx: { + /// Receiving buffer size in bytes for each link + /// The default the rx_buffer_size value is the same as the default batch size: 65335. + /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate + /// more in-flight data. This is particularly relevant when dealing with large messages. + /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. + buffer_size: 65535, + /// Maximum size of the defragmentation buffer at receiver end. + /// Fragmented messages that are larger than the configured size will be dropped. + /// The default value is 1GiB. This would work in most scenarios. + /// NOTE: reduce the value if you are operating on a memory constrained device. + max_message_size: 1073741824, + }, + /// Configure TLS specific parameters + tls: { + server_private_key: "myserver.key", + server_certificate: "myserver.crt" + } + // tls: { + // /// Path to the certificate of the certificate authority used to validate either the server + // /// or the client's keys and certificates, depending on the node's mode. If not specified + // /// on router mode then the default WebPKI certificates are used instead. + // root_ca_certificate: null, + // /// Path to the TLS server private key + // server_private_key: null, + // /// Path to the TLS server public certificate + // server_certificate: null, + // /// Client authentication, if true enables mTLS (mutual authentication) + // client_auth: false, + // /// Path to the TLS client private key + // client_private_key: null, + // /// Path to the TLS client public certificate + // client_certificate: null, + // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + // server_name_verification: null, + // }, + }, + /// Shared memory configuration + shared_memory: { + enabled: false, + }, + /// Access control configuration + auth: { + /// The configuration of authentication. + /// A password implies a username is required. + usrpwd: { + user: null, + password: null, + /// The path to a file containing the user password dictionary + dictionary_file: null, + }, + pubkey: { + public_key_pem: null, + private_key_pem: null, + public_key_file: null, + private_key_file: null, + key_size: null, + known_keys_file: null, + }, + }, + }, + /// Configure the Admin Space + /// Unstable: this configuration part works as advertised, but may change in a future release + adminspace: { + // read and/or write permissions on the admin space + permissions: { + read: true, + write: false, + }, + }, + /// + /// Plugins configurations + /// + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // plugins_search_dirs: [], + // /// Plugins are only loaded if present in the configuration. When starting + // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. + // plugins: { + // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) + // + // /// Plugin settings may contain field `__config__` + // /// - If `__config__` is specified, it's content is merged into plugin configuration + // /// - Properties loaded from `__config__` file overrides existing properties + // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively + // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config + // /// + // /// See below exapmle of plugin configuration using `__config__` property + // + // /// Configure the REST API plugin + // rest: { + // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. + // __required__: true, // defaults to false + // /// load configuration from the file + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // /// http port to answer to rest requests + // http_port: 8000, + // }, + // + // /// Configure the storage manager plugin + // storage_manager: { + // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. + // __path__: [ + // "./target/release/libzenoh_plugin_storage_manager.so", + // "./target/release/libzenoh_plugin_storage_manager.dylib", + // ], + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // backend_search_dirs: [], + // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. + // volumes: { + // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb + // influxdb: { + // url: "https://myinfluxdb.example", + // /// Some plugins may need passwords in their configuration. + // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. + // /// any value held at the key "private" will not be shown in the adminspace. + // private: { + // username: "user1", + // password: "pw1", + // }, + // }, + // influxdb2: { + // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. + // backend: "influxdb", + // private: { + // username: "user2", + // password: "pw2", + // }, + // url: "https://localhost:8086", + // }, + // }, + // + // /// Configure the storages supported by the volumes + // storages: { + // demo: { + // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. + // key_expr: "demo/memory/**", + // /// Storages also need to know which volume will be used to actually store their key-value pairs. + // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. + // volume: "memory", + // }, + // demo2: { + // key_expr: "demo/memory2/**", + // volume: "memory", + // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. + // /// Metadata includes the set of wild card updates and deletions (tombstones). + // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. + // garbage_collection: { + // /// The garbage collection event will be periodic with this duration. + // /// The duration is specified in seconds. + // period: 30, + // /// Metadata older than this parameter will be garbage collected. + // /// The duration is specified in seconds. + // lifespan: 86400, + // }, + // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. + // /// In the absence of this configuration, a normal storage is initialized + // /// Note: all the samples to be stored in replicas should be timestamped + // replica_config: { + // /// Specifying the parameters is optional, by default the values provided will be used. + // /// Time interval between different synchronization attempts in seconds + // publication_interval: 5, + // /// Expected propagation delay of the network in milliseconds + // propagation_delay: 200, + // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. + // /// Higher the frequency of updates, lower the delta should be chosen + // /// To be efficient, delta should be the time containing no more than 100,000 samples + // delta: 1000, + // } + // }, + // demo3: { + // key_expr: "demo/memory3/**", + // volume: "memory", + // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. + // /// If not configured, complete defaults to false. + // complete: "true", + // }, + // influx_demo: { + // key_expr: "demo/influxdb/**", + // /// This prefix will be stripped of the received keys when storing. + // strip_prefix: "demo/influxdb", + // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: + // volume: { + // id: "influxdb", + // db: "example", + // }, + // }, + // influx_demo2: { + // key_expr: "demo/influxdb2/**", + // strip_prefix: "demo/influxdb2", + // volume: { + // id: "influxdb2", + // db: "example", + // }, + // }, + // }, + // }, + // }, + // /// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // } + // }, +} \ No newline at end of file diff --git a/sub_client.json5 b/sub_client.json5 new file mode 100644 index 0000000000..b75f75fa16 --- /dev/null +++ b/sub_client.json5 @@ -0,0 +1,431 @@ +/// This file attempts to list and document available configuration elements. +/// For a more complete view of the configuration's structure, check out `zenoh/src/config.rs`'s `Config` structure. +/// Note that the values here are correctly typed, but may not be sensible, so copying this file to change only the parts that matter to you is not good practice. +{ + /// The identifier (as unsigned 128bit integer in hexadecimal lowercase - leading zeros are not accepted) + /// that zenoh runtime will use. + /// If not set, a random unsigned 128bit integer will be used. + /// WARNING: this id must be unique in your zenoh network. + // id: "1234567890abcdef", + /// The node's mode (router, peer or client) + mode: "client", + /// The node's metadata (name, location, DNS name, etc.) Arbitrary JSON data not interpreted by zenohd and available in admin space @/router/ + metadata: { + name: "strawberry", + location: "Penny Lane" + }, + /// Which endpoints to connect to. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which router/peer to connect to at startup. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be connected to: + /// E.g. tcp/192.168.0.1:7447#iface=eth0, for connect only if the IP address is reachable via the interface eth0 + connect: { + endpoints: [ + // "/
" + "quic/127.0.0.1:7447" + + ], + }, + /// Which endpoints to listen on. E.g. tcp/localhost:7447. + /// By configuring the endpoints, it is possible to tell zenoh which are the endpoints that other routers, + /// peers, or client can use to establish a zenoh session. + /// For TCP/UDP on Linux, it is possible additionally specify the interface to be listened to: + /// E.g. tcp/0.0.0.0:7447#iface=eth0, for listen connection only on eth0 + listen: { + endpoints: [ + // "/
" + ], + }, + /// Configure the scouting mechanisms and their behaviours + scouting: { + /// In client mode, the period dedicated to scouting for a router before failing + timeout: 3000, + /// In peer mode, the period dedicated to scouting remote peers before attempting other operations + delay: 200, + /// The multicast scouting configuration. + multicast: { + /// Whether multicast scouting is enabled or not + enabled: true, + /// The socket which should be used for multicast scouting + address: "224.0.0.224:7446", + /// The network interface which should be used for multicast scouting + interface: "auto", // If not set or set to "auto" the interface if picked automatically + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on UDP multicast. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + /// Whether or not to listen for scout messages on UDP multicast and reply to them. + listen: true, + }, + /// The gossip scouting configuration. + gossip: { + /// Whether gossip scouting is enabled or not + enabled: true, + /// When true, gossip scouting informations are propagated multiple hops to all nodes in the local network. + /// When false, gossip scouting informations are only propagated to the next hop. + /// Activating multihop gossip implies more scouting traffic and a lower scalability. + /// It mostly makes sense when using "linkstate" routing mode where all nodes in the subsystem don't have + /// direct connectivity with each other. + multihop: false, + /// Which type of Zenoh instances to automatically establish sessions with upon discovery on gossip. + /// Accepts a single value or different values for router, peer and client. + /// Each value is bit-or-like combinations of "peer", "router" and "client". + autoconnect: { router: "", peer: "router|peer" + }, + }, + }, + /// Configuration of data messages timestamps management. + timestamping: { + /// Whether data messages should be timestamped if not already. + /// Accepts a single boolean value or different values for router, peer and client. + enabled: { router: true, peer: false, client: false + }, + /// Whether data messages with timestamps in the future should be dropped or not. + /// If set to false (default), messages with timestamps in the future are retimestamped. + /// Timestamps are ignored if timestamping is disabled. + drop_future_timestamp: false, + }, + /// The default timeout to apply to queries in milliseconds. + queries_default_timeout: 10000, + /// The routing strategy to use and it's configuration. + routing: { + /// The routing strategy to use in routers and it's configuration. + router: { + /// When set to true a router will forward data between two peers + /// directly connected to it if it detects that those peers are not + /// connected to each other. + /// The failover brokering only works if gossip discovery is enabled. + peers_failover_brokering: true, + }, + /// The routing strategy to use in peers and it's configuration. + peer: { + /// The routing strategy to use in peers. ("peer_to_peer" or "linkstate"). + mode: "peer_to_peer", + }, + }, + // /// The declarations aggregation strategy. + // aggregation: { + // /// A list of key-expressions for which all included subscribers will be aggregated into. + // subscribers: [ + // // key_expression + // ], + // /// A list of key-expressions for which all included publishers will be aggregated into. + // publishers: [ + // // key_expression + // ], + // }, + // /// The downsampling declaration. + // downsampling: [ + // { + // /// A list of network interfaces messages will be processed on, the rest will be passed as is. + // interfaces: [ "wlan0" ], + // /// Data flow messages will be processed on. ("egress" or "ingress") + // flow: "egress", + // /// A list of downsampling rules: key_expression and the maximum frequency in Hertz + // rules: [ + // { key_expr: "demo/example/zenoh-rs-pub", freq: 0.1 }, + // ], + // }, + // ], + /// Configure internal transport parameters + transport: { + unicast: { + /// Timeout in milliseconds when opening a link + accept_timeout: 10000, + /// Maximum number of zenoh session in pending state while accepting + accept_pending: 100, + /// Maximum number of sessions that can be simultaneously alive + max_sessions: 1000, + /// Maximum number of incoming links that are admitted per session + max_links: 1, + /// Enables the LowLatency transport + /// This option does not make LowLatency transport mandatory, the actual implementation of transport + /// used will depend on Establish procedure and other party's settings + /// + /// NOTE: Currently, the LowLatency transport doesn't preserve QoS prioritization. + /// NOTE: Due to the note above, 'lowlatency' is incompatible with 'qos' option, so in order to + /// enable 'lowlatency' you need to explicitly disable 'qos'. + lowlatency: false, + /// Enables QoS on unicast communications. + qos: { + enabled: true, + }, + /// Enables compression on unicast communications. + /// Compression capabilities are negotiated during session establishment. + /// If both Zenoh nodes support compression, then compression is activated. + compression: { + enabled: false, + }, + }, + multicast: { + /// Enables QoS on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + qos: { + enabled: false, + }, + /// Enables compression on multicast communication. + /// Default to false for Zenoh-to-Zenoh-Pico out-of-the-box compatibility. + compression: { + enabled: false, + }, + }, + link: { + /// An optional whitelist of protocols to be used for accepting and opening sessions. + /// If not configured, all the supported protocols are automatically whitelisted. + /// The supported protocols are: ["tcp" , "udp", "tls", "quic", "ws", "unixsock-stream"] + /// For example, to only enable "tls" and "quic": + // protocols: ["tls", "quic"], + /// Configure the zenoh TX parameters of a link + tx: { + /// The resolution in bits to be used for the message sequence numbers. + /// When establishing a session with another Zenoh instance, the lowest value of the two instances will be used. + /// Accepted values: 8bit, 16bit, 32bit, 64bit. + sequence_number_resolution: "32bit", + /// Link lease duration in milliseconds to announce to other zenoh nodes + lease: 10000, + /// Number of keep-alive messages in a link lease duration. If no data is sent, keep alive + /// messages will be sent at the configured time interval. + /// NOTE: In order to consider eventual packet loss and transmission latency and jitter, + /// set the actual keep_alive timeout to one fourth of the lease time. + /// This is in-line with the ITU-T G.8013/Y.1731 specification on continous connectivity + /// check which considers a link as failed when no messages are received in 3.5 times the + /// target interval. + keep_alive: 4, + /// Batch size in bytes is expressed as a 16bit unsigned integer. + /// Therefore, the maximum batch size is 2^16-1 (i.e. 65535). + /// The default batch size value is the maximum batch size: 65535. + batch_size: 65535, + /// Each zenoh link has a transmission queue that can be configured + queue: { + /// The size of each priority queue indicates the number of batches a given queue can contain. + /// The amount of memory being allocated for each queue is then SIZE_XXX * BATCH_SIZE. + /// In the case of the transport link MTU being smaller than the ZN_BATCH_SIZE, + /// then amount of memory being allocated for each queue is SIZE_XXX * LINK_MTU. + /// If qos is false, then only the DATA priority will be allocated. + size: { + control: 1, + real_time: 1, + interactive_high: 1, + interactive_low: 1, + data_high: 2, + data: 4, + data_low: 4, + background: 4, + }, + /// The initial exponential backoff time in nanoseconds to allow the batching to eventually progress. + /// Higher values lead to a more aggressive batching but it will introduce additional latency. + backoff: 100, + }, + // Number of threads dedicated to transmission + // By default, the number of threads is calculated as follows: 1 + ((#cores - 1) / 4) + // threads: 4, + }, + /// Configure the zenoh RX parameters of a link + rx: { + /// Receiving buffer size in bytes for each link + /// The default the rx_buffer_size value is the same as the default batch size: 65335. + /// For very high throughput scenarios, the rx_buffer_size can be increased to accomodate + /// more in-flight data. This is particularly relevant when dealing with large messages. + /// E.g. for 16MiB rx_buffer_size set the value to: 16777216. + buffer_size: 65535, + /// Maximum size of the defragmentation buffer at receiver end. + /// Fragmented messages that are larger than the configured size will be dropped. + /// The default value is 1GiB. This would work in most scenarios. + /// NOTE: reduce the value if you are operating on a memory constrained device. + max_message_size: 1073741824, + }, + /// Configure TLS specific parameters + tls: { + root_ca_certificate: "ca.crt" + } + // tls: { + // /// Path to the certificate of the certificate authority used to validate either the server + // /// or the client's keys and certificates, depending on the node's mode. If not specified + // /// on router mode then the default WebPKI certificates are used instead. + // root_ca_certificate: null, + // /// Path to the TLS server private key + // server_private_key: null, + // /// Path to the TLS server public certificate + // server_certificate: null, + // /// Client authentication, if true enables mTLS (mutual authentication) + // client_auth: false, + // /// Path to the TLS client private key + // client_private_key: null, + // /// Path to the TLS client public certificate + // client_certificate: null, + // // Whether or not to use server name verification, if set to false zenoh will disregard the common names of the certificates when verifying servers. + // // This could be dangerous because your CA can have signed a server cert for foo.com, that's later being used to host a server at baz.com. If you wan't your + // // ca to verify that the server at baz.com is actually baz.com, let this be true (default). + // server_name_verification: null, + // }, + }, + /// Shared memory configuration + shared_memory: { + enabled: false, + }, + /// Access control configuration + auth: { + /// The configuration of authentification. + /// A password implies a username is required. + usrpwd: { + user: null, + password: null, + /// The path to a file containing the user password dictionary + dictionary_file: null, + }, + pubkey: { + public_key_pem: null, + private_key_pem: null, + public_key_file: null, + private_key_file: null, + key_size: null, + known_keys_file: null, + }, + }, + }, + /// Configure the Admin Space + /// Unstable: this configuration part works as advertised, but may change in a future release + adminspace: { + // read and/or write permissions on the admin space + permissions: { + read: true, + write: false, + }, + }, + /// + /// Plugins configurations + /// + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // plugins_search_dirs: [], + // /// Plugins are only loaded if present in the configuration. When starting + // /// Once loaded, they may react to changes in the configuration made through the zenoh instance's adminspace. + // plugins: { + // /// If no `__path__` is given to a plugin, zenohd will automatically search for a shared library matching the plugin's name (here, `libzenoh_plugin_rest.so` would be searched for on linux) + // + // /// Plugin settings may contain field `__config__` + // /// - If `__config__` is specified, it's content is merged into plugin configuration + // /// - Properties loaded from `__config__` file overrides existing properties + // /// - If json objects in loaded file contains `__config__` properties, they are processed recursively + // /// This is used in the 'storcge_manager' which supports subplugins, each with it's own config + // /// + // /// See below exapmle of plugin configuration using `__config__` property + // + // /// Configure the REST API plugin + // rest: { + // /// Setting this option to true allows zenohd to panic should it detect issues with this plugin. Setting it to false politely asks the plugin not to panic. + // __required__: true, // defaults to false + // /// load configuration from the file + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // /// http port to answer to rest requests + // http_port: 8000, + // }, + // + // /// Configure the storage manager plugin + // storage_manager: { + // /// When a path is present, automatic search is disabled, and zenohd will instead select the first path which manages to load. + // __path__: [ + // "./target/release/libzenoh_plugin_storage_manager.so", + // "./target/release/libzenoh_plugin_storage_manager.dylib", + // ], + // /// Directories where plugins configured by name should be looked for. Plugins configured by __path__ are not subject to lookup + // backend_search_dirs: [], + // /// The "memory" volume is always available, but you may create other volumes here, with various backends to support the actual storing. + // volumes: { + // /// An influxdb backend is also available at https://github.com/eclipse-zenoh/zenoh-backend-influxdb + // influxdb: { + // url: "https://myinfluxdb.example", + // /// Some plugins may need passwords in their configuration. + // /// To avoid leaking them through the adminspace, they may be masked behind a privacy barrier. + // /// any value held at the key "private" will not be shown in the adminspace. + // private: { + // username: "user1", + // password: "pw1", + // }, + // }, + // influxdb2: { + // /// A second backend of the same type can be spawned using `__path__`, for examples when different DBs are needed. + // backend: "influxdb", + // private: { + // username: "user2", + // password: "pw2", + // }, + // url: "https://localhost:8086", + // }, + // }, + // + // /// Configure the storages supported by the volumes + // storages: { + // demo: { + // /// Storages always need to know what set of keys they must work with. These sets are defined by a key expression. + // key_expr: "demo/memory/**", + // /// Storages also need to know which volume will be used to actually store their key-value pairs. + // /// The "memory" volume is always available, and doesn't require any per-storage options, so requesting "memory" by string is always sufficient. + // volume: "memory", + // }, + // demo2: { + // key_expr: "demo/memory2/**", + // volume: "memory", + // /// Storage manager plugin handles metadata in order to ensure convergence of distributed storages configured in Zenoh. + // /// Metadata includes the set of wild card updates and deletions (tombstones). + // /// Once the samples are guaranteed to be delivered, the metadata can be garbage collected. + // garbage_collection: { + // /// The garbage collection event will be periodic with this duration. + // /// The duration is specified in seconds. + // period: 30, + // /// Metadata older than this parameter will be garbage collected. + // /// The duration is specified in seconds. + // lifespan: 86400, + // }, + // /// If multiple storages subscribing to the same key_expr should be synchronized, declare them as replicas. + // /// In the absence of this configuration, a normal storage is initialized + // /// Note: all the samples to be stored in replicas should be timestamped + // replica_config: { + // /// Specifying the parameters is optional, by default the values provided will be used. + // /// Time interval between different synchronization attempts in seconds + // publication_interval: 5, + // /// Expected propagation delay of the network in milliseconds + // propagation_delay: 200, + // /// This is the chunk that you would like your data to be divide into in time, in milliseconds. + // /// Higher the frequency of updates, lower the delta should be chosen + // /// To be efficient, delta should be the time containing no more than 100,000 samples + // delta: 1000, + // } + // }, + // demo3: { + // key_expr: "demo/memory3/**", + // volume: "memory", + // /// A complete storage advertises itself as containing all the known keys matching the configured key expression. + // /// If not configured, complete defaults to false. + // complete: "true", + // }, + // influx_demo: { + // key_expr: "demo/influxdb/**", + // /// This prefix will be stripped of the received keys when storing. + // strip_prefix: "demo/influxdb", + // /// influxdb-backed volumes need a bit more configuration, which is passed like-so: + // volume: { + // id: "influxdb", + // db: "example", + // }, + // }, + // influx_demo2: { + // key_expr: "demo/influxdb2/**", + // strip_prefix: "demo/influxdb2", + // volume: { + // id: "influxdb2", + // db: "example", + // }, + // }, + // }, + // }, + // }, + // /// Plugin configuration example using `__config__` property + // plugins: { + // rest: { + // __config__: "./plugins/zenoh-plugin-rest/config.json5", + // }, + // storage_manager: { + // __config__: "./plugins/zenoh-plugin-storage-manager/config.json5", + // } + // }, +} \ No newline at end of file From 310c1229943b7aefa4e84c5a952c18e1cb3c1a9d Mon Sep 17 00:00:00 2001 From: snehilzs Date: Fri, 26 Apr 2024 16:26:05 +0200 Subject: [PATCH 21/37] add authn features with acl --- .../src/unicast/establishment/accept.rs | 9 ++- .../unicast/establishment/ext/auth/usrpwd.rs | 2 - .../net/routing/interceptor/authorization.rs | 80 ++++++++++++------- 3 files changed, 55 insertions(+), 36 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index cc7cce6d91..c5578ee857 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -473,12 +473,13 @@ impl<'a, 'b: 'a> AcceptFsm for &'a mut AcceptLink<'b> { // Extension Auth #[allow(unused_mut, unused_assignments)] - #[cfg(feature = "auth_usrpwd")] - let mut user_pawssword_id = UsrPwdId(None); + #[cfg(all(feature = "auth_usrpwd", feature = "transport_auth"))] + // #[cfg(feature = "auth_usrpwd")] + let mut user_password_id = UsrPwdId(None); #[cfg(feature = "transport_auth")] { - user_pawssword_id = self + user_password_id = self .ext_auth .recv_open_syn((&mut state.link.ext_auth, open_syn.ext_auth)) .await @@ -511,7 +512,7 @@ impl<'a, 'b: 'a> AcceptFsm for &'a mut AcceptLink<'b> { other_lease: open_syn.lease, other_initial_sn: open_syn.initial_sn, #[cfg(feature = "transport_auth")] - other_auth_id: user_pawssword_id, + other_auth_id: user_password_id, }; Ok((state, output)) } diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs index d0b1ed4d75..8239f9f448 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/usrpwd.rs @@ -159,8 +159,6 @@ impl StateOpen { pub(crate) struct StateAccept { nonce: u64, } - -#[allow(dead_code)] #[derive(Clone, Debug, PartialEq, Eq)] pub(crate) struct UsrPwdId(pub Option>); diff --git a/zenoh/src/net/routing/interceptor/authorization.rs b/zenoh/src/net/routing/interceptor/authorization.rs index 1f4cb84d2b..f3b25aec95 100644 --- a/zenoh/src/net/routing/interceptor/authorization.rs +++ b/zenoh/src/net/routing/interceptor/authorization.rs @@ -24,6 +24,7 @@ use zenoh_config::{ }; use zenoh_keyexpr::keyexpr; use zenoh_keyexpr::keyexpr_tree::{IKeyExprTree, IKeyExprTreeMut, KeBoxTree}; +//use zenoh_link::quic::config; use zenoh_result::ZResult; type PolicyForSubject = FlowPolicy; @@ -180,6 +181,7 @@ impl PolicyEnforcer { } }; } + println!("main policy{}", main_policy.len()); self.policy_map = main_policy; self.subject_map = subject_map; } @@ -197,42 +199,56 @@ impl PolicyEnforcer { &self, config_rule_set: &Vec, ) -> ZResult { + println!("start policy info point{:?}", config_rule_set); let mut policy_rules: Vec = Vec::new(); for config_rule in config_rule_set { for flow in &config_rule.flows { for action in &config_rule.actions { - for key_expr in &config_rule.key_exprs { - if let Some(interface_list) = config_rule.interfaces.clone() { - for interface_subject in interface_list { - policy_rules.push(PolicyRule { - subject: Subject::Interface(interface_subject.clone()), - key_expr: key_expr.clone(), - action: *action, - permission: config_rule.permission, - flow: *flow, - }); + if !config_rule.key_exprs.is_empty() { + for key_expr in &config_rule.key_exprs { + if key_expr.is_empty() { + continue; } - } - if let Some(cert_name_list) = config_rule.cert_common_names.clone() { - for cert_name_subject in cert_name_list { - policy_rules.push(PolicyRule { - subject: Subject::CertCommonName(cert_name_subject.clone()), - key_expr: key_expr.clone(), - action: *action, - permission: config_rule.permission, - flow: *flow, - }); + if let Some(interface_list) = config_rule.interfaces.clone() { + if !interface_list.is_empty() { + for interface_subject in interface_list { + policy_rules.push(PolicyRule { + subject: Subject::Interface(interface_subject.clone()), + key_expr: key_expr.clone(), + action: *action, + permission: config_rule.permission, + flow: *flow, + }); + } + } } - } - if let Some(username_list) = config_rule.usernames.clone() { - for username_subject in username_list { - policy_rules.push(PolicyRule { - subject: Subject::Username(username_subject.clone()), - key_expr: key_expr.clone(), - action: *action, - permission: config_rule.permission, - flow: *flow, - }); + if let Some(cert_name_list) = config_rule.cert_common_names.clone() { + if !cert_name_list.is_empty() { + for cert_name_subject in cert_name_list { + policy_rules.push(PolicyRule { + subject: Subject::CertCommonName( + cert_name_subject.clone(), + ), + key_expr: key_expr.clone(), + action: *action, + permission: config_rule.permission, + flow: *flow, + }); + } + } + } + if let Some(username_list) = config_rule.usernames.clone() { + if !username_list.is_empty() { + for username_subject in username_list { + policy_rules.push(PolicyRule { + subject: Subject::Username(username_subject.clone()), + key_expr: key_expr.clone(), + action: *action, + permission: config_rule.permission, + flow: *flow, + }); + } + } } } } @@ -248,6 +264,7 @@ impl PolicyEnforcer { counter += 1; } } + println!("subject map {:?}policy map{:?}", subject_map, policy_rules); Ok(PolicyInformation { subject_map, policy_rules, @@ -266,6 +283,9 @@ impl PolicyEnforcer { key_expr: &str, ) -> ZResult { let policy_map = &self.policy_map; + if policy_map.is_empty() { + return Ok(self.default_permission); + } match policy_map.get(&subject) { Some(single_policy) => { let deny_result = single_policy From b6eb797a3d9fa7a23af6bb4197e602d6a90d5cc1 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Wed, 1 May 2024 00:03:49 +0530 Subject: [PATCH 22/37] remove error --- io/zenoh-transport/src/unicast/establishment/accept.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index c5578ee857..17c329363f 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -473,11 +473,10 @@ impl<'a, 'b: 'a> AcceptFsm for &'a mut AcceptLink<'b> { // Extension Auth #[allow(unused_mut, unused_assignments)] - #[cfg(all(feature = "auth_usrpwd", feature = "transport_auth"))] - // #[cfg(feature = "auth_usrpwd")] + #[cfg(feature = "auth_usrpwd")] let mut user_password_id = UsrPwdId(None); - #[cfg(feature = "transport_auth")] + #[cfg(feature = "auth_usrpwd")] { user_password_id = self .ext_auth @@ -511,7 +510,7 @@ impl<'a, 'b: 'a> AcceptFsm for &'a mut AcceptLink<'b> { other_whatami: cookie.whatami, other_lease: open_syn.lease, other_initial_sn: open_syn.initial_sn, - #[cfg(feature = "transport_auth")] + #[cfg(feature = "auth_usrpwd")] other_auth_id: user_password_id, }; Ok((state, output)) From 66dc536131025944e004a261229b7a1c7f009c95 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Thu, 2 May 2024 12:18:56 +0530 Subject: [PATCH 23/37] add tests for tls and quic --- .gitignore | 3 +- .../src/unicast/establishment/mod.rs | 1 + .../net/routing/interceptor/authorization.rs | 1 - zenoh/tests/authentication.rs | 729 ++++++++++++++++++ 4 files changed, 731 insertions(+), 3 deletions(-) create mode 100644 zenoh/tests/authentication.rs diff --git a/.gitignore b/.gitignore index a7caf35ccf..bf5a1656d3 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,5 @@ cargo-timing*.html #ignore test data -tests - +testfiles ci/valgrind-check/*.log diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index f79aa826d0..b1ced8b960 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -83,6 +83,7 @@ pub trait AcceptFsm { ) -> Result; type RecvOpenSynIn; + type RecvOpenSynOut; async fn recv_open_syn( self, diff --git a/zenoh/src/net/routing/interceptor/authorization.rs b/zenoh/src/net/routing/interceptor/authorization.rs index f3b25aec95..4cd9aa063a 100644 --- a/zenoh/src/net/routing/interceptor/authorization.rs +++ b/zenoh/src/net/routing/interceptor/authorization.rs @@ -199,7 +199,6 @@ impl PolicyEnforcer { &self, config_rule_set: &Vec, ) -> ZResult { - println!("start policy info point{:?}", config_rule_set); let mut policy_rules: Vec = Vec::new(); for config_rule in config_rule_set { for flow in &config_rule.flows { diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs new file mode 100644 index 0000000000..8d377ed3df --- /dev/null +++ b/zenoh/tests/authentication.rs @@ -0,0 +1,729 @@ +// +// Copyright (c) 2024 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// +// Contributors: +// ZettaScale Zenoh Team, +// +#![cfg(target_family = "unix")] +mod test { + use std::sync::{Arc, Mutex}; + use std::time::Duration; + use tokio::runtime::Handle; + use zenoh::prelude::r#async::*; + use zenoh_core::{zlock, ztimeout}; + + const TIMEOUT: Duration = Duration::from_secs(60); + const SLEEP: Duration = Duration::from_secs(1); + const KEY_EXPR: &str = "test/demo"; + const VALUE: &str = "zenoh"; + + #[tokio::test(flavor = "multi_thread", worker_threads = 4)] + async fn test_acl() { + zenoh_util::try_init_log_from_env(); + test_pub_sub_deny_then_allow_tls().await; + test_pub_sub_allow_then_deny_tls().await; + test_get_qbl_allow_then_deny_tls().await; + test_get_qbl_deny_then_allow_tls().await; + test_pub_sub_deny_then_allow_quic().await; + test_pub_sub_allow_then_deny_quic().await; + test_get_qbl_allow_then_deny_quic().await; + test_get_qbl_deny_then_allow_quic().await; + } + async fn get_basic_router_config_tls() -> Config { + let mut config = config::default(); + config.set_mode(Some(WhatAmI::Router)).unwrap(); + config.listen.endpoints = vec!["tls/127.0.0.1:7447".parse().unwrap()]; + config.scouting.multicast.set_enabled(Some(false)).unwrap(); + config + .insert_json5( + "transport", + r#"{ + "link": { + "protocols": [ + "tls" + ], + "tls": { + "server_private_key": "tests/testfiles/serversidekey.pem", + "server_certificate": "tests/testfiles/serverside.pem", + "root_ca_certificate": "tests/testfiles/ca.pem", + "client_auth": true, + "server_name_verification": false + }, + }, + }"#, + ) + .unwrap(); + config + } + async fn get_basic_router_config_quic() -> Config { + let mut config = config::default(); + config.set_mode(Some(WhatAmI::Router)).unwrap(); + config.listen.endpoints = vec!["quic/127.0.0.1:7447".parse().unwrap()]; + config.scouting.multicast.set_enabled(Some(false)).unwrap(); + config + .insert_json5( + "transport", + r#"{ + "link": { + "protocols": [ + "quic" + ], + "tls": { + "server_private_key": "tests/testfiles/serversidekey.pem", + "server_certificate": "tests/testfiles/serverside.pem", + "root_ca_certificate": "tests/testfiles/ca.pem", + "client_auth": true, + "server_name_verification": false + }, + }, + }"#, + ) + .unwrap(); + config + } + async fn close_router_session(s: Session) { + println!("Closing router session"); + ztimeout!(s.close().res_async()).unwrap(); + } + + async fn get_client_sessions_tls() -> (Session, Session) { + println!("Opening client sessions"); + let mut config = config::client(["tls/127.0.0.1:7447".parse::().unwrap()]); + config + .insert_json5( + "transport", + r#"{ + "link": { + "protocols": [ + "tls" + ], + "tls": { + "root_ca_certificate": "tests/testfiles/ca.pem", + "client_private_key": "tests/testfiles/clientsidekey.pem", + "client_certificate": "tests/testfiles/clientside.pem", + "client_auth": true, + "server_name_verification": false + } + } + }"#, + ) + .unwrap(); + let s01 = ztimeout!(zenoh::open(config).res_async()).unwrap(); + let mut config = config::client(["tls/127.0.0.1:7447".parse::().unwrap()]); + config + .insert_json5( + "transport", + r#"{ + "link": { + "protocols": [ + "tls" + ], + "tls": { + "root_ca_certificate": "tests/testfiles/ca.pem", + "client_private_key": "tests/testfiles/clientsidekey.pem", + "client_certificate": "tests/testfiles/clientside.pem", + "client_auth": true, + "server_name_verification": false + } + } + }"#, + ) + .unwrap(); + let s02 = ztimeout!(zenoh::open(config).res_async()).unwrap(); + (s01, s02) + } + + async fn get_client_sessions_quic() -> (Session, Session) { + println!("Opening client sessions"); + let mut config = config::client(["quic/127.0.0.1:7447".parse::().unwrap()]); + config + .insert_json5( + "transport", + r#"{ + "link": { + "protocols": [ + "quic" + ], + "tls": { + "root_ca_certificate": "tests/testfiles/ca.pem", + "client_private_key": "tests/testfiles/clientsidekey.pem", + "client_certificate": "tests/testfiles/clientside.pem", + "client_auth": true, + "server_name_verification": false + } + } + }"#, + ) + .unwrap(); + let s01 = ztimeout!(zenoh::open(config).res_async()).unwrap(); + let mut config = config::client(["quic/127.0.0.1:7447".parse::().unwrap()]); + config + .insert_json5( + "transport", + r#"{ + "link": { + "protocols": [ + "quic" + ], + "tls": { + "root_ca_certificate": "tests/testfiles/ca.pem", + "client_private_key": "tests/testfiles/clientsidekey.pem", + "client_certificate": "tests/testfiles/clientside.pem", + "client_auth": true, + "server_name_verification": false + } + } + }"#, + ) + .unwrap(); + let s02 = ztimeout!(zenoh::open(config).res_async()).unwrap(); + (s01, s02) + } + + async fn close_sessions(s01: Session, s02: Session) { + println!("Closing client sessions"); + ztimeout!(s01.close().res_async()).unwrap(); + ztimeout!(s02.close().res_async()).unwrap(); + } + + async fn test_pub_sub_deny_then_allow_tls() { + println!("test_pub_sub_deny_then_allow_tls"); + + let mut config_router = get_basic_router_config_tls().await; + + config_router + .insert_json5( + "access_control", + r#"{ + + "enabled": false, + "default_permission": "deny", + "rules": + [ + { + "permission": "allow", + "flows": ["ingress","egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + }"#, + ) + .unwrap(); + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + + let (sub_session, pub_session) = get_client_sessions_tls().await; + { + let publisher = pub_session + .declare_publisher(KEY_EXPR) + .res_async() + .await + .unwrap(); + let received_value = Arc::new(Mutex::new(String::new())); + let temp_recv_value = received_value.clone(); + let subscriber = sub_session + .declare_subscriber(KEY_EXPR) + .callback(move |sample| { + let mut temp_value = zlock!(temp_recv_value); + *temp_value = sample.value.to_string(); + }) + .res_async() + .await + .unwrap(); + + tokio::time::sleep(SLEEP).await; + publisher.put(VALUE).res_async().await.unwrap(); + tokio::time::sleep(SLEEP).await; + assert_eq!(*zlock!(received_value), VALUE); + ztimeout!(subscriber.undeclare().res_async()).unwrap(); + } + close_sessions(sub_session, pub_session).await; + close_router_session(session).await; + } + + async fn test_pub_sub_allow_then_deny_tls() { + println!("test_pub_sub_allow_then_deny_tls"); + + let mut config_router = get_basic_router_config_tls().await; + config_router + .insert_json5( + "access_control", + r#" + {"enabled": true, + "default_permission": "allow", + "rules": + [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + } + "#, + ) + .unwrap(); + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + let (sub_session, pub_session) = get_client_sessions_tls().await; + { + let publisher = ztimeout!(pub_session.declare_publisher(KEY_EXPR).res_async()).unwrap(); + let received_value = Arc::new(Mutex::new(String::new())); + let temp_recv_value = received_value.clone(); + let subscriber = ztimeout!(sub_session + .declare_subscriber(KEY_EXPR) + .callback(move |sample| { + let mut temp_value = zlock!(temp_recv_value); + *temp_value = sample.value.to_string(); + }) + .res_async()) + .unwrap(); + + tokio::time::sleep(SLEEP).await; + + ztimeout!(publisher.put(VALUE).res_async()).unwrap(); + tokio::time::sleep(SLEEP).await; + + assert_ne!(*zlock!(received_value), VALUE); + ztimeout!(subscriber.undeclare().res_async()).unwrap(); + } + close_sessions(sub_session, pub_session).await; + close_router_session(session).await; + } + + async fn test_get_qbl_deny_then_allow_tls() { + println!("test_get_qbl_deny_then_allow_tls"); + + let mut config_router = get_basic_router_config_tls().await; + config_router + .insert_json5( + "access_control", + r#" + {"enabled": true, + "default_permission": "deny", + "rules": + [ + { + "permission": "allow", + "flows": ["egress","ingress"], + "actions": [ + "get", + "declare_queryable"], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + } + "#, + ) + .unwrap(); + + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + + let (get_session, qbl_session) = get_client_sessions_tls().await; + { + let mut received_value = String::new(); + + let qbl = ztimeout!(qbl_session + .declare_queryable(KEY_EXPR) + .callback(move |sample| { + let rep = Sample::try_from(KEY_EXPR, VALUE).unwrap(); + tokio::task::block_in_place(move || { + Handle::current().block_on(async move { + ztimeout!(sample.reply(Ok(rep)).res_async()).unwrap() + }); + }); + }) + .res_async()) + .unwrap(); + + tokio::time::sleep(SLEEP).await; + let recv_reply = ztimeout!(get_session.get(KEY_EXPR).res_async()).unwrap(); + while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { + match reply.sample { + Ok(sample) => { + received_value = sample.value.to_string(); + break; + } + Err(e) => println!("Error : {}", e), + } + } + tokio::time::sleep(SLEEP).await; + assert_eq!(received_value, VALUE); + ztimeout!(qbl.undeclare().res_async()).unwrap(); + } + close_sessions(get_session, qbl_session).await; + close_router_session(session).await; + } + + async fn test_get_qbl_allow_then_deny_tls() { + println!("test_get_qbl_allow_then_deny_tls"); + + let mut config_router = get_basic_router_config_tls().await; + config_router + .insert_json5( + "access_control", + r#" + {"enabled": true, + "default_permission": "allow", + "rules": + [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "get", + "declare_queryable" ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + } + "#, + ) + .unwrap(); + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + + let (get_session, qbl_session) = get_client_sessions_tls().await; + { + let mut received_value = String::new(); + + let qbl = ztimeout!(qbl_session + .declare_queryable(KEY_EXPR) + .callback(move |sample| { + let rep = Sample::try_from(KEY_EXPR, VALUE).unwrap(); + tokio::task::block_in_place(move || { + Handle::current().block_on(async move { + ztimeout!(sample.reply(Ok(rep)).res_async()).unwrap() + }); + }); + }) + .res_async()) + .unwrap(); + + tokio::time::sleep(SLEEP).await; + let recv_reply = ztimeout!(get_session.get(KEY_EXPR).res_async()).unwrap(); + while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { + match reply.sample { + Ok(sample) => { + received_value = sample.value.to_string(); + break; + } + Err(e) => println!("Error : {}", e), + } + } + tokio::time::sleep(SLEEP).await; + assert_ne!(received_value, VALUE); + ztimeout!(qbl.undeclare().res_async()).unwrap(); + } + close_sessions(get_session, qbl_session).await; + close_router_session(session).await; + } + + async fn test_pub_sub_deny_then_allow_quic() { + println!("test_pub_sub_deny_then_allow_quic"); + + let mut config_router = get_basic_router_config_quic().await; + + config_router + .insert_json5( + "access_control", + r#"{ + + "enabled": false, + "default_permission": "deny", + "rules": + [ + { + "permission": "allow", + "flows": ["ingress","egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + }"#, + ) + .unwrap(); + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + + let (sub_session, pub_session) = get_client_sessions_quic().await; + { + let publisher = pub_session + .declare_publisher(KEY_EXPR) + .res_async() + .await + .unwrap(); + let received_value = Arc::new(Mutex::new(String::new())); + let temp_recv_value = received_value.clone(); + let subscriber = sub_session + .declare_subscriber(KEY_EXPR) + .callback(move |sample| { + let mut temp_value = zlock!(temp_recv_value); + *temp_value = sample.value.to_string(); + }) + .res_async() + .await + .unwrap(); + + tokio::time::sleep(SLEEP).await; + publisher.put(VALUE).res_async().await.unwrap(); + tokio::time::sleep(SLEEP).await; + assert_eq!(*zlock!(received_value), VALUE); + ztimeout!(subscriber.undeclare().res_async()).unwrap(); + } + close_sessions(sub_session, pub_session).await; + close_router_session(session).await; + } + + async fn test_pub_sub_allow_then_deny_quic() { + println!("test_pub_sub_allow_then_deny_quic"); + + let mut config_router = get_basic_router_config_quic().await; + config_router + .insert_json5( + "access_control", + r#" + {"enabled": true, + "default_permission": "allow", + "rules": + [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] +} +"#, + ) + .unwrap(); + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + let (sub_session, pub_session) = get_client_sessions_quic().await; + { + let publisher = ztimeout!(pub_session.declare_publisher(KEY_EXPR).res_async()).unwrap(); + let received_value = Arc::new(Mutex::new(String::new())); + let temp_recv_value = received_value.clone(); + let subscriber = ztimeout!(sub_session + .declare_subscriber(KEY_EXPR) + .callback(move |sample| { + let mut temp_value = zlock!(temp_recv_value); + *temp_value = sample.value.to_string(); + }) + .res_async()) + .unwrap(); + + tokio::time::sleep(SLEEP).await; + + ztimeout!(publisher.put(VALUE).res_async()).unwrap(); + tokio::time::sleep(SLEEP).await; + + assert_ne!(*zlock!(received_value), VALUE); + ztimeout!(subscriber.undeclare().res_async()).unwrap(); + } + close_sessions(sub_session, pub_session).await; + close_router_session(session).await; + } + + async fn test_get_qbl_deny_then_allow_quic() { + println!("test_get_qbl_deny_then_allow_quic"); + + let mut config_router = get_basic_router_config_quic().await; + // config_router.listen.endpoints = vec!["quic/127.0.0.1:7447".parse().unwrap()]; + config_router + .insert_json5( + "access_control", + r#" + {"enabled": true, + "default_permission": "deny", + "rules": + [ + { + "permission": "allow", + "flows": ["egress","ingress"], + "actions": [ + "get", + "declare_queryable"], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] +} +"#, + ) + .unwrap(); + + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + + let (get_session, qbl_session) = get_client_sessions_quic().await; + { + let mut received_value = String::new(); + + let qbl = ztimeout!(qbl_session + .declare_queryable(KEY_EXPR) + .callback(move |sample| { + let rep = Sample::try_from(KEY_EXPR, VALUE).unwrap(); + tokio::task::block_in_place(move || { + Handle::current().block_on(async move { + ztimeout!(sample.reply(Ok(rep)).res_async()).unwrap() + }); + }); + }) + .res_async()) + .unwrap(); + + tokio::time::sleep(SLEEP).await; + let recv_reply = ztimeout!(get_session.get(KEY_EXPR).res_async()).unwrap(); + while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { + match reply.sample { + Ok(sample) => { + received_value = sample.value.to_string(); + break; + } + Err(e) => println!("Error : {}", e), + } + } + tokio::time::sleep(SLEEP).await; + assert_eq!(received_value, VALUE); + ztimeout!(qbl.undeclare().res_async()).unwrap(); + } + close_sessions(get_session, qbl_session).await; + close_router_session(session).await; + } + + async fn test_get_qbl_allow_then_deny_quic() { + println!("test_get_qbl_allow_then_deny_quic"); + + let mut config_router = get_basic_router_config_quic().await; + // config_router.listen.endpoints = vec!["quic/127.0.0.1:7447".parse().unwrap()]; + config_router + .insert_json5( + "access_control", + r#" + {"enabled": true, + "default_permission": "allow", + "rules": + [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "get", + "declare_queryable" ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] +} +"#, + ) + .unwrap(); + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + + let (get_session, qbl_session) = get_client_sessions_quic().await; + { + let mut received_value = String::new(); + + let qbl = ztimeout!(qbl_session + .declare_queryable(KEY_EXPR) + .callback(move |sample| { + let rep = Sample::try_from(KEY_EXPR, VALUE).unwrap(); + tokio::task::block_in_place(move || { + Handle::current().block_on(async move { + ztimeout!(sample.reply(Ok(rep)).res_async()).unwrap() + }); + }); + }) + .res_async()) + .unwrap(); + + tokio::time::sleep(SLEEP).await; + let recv_reply = ztimeout!(get_session.get(KEY_EXPR).res_async()).unwrap(); + while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { + match reply.sample { + Ok(sample) => { + received_value = sample.value.to_string(); + break; + } + Err(e) => println!("Error : {}", e), + } + } + tokio::time::sleep(SLEEP).await; + assert_ne!(received_value, VALUE); + ztimeout!(qbl.undeclare().res_async()).unwrap(); + } + close_sessions(get_session, qbl_session).await; + close_router_session(session).await; + } +} From bfeaa5384d8dd86182b3610ba0dadbd4e3619cc8 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Thu, 2 May 2024 13:07:38 +0530 Subject: [PATCH 24/37] add tests for user-password --- .../net/routing/interceptor/authorization.rs | 2 - zenoh/tests/authentication.rs | 337 +++++++++++++++++- 2 files changed, 336 insertions(+), 3 deletions(-) diff --git a/zenoh/src/net/routing/interceptor/authorization.rs b/zenoh/src/net/routing/interceptor/authorization.rs index 4cd9aa063a..30faa85228 100644 --- a/zenoh/src/net/routing/interceptor/authorization.rs +++ b/zenoh/src/net/routing/interceptor/authorization.rs @@ -181,7 +181,6 @@ impl PolicyEnforcer { } }; } - println!("main policy{}", main_policy.len()); self.policy_map = main_policy; self.subject_map = subject_map; } @@ -263,7 +262,6 @@ impl PolicyEnforcer { counter += 1; } } - println!("subject map {:?}policy map{:?}", subject_map, policy_rules); Ok(PolicyInformation { subject_map, policy_rules, diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs index 8d377ed3df..a24906ac43 100644 --- a/zenoh/tests/authentication.rs +++ b/zenoh/tests/authentication.rs @@ -25,12 +25,16 @@ mod test { const VALUE: &str = "zenoh"; #[tokio::test(flavor = "multi_thread", worker_threads = 4)] - async fn test_acl() { + async fn test_authentication() { zenoh_util::try_init_log_from_env(); test_pub_sub_deny_then_allow_tls().await; test_pub_sub_allow_then_deny_tls().await; test_get_qbl_allow_then_deny_tls().await; test_get_qbl_deny_then_allow_tls().await; + test_pub_sub_deny_then_allow_usrpswd().await; + test_pub_sub_allow_then_deny_usrpswd().await; + test_get_qbl_allow_then_deny_usrpswd().await; + test_get_qbl_deny_then_allow_usrpswd().await; test_pub_sub_deny_then_allow_quic().await; test_pub_sub_allow_then_deny_quic().await; test_get_qbl_allow_then_deny_quic().await; @@ -88,6 +92,28 @@ mod test { .unwrap(); config } + + async fn get_basic_router_config_usrpswd() -> Config { + let mut config = config::default(); + config.set_mode(Some(WhatAmI::Router)).unwrap(); + config.listen.endpoints = vec!["tcp/127.0.0.1:7447".parse().unwrap()]; + config.scouting.multicast.set_enabled(Some(false)).unwrap(); + config + .insert_json5( + "transport", + r#"{ + "auth": { + usrpwd: { + user: "routername", + password: "routerpasswd", + dictionary_file: "tests/testfiles/credentials.txt", + }, + }, + }"#, + ) + .unwrap(); + config + } async fn close_router_session(s: Session) { println!("Closing router session"); ztimeout!(s.close().res_async()).unwrap(); @@ -187,6 +213,45 @@ mod test { (s01, s02) } + async fn get_client_sessions_usrpswd() -> (Session, Session) { + println!("Opening client sessions"); + let mut config = config::client(["tcp/127.0.0.1:7447".parse::().unwrap()]); + config + .insert_json5( + "transport", + r#"{ + "auth": { + usrpwd: { + user: "client1name", + password: "client1passwd", + }, + + } + }"#, + ) + .unwrap(); + let s01 = ztimeout!(zenoh::open(config).res_async()).unwrap(); + let mut config = config::client(["tcp/127.0.0.1:7447".parse::().unwrap()]); + config + .insert_json5( + "transport", + r#"{ + + "auth": { + usrpwd: { + user: "client2name", + password: "client2passwd", + }, + + } + + }"#, + ) + .unwrap(); + let s02 = ztimeout!(zenoh::open(config).res_async()).unwrap(); + (s01, s02) + } + async fn close_sessions(s01: Session, s02: Session) { println!("Closing client sessions"); ztimeout!(s01.close().res_async()).unwrap(); @@ -525,6 +590,8 @@ mod test { } async fn test_pub_sub_allow_then_deny_quic() { + tokio::time::sleep(SLEEP).await; + println!("test_pub_sub_allow_then_deny_quic"); let mut config_router = get_basic_router_config_quic().await; @@ -726,4 +793,272 @@ mod test { close_sessions(get_session, qbl_session).await; close_router_session(session).await; } + + async fn test_pub_sub_deny_then_allow_usrpswd() { + println!("test_pub_sub_deny_then_allow_usrpswd"); + + let mut config_router = get_basic_router_config_usrpswd().await; + + config_router + .insert_json5( + "access_control", + r#"{ + + "enabled": false, + "default_permission": "deny", + "rules": + [ + { + "permission": "allow", + "flows": ["ingress","egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "usernames": [ + "client1name","client2name" + ] + }, + ] + }"#, + ) + .unwrap(); + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + + let (sub_session, pub_session) = get_client_sessions_usrpswd().await; + { + let publisher = pub_session + .declare_publisher(KEY_EXPR) + .res_async() + .await + .unwrap(); + let received_value = Arc::new(Mutex::new(String::new())); + let temp_recv_value = received_value.clone(); + let subscriber = sub_session + .declare_subscriber(KEY_EXPR) + .callback(move |sample| { + let mut temp_value = zlock!(temp_recv_value); + *temp_value = sample.value.to_string(); + }) + .res_async() + .await + .unwrap(); + + tokio::time::sleep(SLEEP).await; + publisher.put(VALUE).res_async().await.unwrap(); + tokio::time::sleep(SLEEP).await; + assert_eq!(*zlock!(received_value), VALUE); + ztimeout!(subscriber.undeclare().res_async()).unwrap(); + } + close_sessions(sub_session, pub_session).await; + close_router_session(session).await; + } + + async fn test_pub_sub_allow_then_deny_usrpswd() { + println!("test_pub_sub_allow_then_deny_usrpswd"); + + let mut config_router = get_basic_router_config_usrpswd().await; + config_router + .insert_json5( + "access_control", + r#" + {"enabled": true, + "default_permission": "allow", + "rules": + [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "usernames": [ + "client1name","client2name" + ] + }, + ] +} +"#, + ) + .unwrap(); + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + let (sub_session, pub_session) = get_client_sessions_usrpswd().await; + { + let publisher = ztimeout!(pub_session.declare_publisher(KEY_EXPR).res_async()).unwrap(); + let received_value = Arc::new(Mutex::new(String::new())); + let temp_recv_value = received_value.clone(); + let subscriber = ztimeout!(sub_session + .declare_subscriber(KEY_EXPR) + .callback(move |sample| { + let mut temp_value = zlock!(temp_recv_value); + *temp_value = sample.value.to_string(); + }) + .res_async()) + .unwrap(); + + tokio::time::sleep(SLEEP).await; + + ztimeout!(publisher.put(VALUE).res_async()).unwrap(); + tokio::time::sleep(SLEEP).await; + + assert_ne!(*zlock!(received_value), VALUE); + ztimeout!(subscriber.undeclare().res_async()).unwrap(); + } + close_sessions(sub_session, pub_session).await; + close_router_session(session).await; + } + + async fn test_get_qbl_deny_then_allow_usrpswd() { + println!("test_get_qbl_deny_then_allow_usrpswd"); + + let mut config_router = get_basic_router_config_usrpswd().await; + // config_router.listen.endpoints = vec!["quic/127.0.0.1:7447".parse().unwrap()]; + config_router + .insert_json5( + "access_control", + r#" + {"enabled": true, + "default_permission": "deny", + "rules": + [ + { + "permission": "allow", + "flows": ["egress","ingress"], + "actions": [ + "get", + "declare_queryable"], + "key_exprs": [ + "test/demo" + ], + "usernames": [ + "client1name","client2name" + ] + }, + ] +} +"#, + ) + .unwrap(); + + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + + let (get_session, qbl_session) = get_client_sessions_usrpswd().await; + { + let mut received_value = String::new(); + + let qbl = ztimeout!(qbl_session + .declare_queryable(KEY_EXPR) + .callback(move |sample| { + let rep = Sample::try_from(KEY_EXPR, VALUE).unwrap(); + tokio::task::block_in_place(move || { + Handle::current().block_on(async move { + ztimeout!(sample.reply(Ok(rep)).res_async()).unwrap() + }); + }); + }) + .res_async()) + .unwrap(); + + tokio::time::sleep(SLEEP).await; + let recv_reply = ztimeout!(get_session.get(KEY_EXPR).res_async()).unwrap(); + while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { + match reply.sample { + Ok(sample) => { + received_value = sample.value.to_string(); + break; + } + Err(e) => println!("Error : {}", e), + } + } + tokio::time::sleep(SLEEP).await; + assert_eq!(received_value, VALUE); + ztimeout!(qbl.undeclare().res_async()).unwrap(); + } + close_sessions(get_session, qbl_session).await; + close_router_session(session).await; + } + + async fn test_get_qbl_allow_then_deny_usrpswd() { + println!("test_get_qbl_allow_then_deny_usrpswd"); + + let mut config_router = get_basic_router_config_usrpswd().await; + // config_router.listen.endpoints = vec!["quic/127.0.0.1:7447".parse().unwrap()]; + config_router + .insert_json5( + "access_control", + r#" + {"enabled": true, + "default_permission": "allow", + "rules": + [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "get", + "declare_queryable" ], + "key_exprs": [ + "test/demo" + ], + "usernames": [ + "client1name","client2name" + ] + }, + ] +} +"#, + ) + .unwrap(); + println!("Opening router session"); + + let session = ztimeout!(zenoh::open(config_router).res_async()).unwrap(); + + let (get_session, qbl_session) = get_client_sessions_usrpswd().await; + { + let mut received_value = String::new(); + + let qbl = ztimeout!(qbl_session + .declare_queryable(KEY_EXPR) + .callback(move |sample| { + let rep = Sample::try_from(KEY_EXPR, VALUE).unwrap(); + tokio::task::block_in_place(move || { + Handle::current().block_on(async move { + ztimeout!(sample.reply(Ok(rep)).res_async()).unwrap() + }); + }); + }) + .res_async()) + .unwrap(); + + tokio::time::sleep(SLEEP).await; + let recv_reply = ztimeout!(get_session.get(KEY_EXPR).res_async()).unwrap(); + while let Ok(reply) = ztimeout!(recv_reply.recv_async()) { + match reply.sample { + Ok(sample) => { + received_value = sample.value.to_string(); + break; + } + Err(e) => println!("Error : {}", e), + } + } + tokio::time::sleep(SLEEP).await; + assert_ne!(received_value, VALUE); + ztimeout!(qbl.undeclare().res_async()).unwrap(); + } + close_sessions(get_session, qbl_session).await; + close_router_session(session).await; + } } From 0513918b2ddbef65d14eec970ac0beb47bf13f1e Mon Sep 17 00:00:00 2001 From: snehilzs Date: Thu, 2 May 2024 14:45:53 +0530 Subject: [PATCH 25/37] remove format error --- io/zenoh-transport/src/unicast/establishment/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/io/zenoh-transport/src/unicast/establishment/mod.rs b/io/zenoh-transport/src/unicast/establishment/mod.rs index b1ced8b960..f79aa826d0 100644 --- a/io/zenoh-transport/src/unicast/establishment/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/mod.rs @@ -83,7 +83,6 @@ pub trait AcceptFsm { ) -> Result; type RecvOpenSynIn; - type RecvOpenSynOut; async fn recv_open_syn( self, From b999a210646ab90f79300f12f83e130996b6bbfd Mon Sep 17 00:00:00 2001 From: snehilzs Date: Fri, 3 May 2024 17:54:32 +0530 Subject: [PATCH 26/37] ignore tests without testfiles --- zenoh/tests/authentication.rs | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs index da313e465e..9dd5cb92af 100644 --- a/zenoh/tests/authentication.rs +++ b/zenoh/tests/authentication.rs @@ -22,7 +22,7 @@ mod test { const SLEEP: Duration = Duration::from_secs(1); const KEY_EXPR: &str = "test/demo"; const VALUE: &str = "zenoh"; - + #[ignore] #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn test_authentication() { zenoh_util::try_init_log_from_env(); @@ -30,14 +30,14 @@ mod test { test_pub_sub_allow_then_deny_tls().await; test_get_qbl_allow_then_deny_tls().await; test_get_qbl_deny_then_allow_tls().await; - test_pub_sub_deny_then_allow_usrpswd().await; - test_pub_sub_allow_then_deny_usrpswd().await; - test_get_qbl_allow_then_deny_usrpswd().await; - test_get_qbl_deny_then_allow_usrpswd().await; test_pub_sub_deny_then_allow_quic().await; test_pub_sub_allow_then_deny_quic().await; test_get_qbl_allow_then_deny_quic().await; test_get_qbl_deny_then_allow_quic().await; + test_pub_sub_deny_then_allow_usrpswd().await; + test_pub_sub_allow_then_deny_usrpswd().await; + test_get_qbl_allow_then_deny_usrpswd().await; + test_get_qbl_deny_then_allow_usrpswd().await; } async fn get_basic_router_config_tls() -> Config { let mut config = config::default(); @@ -224,7 +224,6 @@ mod test { user: "client1name", password: "client1passwd", }, - } }"#, ) @@ -324,7 +323,6 @@ mod test { async fn test_pub_sub_allow_then_deny_tls() { println!("test_pub_sub_allow_then_deny_tls"); - let mut config_router = get_basic_router_config_tls().await; config_router .insert_json5( @@ -588,9 +586,8 @@ mod test { close_router_session(session).await; } + #[allow(unused)] async fn test_pub_sub_allow_then_deny_quic() { - tokio::time::sleep(SLEEP).await; - println!("test_pub_sub_allow_then_deny_quic"); let mut config_router = get_basic_router_config_quic().await; @@ -650,11 +647,11 @@ mod test { close_router_session(session).await; } + #[allow(unused)] async fn test_get_qbl_deny_then_allow_quic() { println!("test_get_qbl_deny_then_allow_quic"); let mut config_router = get_basic_router_config_quic().await; - // config_router.listen.endpoints = vec!["quic/127.0.0.1:7447".parse().unwrap()]; config_router .insert_json5( "access_control", @@ -722,11 +719,11 @@ mod test { close_router_session(session).await; } + #[allow(unused)] async fn test_get_qbl_allow_then_deny_quic() { println!("test_get_qbl_allow_then_deny_quic"); let mut config_router = get_basic_router_config_quic().await; - // config_router.listen.endpoints = vec!["quic/127.0.0.1:7447".parse().unwrap()]; config_router .insert_json5( "access_control", @@ -922,7 +919,6 @@ mod test { println!("test_get_qbl_deny_then_allow_usrpswd"); let mut config_router = get_basic_router_config_usrpswd().await; - // config_router.listen.endpoints = vec!["quic/127.0.0.1:7447".parse().unwrap()]; config_router .insert_json5( "access_control", @@ -994,7 +990,6 @@ mod test { println!("test_get_qbl_allow_then_deny_usrpswd"); let mut config_router = get_basic_router_config_usrpswd().await; - // config_router.listen.endpoints = vec!["quic/127.0.0.1:7447".parse().unwrap()]; config_router .insert_json5( "access_control", From ae40b9cca4bf88f451467ac1d0eb7be4b5486cf8 Mon Sep 17 00:00:00 2001 From: snehilzs Date: Fri, 3 May 2024 18:23:32 +0530 Subject: [PATCH 27/37] remove shm test errors --- .../src/unicast/establishment/ext/auth/mod.rs | 18 +++++++++++------- zenoh/tests/authentication.rs | 8 ++++---- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs index a1a5598679..18372b63f8 100644 --- a/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs +++ b/io/zenoh-transport/src/unicast/establishment/ext/auth/mod.rs @@ -571,16 +571,17 @@ impl<'a> AcceptFsm for &'a AuthFsm<'a> { } type RecvOpenSynIn = (&'a mut StateAccept, Option); - #[cfg(feature = "auth_usrpwd")] + #[cfg(not(feature = "auth_usrpwd"))] + type RecvOpenSynOut = (); + #[cfg(feature = "auth_usrpwd")] type RecvOpenSynOut = UsrPwdId; + async fn recv_open_syn( self, input: Self::RecvOpenSynIn, ) -> Result { const S: &str = "Auth extension - Recv OpenSyn."; - #[cfg(feature = "transport_auth")] - let mut user_passwd_id = UsrPwdId(None); let (state, ext) = input; let ext = ext.unwrap_or(init::ext::Auth::new(ZBuf::empty())); @@ -609,14 +610,17 @@ impl<'a> AcceptFsm for &'a AuthFsm<'a> { (Some(e), Some(s)) => { let x = ztake!(exts, id::USRPWD); let username = e.recv_open_syn((s, ztryinto!(x, S))).await?; - user_passwd_id = UsrPwdId(Some(username)); + let user_passwd_id = UsrPwdId(Some(username)); + return Ok(user_passwd_id); + } + (None, None) => { + return Ok(UsrPwdId(None)); } - (None, None) => {} _ => bail!("{S} Invalid UsrPwd configuration."), } } - - Ok(user_passwd_id) + #[cfg(not(feature = "auth_usrpwd"))] + Ok(()) } type SendOpenAckIn = &'a StateAccept; diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs index 9dd5cb92af..e11ded802b 100644 --- a/zenoh/tests/authentication.rs +++ b/zenoh/tests/authentication.rs @@ -30,14 +30,14 @@ mod test { test_pub_sub_allow_then_deny_tls().await; test_get_qbl_allow_then_deny_tls().await; test_get_qbl_deny_then_allow_tls().await; - test_pub_sub_deny_then_allow_quic().await; - test_pub_sub_allow_then_deny_quic().await; - test_get_qbl_allow_then_deny_quic().await; - test_get_qbl_deny_then_allow_quic().await; test_pub_sub_deny_then_allow_usrpswd().await; test_pub_sub_allow_then_deny_usrpswd().await; test_get_qbl_allow_then_deny_usrpswd().await; test_get_qbl_deny_then_allow_usrpswd().await; + test_pub_sub_deny_then_allow_quic().await; + test_pub_sub_allow_then_deny_quic().await; + test_get_qbl_allow_then_deny_quic().await; + test_get_qbl_deny_then_allow_quic().await; } async fn get_basic_router_config_tls() -> Config { let mut config = config::default(); From 58739b19dd35782bd6a99fadef412ad7a37fbe5d Mon Sep 17 00:00:00 2001 From: snehilzs Date: Fri, 3 May 2024 19:48:58 +0530 Subject: [PATCH 28/37] remove typos --- zenoh/src/net/routing/interceptor/authorization.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zenoh/src/net/routing/interceptor/authorization.rs b/zenoh/src/net/routing/interceptor/authorization.rs index 0fd41b7c55..08e1400960 100644 --- a/zenoh/src/net/routing/interceptor/authorization.rs +++ b/zenoh/src/net/routing/interceptor/authorization.rs @@ -179,14 +179,14 @@ impl PolicyEnforcer { match rule.usernames { Some(_) => (), None => { - tracing::warn!("ACL config usernames list is empty. Applying rule #{} to all network interfaces", rule_offset); + tracing::warn!("ACL config usernames list is empty. Applying rule #{} to all usernames", rule_offset); rule.usernames = Some(Vec::new()); } } match rule.cert_common_names { Some(_) => (), None => { - tracing::warn!("ACL config cert_common_names list is empty. Applying rule #{} to all network interfaces", rule_offset); + tracing::warn!("ACL config cert_common_names list is empty. Applying rule #{} to all certificate common names", rule_offset); rule.cert_common_names = Some(Vec::new()); } } From bb16d4cdfb38693f5b7ac71e5e4f1cc51e19cbcb Mon Sep 17 00:00:00 2001 From: snehilzs Date: Sat, 4 May 2024 12:08:30 +0530 Subject: [PATCH 29/37] add testfiles for authn --- zenoh/tests/authentication.rs | 194 +++++++++++++++++++++++++++++++++- 1 file changed, 190 insertions(+), 4 deletions(-) diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs index e11ded802b..f3400c0acb 100644 --- a/zenoh/tests/authentication.rs +++ b/zenoh/tests/authentication.rs @@ -18,14 +18,20 @@ mod test { use zenoh::prelude::r#async::*; use zenoh_core::{zlock, ztimeout}; + use std::fs; + use std::path::Path; + const TIMEOUT: Duration = Duration::from_secs(60); const SLEEP: Duration = Duration::from_secs(1); const KEY_EXPR: &str = "test/demo"; const VALUE: &str = "zenoh"; - #[ignore] #[tokio::test(flavor = "multi_thread", worker_threads = 4)] async fn test_authentication() { zenoh_util::try_init_log_from_env(); + let path = "./tests/testfiles"; + create_new_files(path).await.unwrap(); + println!("testfiles created successfully."); + test_pub_sub_deny_then_allow_tls().await; test_pub_sub_allow_then_deny_tls().await; test_get_qbl_allow_then_deny_tls().await; @@ -35,10 +41,190 @@ mod test { test_get_qbl_allow_then_deny_usrpswd().await; test_get_qbl_deny_then_allow_usrpswd().await; test_pub_sub_deny_then_allow_quic().await; - test_pub_sub_allow_then_deny_quic().await; - test_get_qbl_allow_then_deny_quic().await; - test_get_qbl_deny_then_allow_quic().await; + // test_get_qbl_allow_then_deny_quic().await; + // test_pub_sub_allow_then_deny_quic().await; + // test_get_qbl_deny_then_allow_quic().await; + + use std::fs::remove_dir_all; + tokio::time::sleep(Duration::from_secs(1)).await; + remove_dir_all(path).unwrap(); + println!("testfiles removed successfully."); + } + + #[allow(clippy::all)] + async fn create_new_files(file_path: &str) -> std::io::Result<()> { + use std::io::prelude::*; + let ca_pem = b"-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUO1x6LAlICgKs5+pYUTo4CughfKEwDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTExNDM0MjNaFw0yNTAzMTExNDM0MjNaMFQxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRgwFgYDVQQDDA96 +c190ZXN0X3Jvb3RfY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3 +pFWM+IJNsRCYHt1v/TliecppwVZV+ZHfFw9JKN9ev4K/fWHUiAOwp91MOLxbaYKd +C6dxW28YVGltoGz3kUZJZcJRQVso1jXv24Op4muOsiYXukLc4TU2F6dG1XqkLt5t +svsYAQFf1uK3//QZFVRBosJEn+jjiJ4XCvt49mnPRolp1pNKX0z31mZO6bSly6c9 +OVlJMjWpDCYSOuf6qZZ36fa9eSut2bRJIPY0QCsgnqYBTnIEhksS+3jy6Qt+QpLz +95pFdLbW/MW4XKpaDltyYkO6QrBekF6uWRlvyAHU+NqvXZ4F/3Z5l26qLuBcsLPJ +kyawkO+yNIDxORmQgMczAgMBAAGjUzBRMB0GA1UdDgQWBBThgotd9ws2ryEEaKp2 ++RMOWV8D7jAfBgNVHSMEGDAWgBThgotd9ws2ryEEaKp2+RMOWV8D7jAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA9QoPv78hGmvmqF4GZeqrOBKQB +N/H5wL7f8H6BXU/wpNo2nnWOJn3u37lT+zivAdGEv+x+GeKekcugKBCSluhBLpVb +VNXe4WwMm5FBuO2NRBN2nblTMm1kEO00nVk1/yNo4hI8mj7d4YLU62d7324osNpF +wHqu6B0/c99JeKRvODGswyff1i8rJ1jpcgk/JmHg7UQBHEIkn0cRR0f9W3Mxv6b5 +ZeowRe81neWNkC6IMiMmzA0iHGkhoUMA15qG1ZKOr1XR364LH5BfNNpzAWYwkvJs +0JFrrdw+rm+cRJWs55yiyCCs7pyg1IJkY/o8bifdCOUgIyonzffwREk3+kZR +-----END CERTIFICATE-----"; + + let client_side_pem = b"-----BEGIN CERTIFICATE----- +MIIDjDCCAnSgAwIBAgIUOi9jKILrOzfRNGIkQ48S90NehpkwDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTkxMTMxNDhaFw0yNTAzMTkxMTMxNDhaMFAxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRQwEgYDVQQDDAtj +bGllbnRfc2lkZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMzU2p1a +ly/1bi2TDZ8+Qlvk9/3KyHqrg2BGZUxB3Pj/lufDuYNwOHkss99wp8gzMsT28mD4 +y6X7nCgEN8WeHl+/xfLuGsWIBa1OOr6dz0qewoWFsor01cQ8+nwAKlgnz6IvHfkQ +OJZD/QYSdyn6c1AcIyS60vo4qMjyI4OVb1Dl4WpC4vCmWvDT0WjBZ5GckCnuQ8wS +wZ5MtPuMQf8kYX95ll7eBtDfEXF9Oja0l1/5SmlHuKyqDy4sIKovxtFHTqgb8PUc +yT33pUHOsBXruNBxl1MKq1outdMqcQknT6FAC+aVZ7bTlwhnH8p5Apn57g+dJYTI +9dCr1e2oK5NohhkCAwEAAaNaMFgwFgYDVR0RBA8wDYILY2xpZW50X3NpZGUwHQYD +VR0OBBYEFHDUYYfQacLj1tp49OG9NbPuL0N/MB8GA1UdIwQYMBaAFOGCi133Czav +IQRoqnb5Ew5ZXwPuMA0GCSqGSIb3DQEBCwUAA4IBAQB+nFAe6QyD2AaFdgrFOyEE +MeYb97sy9p5ylhMYyU62AYsIzzpTY74wBG78qYPIw3lAYzNcN0L6T6kBQ4lu6gFm +XB0SqCZ2AkwvV8tTlbLkZeoO6rONeke6c8cJsxYN7NiknDvTMrkTTgiyvbCWfEVX +Htnc4j/KzSBX3UjVcbPM3L/6KwMRw050/6RCiOIPFjTOCfTGoDx5fIyBk3ch/Plw +TkH2juHxX0/aCxr8hRE1v9+pXXlGnGoKbsDMLN9Aziu6xzdT/kD7BvyoM8rh7CE5 +ae7/R4sd13cZ2WGDPimqO0z1kItMOIdiYvk4DgOg+J8hZSkKT56erafdDa2LPBE6 +-----END CERTIFICATE-----"; + + let client_side_key = b"-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDM1NqdWpcv9W4t +kw2fPkJb5Pf9ysh6q4NgRmVMQdz4/5bnw7mDcDh5LLPfcKfIMzLE9vJg+Mul+5wo +BDfFnh5fv8Xy7hrFiAWtTjq+nc9KnsKFhbKK9NXEPPp8ACpYJ8+iLx35EDiWQ/0G +Encp+nNQHCMkutL6OKjI8iODlW9Q5eFqQuLwplrw09FowWeRnJAp7kPMEsGeTLT7 +jEH/JGF/eZZe3gbQ3xFxfTo2tJdf+UppR7isqg8uLCCqL8bRR06oG/D1HMk996VB +zrAV67jQcZdTCqtaLrXTKnEJJ0+hQAvmlWe205cIZx/KeQKZ+e4PnSWEyPXQq9Xt +qCuTaIYZAgMBAAECggEAAlqVVw7UEzLjtN4eX1S6tD3jvCzFBETdjgENF7TfjlR4 +lln9UyV6Xqkc+Y28vdwZwqHwW90sEPCc5ShUQD7+jBzi8FVcZSX4o7rVCbz8RXgg +1eI5EKf632YQflWNpwTxGcTnGCY/sjleil/yst6sDdD+9eR4OXQme2Wt8wyH8pLm +bf1OensGrFu3kJaPMOfP6jXnqEqkUPqmaCNW7+Ans8E+4J9oksRVPQJEuxwSjdJu +BlG50KKpl0XwZ/u/hkkj8/BlRDa62YMGJkFOwaaGUu2/0UU139XaJiMSPoL6t/BU +1H15dtW9liEtnHIssXMRzc9cg+xPgCs79ABXSZaFUQKBgQD4mH/DcEFwkZQcr08i +GUk0RE5arAqHui4eiujcPZVV6j/L7PHHmabKRPBlsndFP7KUCtvzNRmHq7JWDkpF +S36OE4e94CBYb0CIrO8OO5zl1vGAn5qa9ckefSFz9AMWW+hSuo185hFjt67BMaI0 +8CxfYDH+QY5D4JE5RhSwsOmiUQKBgQDS7qjq+MQKPHHTztyHK8IbAfEGlrBdCAjf +K1bDX2BdfbRJMZ+y8LgK5HxDPlNx2/VauBLsIyU1Zirepd8hOsbCVoK1fOq+T7bY +KdB1oqLK1Rq1sMBc26F24LBaZ3Pw5XgYEcvaOW0JFQ9Oc4VjcIXKjTNhobNOegfK +QDnw8fEtSQKBgQDrCuTh2GVHFZ3AcVCUoOvB60NaH4flRHcOkbARbHihvtWK7gC8 +A97bJ8tTnCWA5/TkXFAR54a36/K1wtUeJ38Evhp9wEdU1ftiPn/YKSzzcwLr5fu7 +v9/kX9MdWv0ASu2iKphUGwMeETG9oDwJaXvKwZ0DFOB59P3Z9RTi6qI7wQKBgQCp +uBZ6WgeDJPeBsaSHrpHUIU/KOV1WvaxFxR1evlNPZmG1sxQIat/rA8VoZbHGn3Ff +uVSgY/cAbGB6HYTXu+9JV0p8tTI8Ru+cJqjwvhe2lJmVL87X6HCWsluzoiIL5tcm +pssbn7E36ZYTTag6RsOgItUA7ZbUwiOafOsiD8o64QKBgE6nOkAfy5mbp7X+q9uD +J5y6IXpY/Oia/RwveLWFbI/aum4Nnhb6L9Y0XlrYjm4cJOchQyDR7FF6f4EuAiYb +wdxBbkxXpwXnfKCtNvMF/wZMvPVaS5HTQga8hXMrtlW6jtTJ4HmkTTB/MILAXVkJ +EHi+N70PcrYg6li415TGfgDz +-----END PRIVATE KEY-----"; + + let server_side_pem = b"-----BEGIN CERTIFICATE----- +MIIDjDCCAnSgAwIBAgIUOi9jKILrOzfRNGIkQ48S90NehpgwDQYJKoZIhvcNAQEL +BQAwVDELMAkGA1UEBhMCRlIxCzAJBgNVBAgMAklGMQswCQYDVQQHDAJQUjERMA8G +A1UECgwIenMsIEluYy4xGDAWBgNVBAMMD3pzX3Rlc3Rfcm9vdF9jYTAeFw0yNDAz +MTkxMTMxMDRaFw0yNTAzMTkxMTMxMDRaMFAxCzAJBgNVBAYTAkZSMQswCQYDVQQI +DAJJRjELMAkGA1UEBwwCUFIxETAPBgNVBAoMCHpzLCBJbmMuMRQwEgYDVQQDDAtz +ZXJ2ZXJfc2lkZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKw4eKzt +T1inzuEIPBaPksWyjoD9n6uJx9jAQ2wRB6rXiAsXVLRSuczdGDpb1MwAqoIi6ozw +tzDRwkr58vUNaTCswxadlAmB44JEVYKZoublHjlVj5ygr0R4R5F2T9tIV+jpqZuK +HR4dHe8PiDCiWVzWvYwOLVKXQKSeaE2Z143ukVIJ85qmNykJ066AVhgWnIYSCR9c +s7WPBdTWAW3L4yNlast9hfvxdQNDs5AtUnJKfAX+7DylPAm8V7YjU1k9AtTNPbpy +kb9X97ErsB8891MmZaGZp0J6tnuucDkk0dlowMVvi2aUCsYoKF5DgGxtyVAeLhTP +70GenaLe2uwG8fMCAwEAAaNaMFgwFgYDVR0RBA8wDYILc2VydmVyX3NpZGUwHQYD +VR0OBBYEFBKms1sOw8nM/O5SN1EZIH+LsWaPMB8GA1UdIwQYMBaAFOGCi133Czav +IQRoqnb5Ew5ZXwPuMA0GCSqGSIb3DQEBCwUAA4IBAQA6H/sfm8YUn86+GwxNR9i9 +MCL7WHVRx3gS9ENK87+HtZNL2TVvhPJtupG3Pjgqi33FOHrM4rMUcWSZeCEycVgy +5cjimQLwfDljIBRQE6sem3gKf0obdWl5AlPDLTL/iKj5Su7NycrjZFYqkjZjn+58 +fe8lzHNeP/3RQTgjJ98lQI0bdzGDG1+QoxTgPEc77vgN0P4MHJYx2auz/7jYBqNJ +ko8nugIQsd4kOhmOIBUQ8aXkXFktSQIerEGB8uw5iF2cCdH/sTCvhzhxLb4IWo/O +0cAZ+Vs4FW3KUn/Y44yrVAWl1H6xdFsNXBqbzVEMzlt/RV3rH70RDCc20XhP+w+g +-----END CERTIFICATE-----"; + + let server_side_key = b"-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCsOHis7U9Yp87h +CDwWj5LFso6A/Z+ricfYwENsEQeq14gLF1S0UrnM3Rg6W9TMAKqCIuqM8Lcw0cJK ++fL1DWkwrMMWnZQJgeOCRFWCmaLm5R45VY+coK9EeEeRdk/bSFfo6ambih0eHR3v +D4gwollc1r2MDi1Sl0CknmhNmdeN7pFSCfOapjcpCdOugFYYFpyGEgkfXLO1jwXU +1gFty+MjZWrLfYX78XUDQ7OQLVJySnwF/uw8pTwJvFe2I1NZPQLUzT26cpG/V/ex +K7AfPPdTJmWhmadCerZ7rnA5JNHZaMDFb4tmlArGKCheQ4BsbclQHi4Uz+9Bnp2i +3trsBvHzAgMBAAECggEAUjpIS/CmkOLWYRVoczEr197QMYBnCyUm2TO7PU7IRWbR +GtKR6+MPuWPbHIoaCSlMQARhztdj8BhG1zuOKDi1/7qNDzA/rWZp9RmhZlDquamt +i5xxjEwgQuXW7fn6WO2qo5dlFtGT43vtfeYBlY7+cdhJ+iQOub9j6vWDQYHxrF7x +yM8xvNzomHThvLFzWXJV/nGjX5pqPraMmwJUW+MGX0YaEr6tClqsc1Kmxhs3iIUo +1JCqh3FpVu2i/mR9fdcQ0ONT/s1UHzy+1Bhmh3j2Fuk4+ZeLMfxTfFxk5U0BeMQY +sES3qmd+pG5iqPW+AmXy299G89jf5+1Q4J2Km5KOUQKBgQDidifoeknpi9hRHLLD +w/7KMMe8yYg3c3dv5p0iUQQ2pXd1lJIFQ+B2/D+hfOXhnN/iCDap89ll2LoQ2Q9L +38kQXH06HCM2q11RP0BEsZCG0CnluS+JVNnjs/ALi+yc4HSpzKPs3zXIC3dLOUbq +ov5Esa5h/RU6+NO+DH72TWTv6wKBgQDCryPKtOcLp1eqdwIBRoXdPZeUdZdnwT8+ +70DnC+YdOjFkqTbaoYE5ePa3ziGOZyTFhJbPgiwEdj9Ez1JSgqLLv5hBc4s6FigK +D7fOnn7Q7+al/kEW7+X5yoSl1bFuPCqGL1xxzxmpDY8Gf3nyZ+QGfWIenbk3nq12 +nTgINyWMGQKBgQDSrxBDxXl8EMGH/MYHQRGKs8UvSuMyi3bjoU4w/eSInno75qPO +yC5NJDJin9sSgar8E54fkSCBExdP01DayvC5CwLqDAFqvBTOIKU/A18tPP6tnRKv +lkQ8Bkxdwai47k07J4qeNa9IU/qA/mGOq2MZL6DHwvd8bMA5gFCh/rDYTwKBgAPm +gGASScK5Ao+evMKLyCjLkBrgVD026O542qMGYQDa5pxuq3Or4qvlGYRLM+7ncBwo +8OCNahZYzCGzyaFvjpVobEN7biGmyfyRngwcrsu+0q8mreUov0HG5etwoZJk0DFK +B58cGBaD+AaYTTgnDrF2l52naUuM+Uq0EahQeocZAoGBAMJEGUFyEdm1JATkNhBv +ruDzj07PCjdvq3lUJix2ZlKlabsi5V+oYxMmrUSU8Nkaxy6O+qETNRNWQeWbPQHL +IZx/qrP32PmWX0IVj3pbfKHQSpOKNGzL9xUJ/FIycZWyT3yGf24KBuJwIx7xSrRx +qNsoty1gY/y3n7SN/iMZo8lO +-----END PRIVATE KEY-----"; + + let credentials_txt = b"client1name:client1passwd +client2name:client2passwd"; + + let certs_dir = Path::new(file_path); + if !certs_dir.exists() { + fs::create_dir(certs_dir)?; + } + struct Testfile<'a> { + name: &'a str, + value: &'a [u8], + } + + let test_files = vec![ + Testfile { + name: "ca.pem", + value: ca_pem, + }, + Testfile { + name: "clientsidekey.pem", + value: client_side_key, + }, + Testfile { + name: "clientside.pem", + value: client_side_pem, + }, + Testfile { + name: "serversidekey.pem", + value: server_side_key, + }, + Testfile { + name: "serverside.pem", + value: server_side_pem, + }, + Testfile { + name: "credentials.txt", + value: credentials_txt, + }, + ]; + for test_file in test_files.iter() { + let file_path = certs_dir.join(test_file.name); + let mut file = fs::File::create(&file_path)?; + file.write_all(test_file.value)?; + } + + Ok(()) } + async fn get_basic_router_config_tls() -> Config { let mut config = config::default(); config.set_mode(Some(WhatAmI::Router)).unwrap(); From babdabc120804484fb34efaf1903fec89311af4b Mon Sep 17 00:00:00 2001 From: snehilzs Date: Sat, 4 May 2024 12:34:57 +0530 Subject: [PATCH 30/37] fix testfiles for authn --- zenoh/tests/authentication.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs index f3400c0acb..2524a1a631 100644 --- a/zenoh/tests/authentication.rs +++ b/zenoh/tests/authentication.rs @@ -32,14 +32,24 @@ mod test { create_new_files(path).await.unwrap(); println!("testfiles created successfully."); - test_pub_sub_deny_then_allow_tls().await; - test_pub_sub_allow_then_deny_tls().await; - test_get_qbl_allow_then_deny_tls().await; - test_get_qbl_deny_then_allow_tls().await; test_pub_sub_deny_then_allow_usrpswd().await; test_pub_sub_allow_then_deny_usrpswd().await; test_get_qbl_allow_then_deny_usrpswd().await; test_get_qbl_deny_then_allow_usrpswd().await; + tokio::time::sleep(Duration::from_secs(2)).await; + + test_pub_sub_deny_then_allow_tls().await; + tokio::time::sleep(Duration::from_secs(2)).await; + + test_pub_sub_allow_then_deny_tls().await; + tokio::time::sleep(Duration::from_secs(2)).await; + + test_get_qbl_allow_then_deny_tls().await; + tokio::time::sleep(Duration::from_secs(2)).await; + + test_get_qbl_deny_then_allow_tls().await; + tokio::time::sleep(Duration::from_secs(2)).await; + test_pub_sub_deny_then_allow_quic().await; // test_get_qbl_allow_then_deny_quic().await; // test_pub_sub_allow_then_deny_quic().await; From 0a03e9950fee2e9709afaffa639d47ae5d5ef993 Mon Sep 17 00:00:00 2001 From: Oussama Teffahi Date: Tue, 28 May 2024 15:36:01 +0200 Subject: [PATCH 31/37] Chore: Code format --- io/zenoh-link-commons/src/unicast.rs | 3 ++- io/zenoh-links/zenoh-link-tls/src/unicast.rs | 2 -- io/zenoh-links/zenoh-link-vsock/src/unicast.rs | 3 +-- io/zenoh-links/zenoh-link-ws/src/unicast.rs | 3 +-- io/zenoh-transport/src/unicast/authentication.rs | 5 ++++- .../src/unicast/establishment/accept.rs | 5 +++-- io/zenoh-transport/src/unicast/establishment/open.rs | 4 ++-- .../src/unicast/lowlatency/transport.rs | 2 +- io/zenoh-transport/src/unicast/mod.rs | 7 +++---- .../src/unicast/universal/transport.rs | 2 +- zenoh/src/net/routing/interceptor/access_control.rs | 7 ++++--- zenoh/tests/authentication.rs | 12 +++++++----- 12 files changed, 29 insertions(+), 26 deletions(-) diff --git a/io/zenoh-link-commons/src/unicast.rs b/io/zenoh-link-commons/src/unicast.rs index 3b86eebb54..cd8c550503 100644 --- a/io/zenoh-link-commons/src/unicast.rs +++ b/io/zenoh-link-commons/src/unicast.rs @@ -17,15 +17,16 @@ use core::{ hash::{Hash, Hasher}, ops::Deref, }; -use serde::Serialize; use std::net::SocketAddr; use async_trait::async_trait; +use serde::Serialize; use zenoh_protocol::{ core::{EndPoint, Locator}, transport::BatchSize, }; use zenoh_result::ZResult; + pub type LinkManagerUnicast = Arc; #[async_trait] pub trait LinkManagerUnicastTrait: Send + Sync { diff --git a/io/zenoh-links/zenoh-link-tls/src/unicast.rs b/io/zenoh-links/zenoh-link-tls/src/unicast.rs index 50444c6d25..2e40f23dae 100644 --- a/io/zenoh-links/zenoh-link-tls/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-tls/src/unicast.rs @@ -24,8 +24,6 @@ use tokio_util::sync::CancellationToken; //use webpki::anchor_from_trusted_cert; use x509_parser::prelude::*; use zenoh_core::zasynclock; -//use zenoh_link_commons::tls::WebPkiVerifierAnyServerName; - use zenoh_link_commons::{ get_ip_interface_names, LinkAuthId, LinkAuthIdBuilder, LinkAuthType, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, ListenersUnicastIP, NewLinkChannelSender, diff --git a/io/zenoh-links/zenoh-link-vsock/src/unicast.rs b/io/zenoh-links/zenoh-link-vsock/src/unicast.rs index c199cbd077..32b292ca7e 100644 --- a/io/zenoh-links/zenoh-link-vsock/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-vsock/src/unicast.rs @@ -27,9 +27,8 @@ use tokio_vsock::{ VMADDR_CID_LOCAL, }; use zenoh_core::{zasyncread, zasyncwrite}; -use zenoh_link_commons::LinkAuthId; use zenoh_link_commons::{ - LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, + LinkAuthId, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; use zenoh_protocol::{ core::{endpoint::Address, EndPoint, Locator}, diff --git a/io/zenoh-links/zenoh-link-ws/src/unicast.rs b/io/zenoh-links/zenoh-link-ws/src/unicast.rs index d22d2c3d75..336e8af975 100644 --- a/io/zenoh-links/zenoh-link-ws/src/unicast.rs +++ b/io/zenoh-links/zenoh-link-ws/src/unicast.rs @@ -33,9 +33,8 @@ use tokio::{ use tokio_tungstenite::{accept_async, tungstenite::Message, MaybeTlsStream, WebSocketStream}; use tokio_util::sync::CancellationToken; use zenoh_core::{zasynclock, zasyncread, zasyncwrite}; -use zenoh_link_commons::LinkAuthId; use zenoh_link_commons::{ - LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, + LinkAuthId, LinkManagerUnicastTrait, LinkUnicast, LinkUnicastTrait, NewLinkChannelSender, }; use zenoh_protocol::{ core::{EndPoint, Locator}, diff --git a/io/zenoh-transport/src/unicast/authentication.rs b/io/zenoh-transport/src/unicast/authentication.rs index c0bfa1b17b..b66289983e 100644 --- a/io/zenoh-transport/src/unicast/authentication.rs +++ b/io/zenoh-transport/src/unicast/authentication.rs @@ -1,6 +1,7 @@ +use zenoh_link::{LinkAuthId, LinkAuthType}; + #[cfg(feature = "auth_usrpwd")] use super::establishment::ext::auth::UsrPwdId; -use zenoh_link::{LinkAuthId, LinkAuthType}; #[derive(Clone, Debug, PartialEq, Eq)] pub enum AuthId { @@ -8,6 +9,7 @@ pub enum AuthId { Username(String), None, } + impl From for AuthId { fn from(lid: LinkAuthId) -> Self { match (lid.get_type(), lid.get_value()) { @@ -18,6 +20,7 @@ impl From for AuthId { } } } + #[cfg(feature = "auth_usrpwd")] impl From for AuthId { fn from(user_password_id: UsrPwdId) -> Self { diff --git a/io/zenoh-transport/src/unicast/establishment/accept.rs b/io/zenoh-transport/src/unicast/establishment/accept.rs index 5445e2c669..9a7151252d 100644 --- a/io/zenoh-transport/src/unicast/establishment/accept.rs +++ b/io/zenoh-transport/src/unicast/establishment/accept.rs @@ -11,9 +11,8 @@ // Contributors: // ZettaScale Zenoh Team, // -#[cfg(feature = "auth_usrpwd")] -use super::ext::auth::UsrPwdId; use std::time::Duration; + use async_trait::async_trait; use rand::Rng; use tokio::sync::Mutex; @@ -32,6 +31,8 @@ use zenoh_protocol::{ }; use zenoh_result::ZResult; +#[cfg(feature = "auth_usrpwd")] +use super::ext::auth::UsrPwdId; #[cfg(feature = "shared-memory")] use super::ext::shm::AuthSegment; #[cfg(feature = "shared-memory")] diff --git a/io/zenoh-transport/src/unicast/establishment/open.rs b/io/zenoh-transport/src/unicast/establishment/open.rs index ac541e4825..2d50d465bf 100644 --- a/io/zenoh-transport/src/unicast/establishment/open.rs +++ b/io/zenoh-transport/src/unicast/establishment/open.rs @@ -1,5 +1,3 @@ -#[cfg(feature = "auth_usrpwd")] -use crate::unicast::establishment::ext::auth::UsrPwdId; // // Copyright (c) 2022 ZettaScale Technology // @@ -34,6 +32,8 @@ use zenoh_result::ZResult; use super::ext::shm::AuthSegment; #[cfg(feature = "shared-memory")] use crate::shm::TransportShmConfig; +#[cfg(feature = "auth_usrpwd")] +use crate::unicast::establishment::ext::auth::UsrPwdId; use crate::{ common::batch::BatchConfig, unicast::{ diff --git a/io/zenoh-transport/src/unicast/lowlatency/transport.rs b/io/zenoh-transport/src/unicast/lowlatency/transport.rs index 58880cd6b3..abffb665b7 100644 --- a/io/zenoh-transport/src/unicast/lowlatency/transport.rs +++ b/io/zenoh-transport/src/unicast/lowlatency/transport.rs @@ -11,7 +11,6 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::super::authentication::AuthId; use std::{ sync::{Arc, RwLock as SyncRwLock}, time::Duration, @@ -33,6 +32,7 @@ use zenoh_result::{zerror, ZResult}; use crate::stats::TransportStats; use crate::{ unicast::{ + authentication::AuthId, link::{LinkUnicastWithOpenAck, TransportLinkUnicast}, transport_unicast_inner::{AddLinkResult, TransportUnicastTrait}, TransportConfigUnicast, diff --git a/io/zenoh-transport/src/unicast/mod.rs b/io/zenoh-transport/src/unicast/mod.rs index 64bdd3c510..973d0bf09a 100644 --- a/io/zenoh-transport/src/unicast/mod.rs +++ b/io/zenoh-transport/src/unicast/mod.rs @@ -26,10 +26,6 @@ use std::{ sync::{Arc, Weak}, }; -use self::authentication::AuthId; -#[cfg(feature = "auth_usrpwd")] -use self::establishment::ext::auth::UsrPwdId; - #[cfg(feature = "transport_multilink")] use establishment::ext::auth::ZPublicKey; pub use manager::*; @@ -46,6 +42,9 @@ use self::transport_unicast_inner::TransportUnicastTrait; use super::{TransportPeer, TransportPeerEventHandler}; #[cfg(feature = "shared-memory")] use crate::shm::TransportShmConfig; +use crate::unicast::authentication::AuthId; +#[cfg(feature = "auth_usrpwd")] +use crate::unicast::establishment::ext::auth::UsrPwdId; /*************************************/ /* TRANSPORT UNICAST */ diff --git a/io/zenoh-transport/src/unicast/universal/transport.rs b/io/zenoh-transport/src/unicast/universal/transport.rs index bbb5c0ce7c..e7b0d52458 100644 --- a/io/zenoh-transport/src/unicast/universal/transport.rs +++ b/io/zenoh-transport/src/unicast/universal/transport.rs @@ -11,7 +11,6 @@ // Contributors: // ZettaScale Zenoh Team, // -use super::super::authentication::AuthId; use std::{ fmt::DebugStruct, sync::{Arc, RwLock}, @@ -29,6 +28,7 @@ use zenoh_protocol::{ }; use zenoh_result::{bail, zerror, ZResult}; +use super::super::authentication::AuthId; #[cfg(feature = "stats")] use crate::stats::TransportStats; use crate::{ diff --git a/zenoh/src/net/routing/interceptor/access_control.rs b/zenoh/src/net/routing/interceptor/access_control.rs index 49b97d1b83..885752e2c6 100644 --- a/zenoh/src/net/routing/interceptor/access_control.rs +++ b/zenoh/src/net/routing/interceptor/access_control.rs @@ -25,10 +25,11 @@ use zenoh_protocol::{ network::{Declare, DeclareBody, NetworkBody, NetworkMessage, Push, Request}, zenoh::{PushBody, RequestBody}, }; -use zenoh_transport::unicast::authentication::AuthId; - use zenoh_result::ZResult; -use zenoh_transport::{multicast::TransportMulticast, unicast::TransportUnicast}; +use zenoh_transport::{ + multicast::TransportMulticast, + unicast::{authentication::AuthId, TransportUnicast}, +}; use super::{ authorization::PolicyEnforcer, EgressInterceptor, IngressInterceptor, InterceptorFactory, diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs index 8357b09495..e6995ecaa0 100644 --- a/zenoh/tests/authentication.rs +++ b/zenoh/tests/authentication.rs @@ -12,15 +12,17 @@ // ZettaScale Zenoh Team, // mod test { - use std::sync::{Arc, Mutex}; - use std::time::Duration; + use std::{ + fs, + path::Path, + sync::{Arc, Mutex}, + time::Duration, + }; + use tokio::runtime::Handle; use zenoh::prelude::*; use zenoh_core::{zlock, ztimeout}; - use std::fs; - use std::path::Path; - const TIMEOUT: Duration = Duration::from_secs(60); const SLEEP: Duration = Duration::from_secs(1); const KEY_EXPR: &str = "test/demo"; From f91e885e5c13f49886fb71d27a56c818f23abd20 Mon Sep 17 00:00:00 2001 From: Oussama Teffahi Date: Wed, 29 May 2024 16:25:20 +0200 Subject: [PATCH 32/37] Change port numbers to allow tests to run concurrently --- zenoh/tests/acl.rs | 6 +++--- zenoh/tests/authentication.rs | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/zenoh/tests/acl.rs b/zenoh/tests/acl.rs index 1889a9f9fa..56e51a070c 100644 --- a/zenoh/tests/acl.rs +++ b/zenoh/tests/acl.rs @@ -42,7 +42,7 @@ mod test { async fn get_basic_router_config() -> Config { let mut config = config::default(); config.set_mode(Some(WhatAmI::Router)).unwrap(); - config.listen.endpoints = vec!["tcp/127.0.0.1:7447".parse().unwrap()]; + config.listen.endpoints = vec!["tcp/127.0.0.1:27447".parse().unwrap()]; config.scouting.multicast.set_enabled(Some(false)).unwrap(); config } @@ -54,9 +54,9 @@ mod test { async fn get_client_sessions() -> (Session, Session) { println!("Opening client sessions"); - let config = config::client(["tcp/127.0.0.1:7447".parse::().unwrap()]); + let config = config::client(["tcp/127.0.0.1:27447".parse::().unwrap()]); let s01 = ztimeout!(zenoh::open(config)).unwrap(); - let config = config::client(["tcp/127.0.0.1:7447".parse::().unwrap()]); + let config = config::client(["tcp/127.0.0.1:27447".parse::().unwrap()]); let s02 = ztimeout!(zenoh::open(config)).unwrap(); (s01, s02) } diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs index e6995ecaa0..bec7aac262 100644 --- a/zenoh/tests/authentication.rs +++ b/zenoh/tests/authentication.rs @@ -240,7 +240,7 @@ client2name:client2passwd"; async fn get_basic_router_config_tls() -> Config { let mut config = config::default(); config.set_mode(Some(WhatAmI::Router)).unwrap(); - config.listen.endpoints = vec!["tls/127.0.0.1:7447".parse().unwrap()]; + config.listen.endpoints = vec!["tls/127.0.0.1:37447".parse().unwrap()]; config.scouting.multicast.set_enabled(Some(false)).unwrap(); config .insert_json5( @@ -266,7 +266,7 @@ client2name:client2passwd"; async fn get_basic_router_config_quic() -> Config { let mut config = config::default(); config.set_mode(Some(WhatAmI::Router)).unwrap(); - config.listen.endpoints = vec!["quic/127.0.0.1:7447".parse().unwrap()]; + config.listen.endpoints = vec!["quic/127.0.0.1:37447".parse().unwrap()]; config.scouting.multicast.set_enabled(Some(false)).unwrap(); config .insert_json5( @@ -293,7 +293,7 @@ client2name:client2passwd"; async fn get_basic_router_config_usrpswd() -> Config { let mut config = config::default(); config.set_mode(Some(WhatAmI::Router)).unwrap(); - config.listen.endpoints = vec!["tcp/127.0.0.1:7447".parse().unwrap()]; + config.listen.endpoints = vec!["tcp/127.0.0.1:37447".parse().unwrap()]; config.scouting.multicast.set_enabled(Some(false)).unwrap(); config .insert_json5( @@ -318,7 +318,7 @@ client2name:client2passwd"; async fn get_client_sessions_tls() -> (Session, Session) { println!("Opening client sessions"); - let mut config = config::client(["tls/127.0.0.1:7447".parse::().unwrap()]); + let mut config = config::client(["tls/127.0.0.1:37447".parse::().unwrap()]); config .insert_json5( "transport", @@ -339,7 +339,7 @@ client2name:client2passwd"; ) .unwrap(); let s01 = ztimeout!(zenoh::open(config)).unwrap(); - let mut config = config::client(["tls/127.0.0.1:7447".parse::().unwrap()]); + let mut config = config::client(["tls/127.0.0.1:37447".parse::().unwrap()]); config .insert_json5( "transport", @@ -365,7 +365,7 @@ client2name:client2passwd"; async fn get_client_sessions_quic() -> (Session, Session) { println!("Opening client sessions"); - let mut config = config::client(["quic/127.0.0.1:7447".parse::().unwrap()]); + let mut config = config::client(["quic/127.0.0.1:37447".parse::().unwrap()]); config .insert_json5( "transport", @@ -386,7 +386,7 @@ client2name:client2passwd"; ) .unwrap(); let s01 = ztimeout!(zenoh::open(config)).unwrap(); - let mut config = config::client(["quic/127.0.0.1:7447".parse::().unwrap()]); + let mut config = config::client(["quic/127.0.0.1:37447".parse::().unwrap()]); config .insert_json5( "transport", @@ -412,7 +412,7 @@ client2name:client2passwd"; async fn get_client_sessions_usrpswd() -> (Session, Session) { println!("Opening client sessions"); - let mut config = config::client(["tcp/127.0.0.1:7447".parse::().unwrap()]); + let mut config = config::client(["tcp/127.0.0.1:37447".parse::().unwrap()]); config .insert_json5( "transport", @@ -427,7 +427,7 @@ client2name:client2passwd"; ) .unwrap(); let s01 = ztimeout!(zenoh::open(config)).unwrap(); - let mut config = config::client(["tcp/127.0.0.1:7447".parse::().unwrap()]); + let mut config = config::client(["tcp/127.0.0.1:37447".parse::().unwrap()]); config .insert_json5( "transport", From 2714ced27ff89fc5482cd662e7b2effdc80972fc Mon Sep 17 00:00:00 2001 From: Oussama Teffahi Date: Wed, 29 May 2024 17:38:12 +0200 Subject: [PATCH 33/37] Fix TLS and Quic test failures due to subsequent sessions on same port number --- zenoh/tests/authentication.rs | 104 +++++++++++++++++----------------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs index bec7aac262..2f16b49735 100644 --- a/zenoh/tests/authentication.rs +++ b/zenoh/tests/authentication.rs @@ -38,28 +38,18 @@ mod test { test_pub_sub_allow_then_deny_usrpswd().await; test_get_qbl_allow_then_deny_usrpswd().await; test_get_qbl_deny_then_allow_usrpswd().await; - tokio::time::sleep(Duration::from_secs(2)).await; - test_pub_sub_deny_then_allow_tls().await; - tokio::time::sleep(Duration::from_secs(2)).await; + test_pub_sub_deny_then_allow_tls(3774).await; + test_pub_sub_allow_then_deny_tls(3775).await; + test_get_qbl_allow_then_deny_tls(3776).await; + test_get_qbl_deny_then_allow_tls(3777).await; - test_pub_sub_allow_then_deny_tls().await; - tokio::time::sleep(Duration::from_secs(2)).await; + test_pub_sub_deny_then_allow_quic(3774).await; + test_pub_sub_allow_then_deny_quic(3775).await; + test_get_qbl_deny_then_allow_quic(3776).await; + test_get_qbl_allow_then_deny_quic(3777).await; - test_get_qbl_allow_then_deny_tls().await; - tokio::time::sleep(Duration::from_secs(2)).await; - - test_get_qbl_deny_then_allow_tls().await; - tokio::time::sleep(Duration::from_secs(2)).await; - - test_pub_sub_deny_then_allow_quic().await; - // test_get_qbl_allow_then_deny_quic().await; - // test_pub_sub_allow_then_deny_quic().await; - // test_get_qbl_deny_then_allow_quic().await; - - use std::fs::remove_dir_all; - tokio::time::sleep(Duration::from_secs(1)).await; - remove_dir_all(path).unwrap(); + std::fs::remove_dir_all(path).unwrap(); println!("testfiles removed successfully."); } @@ -237,10 +227,10 @@ client2name:client2passwd"; Ok(()) } - async fn get_basic_router_config_tls() -> Config { + async fn get_basic_router_config_tls(port: u16) -> Config { let mut config = config::default(); config.set_mode(Some(WhatAmI::Router)).unwrap(); - config.listen.endpoints = vec!["tls/127.0.0.1:37447".parse().unwrap()]; + config.listen.endpoints = vec![format!("tls/127.0.0.1:{}", port).parse().unwrap()]; config.scouting.multicast.set_enabled(Some(false)).unwrap(); config .insert_json5( @@ -263,10 +253,10 @@ client2name:client2passwd"; .unwrap(); config } - async fn get_basic_router_config_quic() -> Config { + async fn get_basic_router_config_quic(port: u16) -> Config { let mut config = config::default(); config.set_mode(Some(WhatAmI::Router)).unwrap(); - config.listen.endpoints = vec!["quic/127.0.0.1:37447".parse().unwrap()]; + config.listen.endpoints = vec![format!("quic/127.0.0.1:{}", port).parse().unwrap()]; config.scouting.multicast.set_enabled(Some(false)).unwrap(); config .insert_json5( @@ -316,9 +306,11 @@ client2name:client2passwd"; ztimeout!(s.close()).unwrap(); } - async fn get_client_sessions_tls() -> (Session, Session) { + async fn get_client_sessions_tls(port: u16) -> (Session, Session) { println!("Opening client sessions"); - let mut config = config::client(["tls/127.0.0.1:37447".parse::().unwrap()]); + let mut config = config::client([format!("tls/127.0.0.1:{}", port) + .parse::() + .unwrap()]); config .insert_json5( "transport", @@ -339,7 +331,9 @@ client2name:client2passwd"; ) .unwrap(); let s01 = ztimeout!(zenoh::open(config)).unwrap(); - let mut config = config::client(["tls/127.0.0.1:37447".parse::().unwrap()]); + let mut config = config::client([format!("tls/127.0.0.1:{}", port) + .parse::() + .unwrap()]); config .insert_json5( "transport", @@ -363,9 +357,11 @@ client2name:client2passwd"; (s01, s02) } - async fn get_client_sessions_quic() -> (Session, Session) { + async fn get_client_sessions_quic(port: u16) -> (Session, Session) { println!("Opening client sessions"); - let mut config = config::client(["quic/127.0.0.1:37447".parse::().unwrap()]); + let mut config = config::client([format!("quic/127.0.0.1:{}", port) + .parse::() + .unwrap()]); config .insert_json5( "transport", @@ -386,7 +382,9 @@ client2name:client2passwd"; ) .unwrap(); let s01 = ztimeout!(zenoh::open(config)).unwrap(); - let mut config = config::client(["quic/127.0.0.1:37447".parse::().unwrap()]); + let mut config = config::client([format!("quic/127.0.0.1:{}", port) + .parse::() + .unwrap()]); config .insert_json5( "transport", @@ -454,10 +452,10 @@ client2name:client2passwd"; ztimeout!(s02.close()).unwrap(); } - async fn test_pub_sub_deny_then_allow_tls() { + async fn test_pub_sub_deny_then_allow_tls(port: u16) { println!("test_pub_sub_deny_then_allow_tls"); - let mut config_router = get_basic_router_config_tls().await; + let mut config_router = get_basic_router_config_tls(port).await; config_router .insert_json5( @@ -490,7 +488,7 @@ client2name:client2passwd"; let session = ztimeout!(zenoh::open(config_router)).unwrap(); - let (sub_session, pub_session) = get_client_sessions_tls().await; + let (sub_session, pub_session) = get_client_sessions_tls(port).await; { let publisher = pub_session.declare_publisher(KEY_EXPR).await.unwrap(); let received_value = Arc::new(Mutex::new(String::new())); @@ -514,9 +512,9 @@ client2name:client2passwd"; close_router_session(session).await; } - async fn test_pub_sub_allow_then_deny_tls() { + async fn test_pub_sub_allow_then_deny_tls(port: u16) { println!("test_pub_sub_allow_then_deny_tls"); - let mut config_router = get_basic_router_config_tls().await; + let mut config_router = get_basic_router_config_tls(port).await; config_router .insert_json5( "access_control", @@ -547,7 +545,7 @@ client2name:client2passwd"; println!("Opening router session"); let session = ztimeout!(zenoh::open(config_router)).unwrap(); - let (sub_session, pub_session) = get_client_sessions_tls().await; + let (sub_session, pub_session) = get_client_sessions_tls(port).await; { let publisher = ztimeout!(pub_session.declare_publisher(KEY_EXPR)).unwrap(); let received_value = Arc::new(Mutex::new(String::new())); @@ -573,10 +571,10 @@ client2name:client2passwd"; close_router_session(session).await; } - async fn test_get_qbl_deny_then_allow_tls() { + async fn test_get_qbl_deny_then_allow_tls(port: u16) { println!("test_get_qbl_deny_then_allow_tls"); - let mut config_router = get_basic_router_config_tls().await; + let mut config_router = get_basic_router_config_tls(port).await; config_router .insert_json5( "access_control", @@ -608,7 +606,7 @@ client2name:client2passwd"; let session = ztimeout!(zenoh::open(config_router)).unwrap(); - let (get_session, qbl_session) = get_client_sessions_tls().await; + let (get_session, qbl_session) = get_client_sessions_tls(port).await; { let mut received_value = String::new(); @@ -647,10 +645,10 @@ client2name:client2passwd"; close_router_session(session).await; } - async fn test_get_qbl_allow_then_deny_tls() { + async fn test_get_qbl_allow_then_deny_tls(port: u16) { println!("test_get_qbl_allow_then_deny_tls"); - let mut config_router = get_basic_router_config_tls().await; + let mut config_router = get_basic_router_config_tls(port).await; config_router .insert_json5( "access_control", @@ -681,7 +679,7 @@ client2name:client2passwd"; let session = ztimeout!(zenoh::open(config_router)).unwrap(); - let (get_session, qbl_session) = get_client_sessions_tls().await; + let (get_session, qbl_session) = get_client_sessions_tls(port).await; { let mut received_value = String::new(); @@ -720,10 +718,10 @@ client2name:client2passwd"; close_router_session(session).await; } - async fn test_pub_sub_deny_then_allow_quic() { + async fn test_pub_sub_deny_then_allow_quic(port: u16) { println!("test_pub_sub_deny_then_allow_quic"); - let mut config_router = get_basic_router_config_quic().await; + let mut config_router = get_basic_router_config_quic(port).await; config_router .insert_json5( @@ -756,7 +754,7 @@ client2name:client2passwd"; let session = ztimeout!(zenoh::open(config_router)).unwrap(); - let (sub_session, pub_session) = get_client_sessions_quic().await; + let (sub_session, pub_session) = get_client_sessions_quic(port).await; { let publisher = pub_session.declare_publisher(KEY_EXPR).await.unwrap(); let received_value = Arc::new(Mutex::new(String::new())); @@ -781,10 +779,10 @@ client2name:client2passwd"; } #[allow(unused)] - async fn test_pub_sub_allow_then_deny_quic() { + async fn test_pub_sub_allow_then_deny_quic(port: u16) { println!("test_pub_sub_allow_then_deny_quic"); - let mut config_router = get_basic_router_config_quic().await; + let mut config_router = get_basic_router_config_quic(port).await; config_router .insert_json5( "access_control", @@ -815,7 +813,7 @@ client2name:client2passwd"; println!("Opening router session"); let session = ztimeout!(zenoh::open(config_router)).unwrap(); - let (sub_session, pub_session) = get_client_sessions_quic().await; + let (sub_session, pub_session) = get_client_sessions_quic(port).await; { let publisher = ztimeout!(pub_session.declare_publisher(KEY_EXPR)).unwrap(); let received_value = Arc::new(Mutex::new(String::new())); @@ -842,10 +840,10 @@ client2name:client2passwd"; } #[allow(unused)] - async fn test_get_qbl_deny_then_allow_quic() { + async fn test_get_qbl_deny_then_allow_quic(port: u16) { println!("test_get_qbl_deny_then_allow_quic"); - let mut config_router = get_basic_router_config_quic().await; + let mut config_router = get_basic_router_config_quic(port).await; config_router .insert_json5( "access_control", @@ -877,7 +875,7 @@ client2name:client2passwd"; let session = ztimeout!(zenoh::open(config_router)).unwrap(); - let (get_session, qbl_session) = get_client_sessions_quic().await; + let (get_session, qbl_session) = get_client_sessions_quic(port).await; { let mut received_value = String::new(); @@ -917,10 +915,10 @@ client2name:client2passwd"; } #[allow(unused)] - async fn test_get_qbl_allow_then_deny_quic() { + async fn test_get_qbl_allow_then_deny_quic(port: u16) { println!("test_get_qbl_allow_then_deny_quic"); - let mut config_router = get_basic_router_config_quic().await; + let mut config_router = get_basic_router_config_quic(port).await; config_router .insert_json5( "access_control", @@ -951,7 +949,7 @@ client2name:client2passwd"; let session = ztimeout!(zenoh::open(config_router)).unwrap(); - let (get_session, qbl_session) = get_client_sessions_quic().await; + let (get_session, qbl_session) = get_client_sessions_quic(port).await; { let mut received_value = String::new(); From baf4704f4b47007c7772456facea9126178d5b6f Mon Sep 17 00:00:00 2001 From: Oussama Teffahi Date: Wed, 29 May 2024 17:54:38 +0200 Subject: [PATCH 34/37] Format json configs --- zenoh/tests/authentication.rs | 603 +++++++++++++++++----------------- 1 file changed, 293 insertions(+), 310 deletions(-) diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs index 2f16b49735..cc2353496f 100644 --- a/zenoh/tests/authentication.rs +++ b/zenoh/tests/authentication.rs @@ -236,19 +236,19 @@ client2name:client2passwd"; .insert_json5( "transport", r#"{ - "link": { - "protocols": [ - "tls" - ], - "tls": { - "server_private_key": "tests/testfiles/serversidekey.pem", - "server_certificate": "tests/testfiles/serverside.pem", - "root_ca_certificate": "tests/testfiles/ca.pem", - "client_auth": true, - "server_name_verification": false - }, - }, - }"#, + "link": { + "protocols": [ + "tls" + ], + "tls": { + "server_private_key": "tests/testfiles/serversidekey.pem", + "server_certificate": "tests/testfiles/serverside.pem", + "root_ca_certificate": "tests/testfiles/ca.pem", + "client_auth": true, + "server_name_verification": false + }, + }, + }"#, ) .unwrap(); config @@ -262,19 +262,19 @@ client2name:client2passwd"; .insert_json5( "transport", r#"{ - "link": { - "protocols": [ - "quic" - ], - "tls": { - "server_private_key": "tests/testfiles/serversidekey.pem", - "server_certificate": "tests/testfiles/serverside.pem", - "root_ca_certificate": "tests/testfiles/ca.pem", - "client_auth": true, - "server_name_verification": false - }, - }, - }"#, + "link": { + "protocols": [ + "quic" + ], + "tls": { + "server_private_key": "tests/testfiles/serversidekey.pem", + "server_certificate": "tests/testfiles/serverside.pem", + "root_ca_certificate": "tests/testfiles/ca.pem", + "client_auth": true, + "server_name_verification": false + }, + }, + }"#, ) .unwrap(); config @@ -289,14 +289,14 @@ client2name:client2passwd"; .insert_json5( "transport", r#"{ - "auth": { - usrpwd: { - user: "routername", - password: "routerpasswd", - dictionary_file: "tests/testfiles/credentials.txt", - }, - }, - }"#, + "auth": { + usrpwd: { + user: "routername", + password: "routerpasswd", + dictionary_file: "tests/testfiles/credentials.txt", + }, + }, + }"#, ) .unwrap(); config @@ -326,8 +326,8 @@ client2name:client2passwd"; "client_auth": true, "server_name_verification": false } - } - }"#, + } + }"#, ) .unwrap(); let s01 = ztimeout!(zenoh::open(config)).unwrap(); @@ -349,8 +349,8 @@ client2name:client2passwd"; "client_auth": true, "server_name_verification": false } - } - }"#, + } + }"#, ) .unwrap(); let s02 = ztimeout!(zenoh::open(config)).unwrap(); @@ -377,8 +377,8 @@ client2name:client2passwd"; "client_auth": true, "server_name_verification": false } - } - }"#, + } + }"#, ) .unwrap(); let s01 = ztimeout!(zenoh::open(config)).unwrap(); @@ -400,8 +400,8 @@ client2name:client2passwd"; "client_auth": true, "server_name_verification": false } - } - }"#, + } + }"#, ) .unwrap(); let s02 = ztimeout!(zenoh::open(config)).unwrap(); @@ -415,13 +415,13 @@ client2name:client2passwd"; .insert_json5( "transport", r#"{ - "auth": { - usrpwd: { + "auth": { + usrpwd: { user: "client1name", password: "client1passwd", - }, - } - }"#, + }, + } + }"#, ) .unwrap(); let s01 = ztimeout!(zenoh::open(config)).unwrap(); @@ -430,16 +430,13 @@ client2name:client2passwd"; .insert_json5( "transport", r#"{ - - "auth": { - usrpwd: { + "auth": { + usrpwd: { user: "client2name", password: "client2passwd", - }, - - } - - }"#, + }, + } + }"#, ) .unwrap(); let s02 = ztimeout!(zenoh::open(config)).unwrap(); @@ -461,27 +458,25 @@ client2name:client2passwd"; .insert_json5( "access_control", r#"{ - - "enabled": false, - "default_permission": "deny", - "rules": - [ - { - "permission": "allow", - "flows": ["ingress","egress"], - "actions": [ - "put", - "declare_subscriber" - ], - "key_exprs": [ - "test/demo" - ], - "cert_common_names": [ - "client_side" - ] - }, - ] - }"#, + "enabled": false, + "default_permission": "deny", + "rules": [ + { + "permission": "allow", + "flows": ["ingress","egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + }"#, ) .unwrap(); println!("Opening router session"); @@ -518,28 +513,26 @@ client2name:client2passwd"; config_router .insert_json5( "access_control", - r#" - {"enabled": true, - "default_permission": "allow", - "rules": - [ - { - "permission": "deny", - "flows": ["egress"], - "actions": [ - "put", - "declare_subscriber" - ], - "key_exprs": [ - "test/demo" - ], - "cert_common_names": [ - "client_side" - ] - }, - ] - } - "#, + r#"{ + "enabled": true, + "default_permission": "allow", + "rules": [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + }"#, ) .unwrap(); println!("Opening router session"); @@ -578,27 +571,26 @@ client2name:client2passwd"; config_router .insert_json5( "access_control", - r#" - {"enabled": true, - "default_permission": "deny", - "rules": - [ - { - "permission": "allow", - "flows": ["egress","ingress"], - "actions": [ - "get", - "declare_queryable"], - "key_exprs": [ - "test/demo" - ], - "cert_common_names": [ - "client_side" - ] - }, - ] - } - "#, + r#"{ + "enabled": true, + "default_permission": "deny", + "rules": [ + { + "permission": "allow", + "flows": ["egress","ingress"], + "actions": [ + "get", + "declare_queryable" + ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + }"#, ) .unwrap(); @@ -652,27 +644,26 @@ client2name:client2passwd"; config_router .insert_json5( "access_control", - r#" - {"enabled": true, - "default_permission": "allow", - "rules": - [ - { - "permission": "deny", - "flows": ["egress"], - "actions": [ - "get", - "declare_queryable" ], - "key_exprs": [ - "test/demo" - ], - "cert_common_names": [ - "client_side" - ] - }, - ] - } - "#, + r#"{ + "enabled": true, + "default_permission": "allow", + "rules": [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "get", + "declare_queryable" + ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + }"#, ) .unwrap(); println!("Opening router session"); @@ -727,27 +718,25 @@ client2name:client2passwd"; .insert_json5( "access_control", r#"{ - - "enabled": false, - "default_permission": "deny", - "rules": - [ - { - "permission": "allow", - "flows": ["ingress","egress"], - "actions": [ - "put", - "declare_subscriber" - ], - "key_exprs": [ - "test/demo" - ], - "cert_common_names": [ - "client_side" - ] - }, - ] - }"#, + "enabled": false, + "default_permission": "deny", + "rules": [ + { + "permission": "allow", + "flows": ["ingress","egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + }"#, ) .unwrap(); println!("Opening router session"); @@ -786,28 +775,26 @@ client2name:client2passwd"; config_router .insert_json5( "access_control", - r#" - {"enabled": true, - "default_permission": "allow", - "rules": - [ - { - "permission": "deny", - "flows": ["egress"], - "actions": [ - "put", - "declare_subscriber" - ], - "key_exprs": [ - "test/demo" - ], - "cert_common_names": [ - "client_side" - ] - }, - ] -} -"#, + r#"{ + "enabled": true, + "default_permission": "allow", + "rules": [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + }"#, ) .unwrap(); println!("Opening router session"); @@ -847,27 +834,25 @@ client2name:client2passwd"; config_router .insert_json5( "access_control", - r#" - {"enabled": true, - "default_permission": "deny", - "rules": - [ - { - "permission": "allow", - "flows": ["egress","ingress"], - "actions": [ - "get", - "declare_queryable"], - "key_exprs": [ - "test/demo" - ], - "cert_common_names": [ - "client_side" - ] - }, - ] -} -"#, + r#"{ + "enabled": true, + "default_permission": "deny", + "rules": [ + { + "permission": "allow", + "flows": ["egress","ingress"], + "actions": [ + "get", + "declare_queryable"], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + }"#, ) .unwrap(); @@ -922,27 +907,27 @@ client2name:client2passwd"; config_router .insert_json5( "access_control", - r#" - {"enabled": true, - "default_permission": "allow", - "rules": - [ - { - "permission": "deny", - "flows": ["egress"], - "actions": [ - "get", - "declare_queryable" ], - "key_exprs": [ - "test/demo" - ], - "cert_common_names": [ - "client_side" - ] - }, - ] -} -"#, + r#"{ + "enabled": true, + "default_permission": "allow", + "rules": + [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "get", + "declare_queryable" + ], + "key_exprs": [ + "test/demo" + ], + "cert_common_names": [ + "client_side" + ] + }, + ] + }"#, ) .unwrap(); println!("Opening router session"); @@ -997,27 +982,26 @@ client2name:client2passwd"; .insert_json5( "access_control", r#"{ - - "enabled": false, - "default_permission": "deny", - "rules": - [ - { - "permission": "allow", - "flows": ["ingress","egress"], - "actions": [ - "put", - "declare_subscriber" - ], - "key_exprs": [ - "test/demo" - ], - "usernames": [ - "client1name","client2name" - ] - }, - ] - }"#, + "enabled": false, + "default_permission": "deny", + "rules": [ + { + "permission": "allow", + "flows": ["ingress","egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "usernames": [ + "client1name", + "client2name" + ] + }, + ] + }"#, ) .unwrap(); println!("Opening router session"); @@ -1055,28 +1039,27 @@ client2name:client2passwd"; config_router .insert_json5( "access_control", - r#" - {"enabled": true, - "default_permission": "allow", - "rules": - [ - { - "permission": "deny", - "flows": ["egress"], - "actions": [ - "put", - "declare_subscriber" - ], - "key_exprs": [ - "test/demo" - ], - "usernames": [ - "client1name","client2name" - ] - }, - ] -} -"#, + r#"{ + "enabled": true, + "default_permission": "allow", + "rules": [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "put", + "declare_subscriber" + ], + "key_exprs": [ + "test/demo" + ], + "usernames": [ + "client1name", + "client2name" + ] + }, + ] + }"#, ) .unwrap(); println!("Opening router session"); @@ -1115,27 +1098,27 @@ client2name:client2passwd"; config_router .insert_json5( "access_control", - r#" - {"enabled": true, - "default_permission": "deny", - "rules": - [ - { - "permission": "allow", - "flows": ["egress","ingress"], - "actions": [ - "get", - "declare_queryable"], - "key_exprs": [ - "test/demo" - ], - "usernames": [ - "client1name","client2name" - ] - }, - ] -} -"#, + r#"{ + "enabled": true, + "default_permission": "deny", + "rules": [ + { + "permission": "allow", + "flows": ["egress","ingress"], + "actions": [ + "get", + "declare_queryable" + ], + "key_exprs": [ + "test/demo" + ], + "usernames": [ + "client1name", + "client2name" + ] + }, + ] + }"#, ) .unwrap(); @@ -1189,27 +1172,27 @@ client2name:client2passwd"; config_router .insert_json5( "access_control", - r#" - {"enabled": true, - "default_permission": "allow", - "rules": - [ - { - "permission": "deny", - "flows": ["egress"], - "actions": [ - "get", - "declare_queryable" ], - "key_exprs": [ - "test/demo" - ], - "usernames": [ - "client1name","client2name" - ] - }, - ] -} -"#, + r#"{ + "enabled": true, + "default_permission": "allow", + "rules": [ + { + "permission": "deny", + "flows": ["egress"], + "actions": [ + "get", + "declare_queryable" + ], + "key_exprs": [ + "test/demo" + ], + "usernames": [ + "client1name", + "client2name" + ] + }, + ] + }"#, ) .unwrap(); println!("Opening router session"); From 405000a5236774d5aa1e4a9f739a29602ba21bc4 Mon Sep 17 00:00:00 2001 From: Oussama Teffahi Date: Fri, 31 May 2024 11:29:20 +0200 Subject: [PATCH 35/37] Remove unused deprecated dependency async-rustls --- Cargo.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0d8a805b5f..c1ea80830b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,9 +75,6 @@ description = "Zenoh: Zero Overhead Pub/sub, Store/Query and Compute." # DEFAULT-FEATURES NOTE: Be careful with default-features and additivity! # (https://github.com/rust-lang/cargo/issues/11329) [workspace.dependencies] - - -async-rustls = "0.4.0" async-trait = "0.1.60" aes = "0.8.2" ahash = "0.8.7" From 84ae20eca3c4b94abb28fa6027ef9d56a7704099 Mon Sep 17 00:00:00 2001 From: Oussama Teffahi Date: Fri, 31 May 2024 14:18:53 +0200 Subject: [PATCH 36/37] Chore: format list of cargo dependencies --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c1ea80830b..935eacb328 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -75,7 +75,6 @@ description = "Zenoh: Zero Overhead Pub/sub, Store/Query and Compute." # DEFAULT-FEATURES NOTE: Be careful with default-features and additivity! # (https://github.com/rust-lang/cargo/issues/11329) [workspace.dependencies] -async-trait = "0.1.60" aes = "0.8.2" ahash = "0.8.7" anyhow = { version = "1.0.69", default-features = false } # Default features are disabled due to usage in no_std crates @@ -83,6 +82,7 @@ async-executor = "1.5.0" async-global-executor = "2.3.1" async-io = "1.13.0" async-std = { version = "=1.12.0", default-features = false } # Default features are disabled due to some crates' requirements +async-trait = "0.1.60" base64 = "0.21.4" bincode = "1.3.3" clap = { version = "4.4.11", features = ["derive"] } From b1368125ffb84e2aa04dab94a03573189770e745 Mon Sep 17 00:00:00 2001 From: Oussama Teffahi Date: Fri, 31 May 2024 14:55:24 +0200 Subject: [PATCH 37/37] Fix imports --- zenoh/tests/authentication.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/zenoh/tests/authentication.rs b/zenoh/tests/authentication.rs index cc2353496f..e4b15d5771 100644 --- a/zenoh/tests/authentication.rs +++ b/zenoh/tests/authentication.rs @@ -20,7 +20,12 @@ mod test { }; use tokio::runtime::Handle; - use zenoh::prelude::*; + use zenoh::{ + config, + config::{EndPoint, WhatAmI}, + prelude::*, + Config, Session, + }; use zenoh_core::{zlock, ztimeout}; const TIMEOUT: Duration = Duration::from_secs(60);