inejge / ldap3

A pure-Rust LDAP library using the Tokio stack
Apache License 2.0
226 stars 39 forks source link

panicked at 'message id', src/protocol.rs:85:13 #46

Closed fdubois1 closed 4 years ago

fdubois1 commented 4 years ago

Hi,

I am using an async connection. I got a panic "message id" returned in protocol.rs.

I printed the tags right before and I had :

[StructureTag { class: Universal, id: 2, payload: P([0]) }, StructureTag { class: Application, id: 24, payload: C([StructureTag { class: Universal, id: 10, payload: P([52]) }, StructureTag { class: Universal, id: 4, payload: P([]) }, StructureTag { class: Universal, id: 4, payload: P([48, 48, 48, 48, 48, 48, 48, 51, 58, 32, 76, 100, 97, 112, 69, 114, 114, 58, 32, 68, 83, 73, 68, 45, 48, 67, 48, 54, 48, 54, 49, 65, 44, 32, 99, 111, 109, 109, 101, 110, 116, 58, 32, 69, 114, 114, 111, 114, 32, 100, 101, 99, 114, 121, 112, 116, 105, 110, 103, 32, 108, 100, 97, 112, 32, 109, 101, 115, 115, 97, 103, 101, 44, 32, 100, 97, 116, 97, 32, 48, 44, 32, 118, 52, 53, 54, 51, 0]) }]) }]

Any idea ? I'm still trying to figure it out, but if you have an idea, let me know.

Thank for your help

inejge commented 4 years ago

On first glance, that looks like a Notice of Disconnection: the first tag is an ASN.1 integer with value 0. Structurally, that would be a Message ID in the message envelope. Which is somehow not recognized by the parser.

What kind of server are you talking to?

fdubois1 commented 4 years ago

It is an Active Directory running on a Windows Server 2019

inejge commented 4 years ago

Ok, now please print the tags on line 61 of src/protocol.rs, before let maybe_controls = ... I suspect that AD is creatively encoding the message and the parser fails to recognize the extra components.

fdubois1 commented 4 years ago

This is what it is printed before let maybe_controls = ...

[StructureTag { class: Universal, id: 2, payload: P([0]) }, StructureTag { class: Application, id: 24, payload: C([StructureTag { class: Universal, id: 10, payload: P([52]) }, StructureTag { class: Universal, id: 4, payload: P([]) }, StructureTag { class: Universal, id: 4, payload: P([48, 48, 48, 48, 48, 48, 48, 51, 58, 32, 76, 100, 97, 112, 69, 114, 114, 58, 32, 68, 83, 73, 68, 45, 48, 67, 48, 54, 48, 54, 49, 65, 44, 32, 99, 111, 109, 109, 101, 110, 116, 58, 32, 69, 114, 114, 111, 114, 32, 100, 101, 99, 114, 121, 112, 116, 105, 110, 103, 32, 108, 100, 97, 112, 32, 109, 101, 115, 115, 97, 103, 101, 44, 32, 100, 97, 116, 97, 32, 48, 44, 32, 118, 52, 53, 54, 51, 0]) }]) }, StructureTag { class: Context, id: 10, payload: P([49, 46, 51, 46, 54, 46, 49, 46, 52, 46, 49, 46, 49, 52, 54, 54, 46, 50, 48, 48, 51, 54]) }]

If I looked correctly, there is one more StructureTag at the end (compared to what it is printed right before the panic): StructureTag { class: Context, id: 10, payload: P([49, 46, 51, 46, 54, 46, 49, 46, 52, 46, 49, 46, 49, 52, 54, 54, 46, 50, 48, 48, 51, 54])

Thanks a lot for your quick response

fdubois1 commented 4 years ago

Do we have something special to close a connection ? Here is what I do :

fn init(ad_config: &ActiveDirectoryConfig) {
        let (conn, mut ldap) = LdapConnAsync::with_settings(ldap_conn_settings, ad_config.server_url).await?;
        ldap3::drive!(conn);
        ldap.simple_bind(&ad_config.username, &ad_config.password).await?.success()?

...

      ldap.unbind().await?;
}

The task spawned with ldap3::drive!(conn) will be stopped when we drop the ldap object I guess ? Do we have more to do ?

Thank you again

inejge commented 4 years ago

Nothing more should be necessary. What I suspect from the tags printout is that AD is incorrectly encoding the Notice of Disconnection, putting the last StructureTag outside of the sequence of elements comprising the Extended response, which confuses our parser. To find out, I'll need to see the raw dump of the final message. Please put the following on line 52 of src/protocol.rs, before buf.advance(...):

println!("{:?}", &buf[..amt]);

and post the output.

fdubois1 commented 4 years ago

Here is the output [48, 132, 0, 0, 0, 128, 2, 1, 0, 120, 132, 0, 0, 0, 95, 10, 1, 52, 4, 0, 4, 88, 48, 48, 48, 48, 48, 48, 48, 51, 58, 32, 76, 100, 97, 112, 69, 114, 114, 58, 32, 68, 83, 73, 68, 45, 48, 67, 48, 54, 48, 54, 49, 65, 44, 32, 99, 111, 109, 109, 101, 110, 116, 58, 32, 69, 114, 114, 111, 114, 32, 100, 101, 99, 114, 121, 112, 116, 105, 110, 103, 32, 108, 100, 97, 112, 32, 109, 101, 115, 115, 97, 103, 101, 44, 32, 100, 97, 116, 97, 32, 48, 44, 32, 118, 52, 53, 54, 51, 0, 138, 22, 49, 46, 51, 46, 54, 46, 49, 46, 52, 46, 49, 46, 49, 52, 54, 54, 46, 50, 48, 48, 51, 54]

inejge commented 4 years ago

Thanks, now I'm almost completely convinced that it's an AD bug (I'll try to coax a Notice of Disconnection from OpenLDAP to confirm). If it is, good luck getting it fixed on the AD side, I guess :wink: I'll try to make a workaround sometime later. Update: Yup, it's an AD bug.

fdubois1 commented 4 years ago

Thank you for the information. And why I didn't have that issue with the previous version of ldap3 ? The parser was built in a different way ? Anyway. Do you have an idea to avoid that crash quickly ? Everything works well with the new ldap3 alpha, except that panic that I would like to remove.

Thank you for your help !

inejge commented 4 years ago

The previous parser would also have choked on this kind of message. Perhaps the message never had actually reached the decoder because of internal Tokio differences.

Try the ad-disconn branch, it should eliminate the crash. If you're running the program with tracing enabled, it should print out an "unmatched id: 0" message, but that's all.

fdubois1 commented 4 years ago

Awesome, it works well. Thank you very much for your help, your time, I really appreciate !!!