-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Initial Scaffold for EAP Messages #34
base: main
Are you sure you want to change the base?
Initial Scaffold for EAP Messages #34
Conversation
Implement EAP struct with Enums defined from RFC2284 and RFC3579. Implement basic parsing of data into the struct and human-readable output of contents.
Write basic field tests for EAP elements, implement a to_bytes() method, misc touchups. Testing: EAP parsing tests pass
Moved the segments of code which produce validators for message authentication into their own methods, using them inside existing is_authentic_* methods in Packet. Implemented EAP generation length fixes. Added mashalling test. Implemented an MD5-Challenge response using the EAP message struct defined in earlier commits in the test server, but failing in the client-side with "Conflicting response authenticator for reply ..." This seems to indicate that either the Message-Authenticator value being produced is incorrect, or, more likely, that i am using the code incorrectly. Testing: Passes all tests currently defined
ping @moznion - could you please take a peek at my last commit? i'm messing something up here, the test client says that my response message authenticator is wrong: Sent Access-Request Id 52 from 0.0.0.0:43630 to 127.0.0.1:1812 length 67
User-Name = "test"
Cleartext-Password = "me"
NAS-IP-Address = 127.0.1.1
NAS-Port = 1
Message-Authenticator = 0x00
EAP-Code = Response
EAP-Type-Identity = 0x74657374
EAP-Message = 0x02e200090174657374
Conflicting response authenticator for reply from 127.0.0.1 (sockfd: 5, id: 52)
Main loop: done. |
@moznion - is it possible that |
Hi, thank you for your contribution! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really appreciate your contribution!
I left some comments, but I know this is still WIP status :)
} | ||
/// Create an EAP message structure from a slice of bytes | ||
pub fn from_bytes(eap_bytes: &[u8]) -> Self { | ||
let code = EAPCode::from(eap_bytes[0]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here could be panic because when the eap_bytes
doesn't have sufficient length of data.
Would it be better to check the length at the entry of this method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - i haven't implemented safety latches for stuff yet as i'm just trying to get valid content on the wire.
|
||
impl EAP { | ||
/// Create an (invalid) EAP message structure | ||
pub fn new() -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose this constructor should be split into two methods. For example:
pub fn new(code: EAPCode, id: u8, typ: EAPType, data: &Vec<u8>)
to make a EAP object as immutable and calculate the length in the constructorpub fn make_invalid()
to make an invalid, i.e. empty, object
I mean the normal constructor should afford the immutable operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, definitely all for being able to instantiate prepared immutable structures as responses, new ones, etc, but trying to get wire-level correctness first.
examples/eap_server.rs
Outdated
} | ||
|
||
struct MyRequestHandler { | ||
secret_provider: MySecretProvider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nit] is this secret provider needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy-pasta, with pesto :)
// Access-Accept/ | ||
// EAP-Message/EAP-Success | ||
// (other attributes) | ||
// <- EAP-Success |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a question: does this flow diagram has the original document? For example, RFC document.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, all of the dry stuff in the comments strewn about is copy-pasted from RFCs. This bloody process is described in like 3 - the two i mentioned and the actual EAP RFC, plus HMAC-MD5 has its own (stdby for proto-code)
println!("No eap message found"); | ||
EAP::new() | ||
} | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems the result of this match
expression is discarded. What does this code intend?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, but it satisfies the constraints of the match (maybe thats not needed anymore, been doing it this way for a few years).
Who/Where does it raise this message? |
If you said about But the MD5 hash calculations in the current implementation, I think that would be legit.
What do you think about that, @sempervictus? |
That message is thrown by |
So looks like other dedicated souls with apparent inclinations toward masochism have done this, but there's not exactly a boatload of example code for us to use. Erlang's |
@moznion - any luck on your end divining what i may have done wrong here? I should have a couple of cycles today to get back into it, hoping for some insight from a pair of fresh eyes on the code to help me move forward on the correct line of approach. 😄 |
b57ed86
to
10bf7fc
Compare
@moznion: i've tried a few approaches pulled from Erlang, Python, and C++ code found on GH but they all use different inputs and structural trickery to create the HMAC, they also don't seem to finalize the vector like Rust does (or its implicit), and we can't get bytes from ours until we do. |
947e8c7
to
93c29ee
Compare
@moznion - is there a way to enforce the order of attribute fields? Not a problem for RFC-compliant packet-parsers, but not great for the HMAC piece when messing with attributes to recreate the data initially checksummed 😄 . I can work on getting this sorted for other types, any chance you might be able to tackle the "business-logic" around response creation for the various states of EAP inner messages and RADIUS outers? |
Implement a new type using the hmac and md-5 crates, namespacing md-5 as hmac_md5 to avoid collision with existing crate. Stub out MessageAuthenticator struct & implementation to create HMACMD5 signature buffers from Packet's encode() byte vector. Implement Message-Authenticator input structure for starting the chain of HMAC exchanges and verifying Access-Request messages. Testing: Implemented test to verify Access-Request message HMACMD5 - pass
93c29ee
to
ae0382b
Compare
@moznion: i'm dealing with the field ordering mess by way of byte-slice replacement for the 16B of the Message-Authenticator for the time being, but i think that this concern is at the |
Hmm, actually I'm not sure how to fix the order of the struct fields. I'm guessing making a dedicated method to serde would be a way to do that. |
Small amount of cleanup and progress on responding to an Identity Access-Request. Generating bad Message-Authenticator values in for_response, likely not grokking the requisite field value correctly
When a struct such as [field1,field2,field3] is hashed and then field2 is removed and a replacement appended after field3, the struct containing the same fields in a different order will not sum correctly. I've hacked around this somewhat, but it may be related to the problem i'm seeing in the |
Thank you @sempervictus, I understand the current status. I'll take a look at that. |
I apologize for my late reply. I took a look at this problem and I recognize the right way to apply HMAC-MD5. In my understanding, HMAC-MD5 should be applied for the entire RADIUS packet that has 0 filled |
Implement EAP struct with Enums defined from RFC2284 and RFC3579.
Implement basic parsing of data into the struct and human-readable
output of contents.
This is very much WIP, seeking to address #32, working off of dry RFCs trying to put them together into something coherent for
struct
s andimpl
s.TODO's for MVP:
server
but message identifiers in EAP segments have to be deconflicted)TODO's for completion:
Testing:
Using
radtest -t eap-md5 test me localhost 1 somesecretval
i am seeing proper output for the EAP packet fields in