Improve interoperability of NTLM encryption/decryption and authentication - #71373

Merged
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2
Jun 30, 2022
Merged

Improve interoperability of NTLM encryption/decryption and authentication#71373
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2

Conversation

@filipnavara

@filipnavarafilipnavara commented Jun 28, 2022

Copy link
Copy Markdown
Member

Best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

@ghostghost added community-contribution Indicates that the PR has been added by a community member area-System.Net.Security labels Jun 28, 2022
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/ncl, @vcsjones
See info in area-owners.md if you want to be subscribed.

Issue Details

Built on top of #71280, best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

Author:filipnavara
Assignees:-
Labels:

area-System.Net.Security, community-contribution

Milestone:-

NegotiateStream on non-encrypted connections with NTLM sends the
messages in a special `<signature token><plain text message>` format.
That's not something that gss_wrap/gss_unwrap would produce. It can be
produced through gss_get_mic/gss_verify_mic calls though so let's do
that.
The method names were misleading since they wrapped the EncryptMessage
and DecryptMessage native APIs and not the MakeSignature/VerifySignature
APIs that also exist.
…/Decrypt
The SSPI / GSSAPI providers keep track of the sequence numbers
themselves.
This maps directly to the semantics of gss_wrap/gss_unwrap methods
that are used in many specifications. It replaces the misleading name
which in SSPI API is an equivalent of gss_get_mic/gss_verify_mic.
It also fixes the declaration to actually decode the buffers both
on Windows and Unix. In NTLM the content of the message is sealed
and needs to be decoded.
Note that previously on Unix the VerifySignature API didn't decode the
content. On Windows it did decode the content inside a buffer that was
passed as ReadOnlySpan<byte> but it didn't communicate back the offset
of the decoded data.
The SMTP GSSAPI authentication code was thus reading incorrect data.
In case the underlying authentication was Kerberos the data were
not encrypted and they were located at the beginning of the buffer
so it was not an issue. In case the underlying authentication was
NTLM it was looking at the NTLM signature token which luckily
happens to always start with the bytes 01 00 00 00. That exactly
matched the expected value by accident.
The last token in the GSSAPI SASL authentication mechanism is a bit
mask that specifies the supported security protections offered by the
server and the maximum token size. The client is supposed to choose
one of the protections and reply back. Relax the check to actually
support servers that offer anything but "no protection". As long
as the server also offers no protection we can choose it.
Updated the managed NTLM implementation and the fake servers to
implement the specification quirk:
MS-SPNG section 3.2.5.1 NTLM RC4 Key State for MechListMIC and First
Signed Message specifies that the RC4 sealing keys are reset back to
the initial state for the first message.
Since the managed implementation doesn't expose encryption yet it
didn't affect any observable behavior. Likewise the fake servers
didn't need this code path yet.

@wfurtwfurt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
cc: @SteveSyfuhs for any thoughts on the GSSAPI/SSPI changes.

@wfurt

Copy link
Copy Markdown
Member

contributes to #19436

@wfurtwfurt mentioned this pull request Jun 30, 2022
@wfurt
wfurt merged commit ac9e1f9 into dotnet:mainJun 30, 2022
@karelzkarelz added this to the 7.0.0 milestone Jul 19, 2022
@ghostghost locked as resolved and limited conversation to collaborators Aug 18, 2022
@filipnavara
filipnavara deleted the smtpauth2 branch June 5, 2025 07:39
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Net.Securitycommunity-contributionIndicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@filipnavara@wfurt@karelz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Improve interoperability of NTLM encryption/decryption and authentication - #71373

Merged
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2
Jun 30, 2022
Merged

Improve interoperability of NTLM encryption/decryption and authentication#71373
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2

Conversation

@filipnavara

@filipnavarafilipnavara commented Jun 28, 2022

Copy link
Copy Markdown
Member

Best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

@ghostghost added community-contribution Indicates that the PR has been added by a community member area-System.Net.Security labels Jun 28, 2022
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/ncl, @vcsjones
See info in area-owners.md if you want to be subscribed.

Issue Details

Built on top of #71280, best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

Author:filipnavara
Assignees:-
Labels:

area-System.Net.Security, community-contribution

Milestone:-

NegotiateStream on non-encrypted connections with NTLM sends the
messages in a special `<signature token><plain text message>` format.
That's not something that gss_wrap/gss_unwrap would produce. It can be
produced through gss_get_mic/gss_verify_mic calls though so let's do
that.
The method names were misleading since they wrapped the EncryptMessage
and DecryptMessage native APIs and not the MakeSignature/VerifySignature
APIs that also exist.
…/Decrypt
The SSPI / GSSAPI providers keep track of the sequence numbers
themselves.
This maps directly to the semantics of gss_wrap/gss_unwrap methods
that are used in many specifications. It replaces the misleading name
which in SSPI API is an equivalent of gss_get_mic/gss_verify_mic.
It also fixes the declaration to actually decode the buffers both
on Windows and Unix. In NTLM the content of the message is sealed
and needs to be decoded.
Note that previously on Unix the VerifySignature API didn't decode the
content. On Windows it did decode the content inside a buffer that was
passed as ReadOnlySpan<byte> but it didn't communicate back the offset
of the decoded data.
The SMTP GSSAPI authentication code was thus reading incorrect data.
In case the underlying authentication was Kerberos the data were
not encrypted and they were located at the beginning of the buffer
so it was not an issue. In case the underlying authentication was
NTLM it was looking at the NTLM signature token which luckily
happens to always start with the bytes 01 00 00 00. That exactly
matched the expected value by accident.
The last token in the GSSAPI SASL authentication mechanism is a bit
mask that specifies the supported security protections offered by the
server and the maximum token size. The client is supposed to choose
one of the protections and reply back. Relax the check to actually
support servers that offer anything but "no protection". As long
as the server also offers no protection we can choose it.
Updated the managed NTLM implementation and the fake servers to
implement the specification quirk:
MS-SPNG section 3.2.5.1 NTLM RC4 Key State for MechListMIC and First
Signed Message specifies that the RC4 sealing keys are reset back to
the initial state for the first message.
Since the managed implementation doesn't expose encryption yet it
didn't affect any observable behavior. Likewise the fake servers
didn't need this code path yet.

@wfurtwfurt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
cc: @SteveSyfuhs for any thoughts on the GSSAPI/SSPI changes.

@wfurt

Copy link
Copy Markdown
Member

contributes to #19436

@wfurtwfurt mentioned this pull request Jun 30, 2022
@wfurt
wfurt merged commit ac9e1f9 into dotnet:mainJun 30, 2022
@karelzkarelz added this to the 7.0.0 milestone Jul 19, 2022
@ghostghost locked as resolved and limited conversation to collaborators Aug 18, 2022
@filipnavara
filipnavara deleted the smtpauth2 branch June 5, 2025 07:39
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Net.Securitycommunity-contributionIndicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@filipnavara@wfurt@karelz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Improve interoperability of NTLM encryption/decryption and authentication - #71373

Merged
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2
Jun 30, 2022
Merged

Improve interoperability of NTLM encryption/decryption and authentication#71373
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2

Conversation

@filipnavara

@filipnavarafilipnavara commented Jun 28, 2022

Copy link
Copy Markdown
Member

Best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

@ghostghost added community-contribution Indicates that the PR has been added by a community member area-System.Net.Security labels Jun 28, 2022
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/ncl, @vcsjones
See info in area-owners.md if you want to be subscribed.

Issue Details

Built on top of #71280, best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

Author:filipnavara
Assignees:-
Labels:

area-System.Net.Security, community-contribution

Milestone:-

NegotiateStream on non-encrypted connections with NTLM sends the
messages in a special `<signature token><plain text message>` format.
That's not something that gss_wrap/gss_unwrap would produce. It can be
produced through gss_get_mic/gss_verify_mic calls though so let's do
that.
The method names were misleading since they wrapped the EncryptMessage
and DecryptMessage native APIs and not the MakeSignature/VerifySignature
APIs that also exist.
…/Decrypt
The SSPI / GSSAPI providers keep track of the sequence numbers
themselves.
This maps directly to the semantics of gss_wrap/gss_unwrap methods
that are used in many specifications. It replaces the misleading name
which in SSPI API is an equivalent of gss_get_mic/gss_verify_mic.
It also fixes the declaration to actually decode the buffers both
on Windows and Unix. In NTLM the content of the message is sealed
and needs to be decoded.
Note that previously on Unix the VerifySignature API didn't decode the
content. On Windows it did decode the content inside a buffer that was
passed as ReadOnlySpan<byte> but it didn't communicate back the offset
of the decoded data.
The SMTP GSSAPI authentication code was thus reading incorrect data.
In case the underlying authentication was Kerberos the data were
not encrypted and they were located at the beginning of the buffer
so it was not an issue. In case the underlying authentication was
NTLM it was looking at the NTLM signature token which luckily
happens to always start with the bytes 01 00 00 00. That exactly
matched the expected value by accident.
The last token in the GSSAPI SASL authentication mechanism is a bit
mask that specifies the supported security protections offered by the
server and the maximum token size. The client is supposed to choose
one of the protections and reply back. Relax the check to actually
support servers that offer anything but "no protection". As long
as the server also offers no protection we can choose it.
Updated the managed NTLM implementation and the fake servers to
implement the specification quirk:
MS-SPNG section 3.2.5.1 NTLM RC4 Key State for MechListMIC and First
Signed Message specifies that the RC4 sealing keys are reset back to
the initial state for the first message.
Since the managed implementation doesn't expose encryption yet it
didn't affect any observable behavior. Likewise the fake servers
didn't need this code path yet.

@wfurtwfurt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
cc: @SteveSyfuhs for any thoughts on the GSSAPI/SSPI changes.

@wfurt

Copy link
Copy Markdown
Member

contributes to #19436

@wfurtwfurt mentioned this pull request Jun 30, 2022
@wfurt
wfurt merged commit ac9e1f9 into dotnet:mainJun 30, 2022
@karelzkarelz added this to the 7.0.0 milestone Jul 19, 2022
@ghostghost locked as resolved and limited conversation to collaborators Aug 18, 2022
@filipnavara
filipnavara deleted the smtpauth2 branch June 5, 2025 07:39
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Net.Securitycommunity-contributionIndicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@filipnavara@wfurt@karelz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Improve interoperability of NTLM encryption/decryption and authentication - #71373

Merged
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2
Jun 30, 2022
Merged

Improve interoperability of NTLM encryption/decryption and authentication#71373
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2

Conversation

@filipnavara

@filipnavarafilipnavara commented Jun 28, 2022

Copy link
Copy Markdown
Member

Best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

@ghostghost added community-contribution Indicates that the PR has been added by a community member area-System.Net.Security labels Jun 28, 2022
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/ncl, @vcsjones
See info in area-owners.md if you want to be subscribed.

Issue Details

Built on top of #71280, best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

Author:filipnavara
Assignees:-
Labels:

area-System.Net.Security, community-contribution

Milestone:-

NegotiateStream on non-encrypted connections with NTLM sends the
messages in a special `<signature token><plain text message>` format.
That's not something that gss_wrap/gss_unwrap would produce. It can be
produced through gss_get_mic/gss_verify_mic calls though so let's do
that.
The method names were misleading since they wrapped the EncryptMessage
and DecryptMessage native APIs and not the MakeSignature/VerifySignature
APIs that also exist.
…/Decrypt
The SSPI / GSSAPI providers keep track of the sequence numbers
themselves.
This maps directly to the semantics of gss_wrap/gss_unwrap methods
that are used in many specifications. It replaces the misleading name
which in SSPI API is an equivalent of gss_get_mic/gss_verify_mic.
It also fixes the declaration to actually decode the buffers both
on Windows and Unix. In NTLM the content of the message is sealed
and needs to be decoded.
Note that previously on Unix the VerifySignature API didn't decode the
content. On Windows it did decode the content inside a buffer that was
passed as ReadOnlySpan<byte> but it didn't communicate back the offset
of the decoded data.
The SMTP GSSAPI authentication code was thus reading incorrect data.
In case the underlying authentication was Kerberos the data were
not encrypted and they were located at the beginning of the buffer
so it was not an issue. In case the underlying authentication was
NTLM it was looking at the NTLM signature token which luckily
happens to always start with the bytes 01 00 00 00. That exactly
matched the expected value by accident.
The last token in the GSSAPI SASL authentication mechanism is a bit
mask that specifies the supported security protections offered by the
server and the maximum token size. The client is supposed to choose
one of the protections and reply back. Relax the check to actually
support servers that offer anything but "no protection". As long
as the server also offers no protection we can choose it.
Updated the managed NTLM implementation and the fake servers to
implement the specification quirk:
MS-SPNG section 3.2.5.1 NTLM RC4 Key State for MechListMIC and First
Signed Message specifies that the RC4 sealing keys are reset back to
the initial state for the first message.
Since the managed implementation doesn't expose encryption yet it
didn't affect any observable behavior. Likewise the fake servers
didn't need this code path yet.

@wfurtwfurt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
cc: @SteveSyfuhs for any thoughts on the GSSAPI/SSPI changes.

@wfurt

Copy link
Copy Markdown
Member

contributes to #19436

@wfurtwfurt mentioned this pull request Jun 30, 2022
@wfurt
wfurt merged commit ac9e1f9 into dotnet:mainJun 30, 2022
@karelzkarelz added this to the 7.0.0 milestone Jul 19, 2022
@ghostghost locked as resolved and limited conversation to collaborators Aug 18, 2022
@filipnavara
filipnavara deleted the smtpauth2 branch June 5, 2025 07:39
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Net.Securitycommunity-contributionIndicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@filipnavara@wfurt@karelz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Improve interoperability of NTLM encryption/decryption and authentication - #71373

Merged
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2
Jun 30, 2022
Merged

Improve interoperability of NTLM encryption/decryption and authentication#71373
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2

Conversation

@filipnavara

@filipnavarafilipnavara commented Jun 28, 2022

Copy link
Copy Markdown
Member

Best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

@ghostghost added community-contribution Indicates that the PR has been added by a community member area-System.Net.Security labels Jun 28, 2022
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/ncl, @vcsjones
See info in area-owners.md if you want to be subscribed.

Issue Details

Built on top of #71280, best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

Author:filipnavara
Assignees:-
Labels:

area-System.Net.Security, community-contribution

Milestone:-

NegotiateStream on non-encrypted connections with NTLM sends the
messages in a special `<signature token><plain text message>` format.
That's not something that gss_wrap/gss_unwrap would produce. It can be
produced through gss_get_mic/gss_verify_mic calls though so let's do
that.
The method names were misleading since they wrapped the EncryptMessage
and DecryptMessage native APIs and not the MakeSignature/VerifySignature
APIs that also exist.
…/Decrypt
The SSPI / GSSAPI providers keep track of the sequence numbers
themselves.
This maps directly to the semantics of gss_wrap/gss_unwrap methods
that are used in many specifications. It replaces the misleading name
which in SSPI API is an equivalent of gss_get_mic/gss_verify_mic.
It also fixes the declaration to actually decode the buffers both
on Windows and Unix. In NTLM the content of the message is sealed
and needs to be decoded.
Note that previously on Unix the VerifySignature API didn't decode the
content. On Windows it did decode the content inside a buffer that was
passed as ReadOnlySpan<byte> but it didn't communicate back the offset
of the decoded data.
The SMTP GSSAPI authentication code was thus reading incorrect data.
In case the underlying authentication was Kerberos the data were
not encrypted and they were located at the beginning of the buffer
so it was not an issue. In case the underlying authentication was
NTLM it was looking at the NTLM signature token which luckily
happens to always start with the bytes 01 00 00 00. That exactly
matched the expected value by accident.
The last token in the GSSAPI SASL authentication mechanism is a bit
mask that specifies the supported security protections offered by the
server and the maximum token size. The client is supposed to choose
one of the protections and reply back. Relax the check to actually
support servers that offer anything but "no protection". As long
as the server also offers no protection we can choose it.
Updated the managed NTLM implementation and the fake servers to
implement the specification quirk:
MS-SPNG section 3.2.5.1 NTLM RC4 Key State for MechListMIC and First
Signed Message specifies that the RC4 sealing keys are reset back to
the initial state for the first message.
Since the managed implementation doesn't expose encryption yet it
didn't affect any observable behavior. Likewise the fake servers
didn't need this code path yet.

@wfurtwfurt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
cc: @SteveSyfuhs for any thoughts on the GSSAPI/SSPI changes.

@wfurt

Copy link
Copy Markdown
Member

contributes to #19436

@wfurtwfurt mentioned this pull request Jun 30, 2022
@wfurt
wfurt merged commit ac9e1f9 into dotnet:mainJun 30, 2022
@karelzkarelz added this to the 7.0.0 milestone Jul 19, 2022
@ghostghost locked as resolved and limited conversation to collaborators Aug 18, 2022
@filipnavara
filipnavara deleted the smtpauth2 branch June 5, 2025 07:39
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Net.Securitycommunity-contributionIndicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@filipnavara@wfurt@karelz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Improve interoperability of NTLM encryption/decryption and authentication - #71373

Merged
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2
Jun 30, 2022
Merged

Improve interoperability of NTLM encryption/decryption and authentication#71373
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2

Conversation

@filipnavara

@filipnavarafilipnavara commented Jun 28, 2022

Copy link
Copy Markdown
Member

Best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

@ghostghost added community-contribution Indicates that the PR has been added by a community member area-System.Net.Security labels Jun 28, 2022
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/ncl, @vcsjones
See info in area-owners.md if you want to be subscribed.

Issue Details

Built on top of #71280, best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

Author:filipnavara
Assignees:-
Labels:

area-System.Net.Security, community-contribution

Milestone:-

NegotiateStream on non-encrypted connections with NTLM sends the
messages in a special `<signature token><plain text message>` format.
That's not something that gss_wrap/gss_unwrap would produce. It can be
produced through gss_get_mic/gss_verify_mic calls though so let's do
that.
The method names were misleading since they wrapped the EncryptMessage
and DecryptMessage native APIs and not the MakeSignature/VerifySignature
APIs that also exist.
…/Decrypt
The SSPI / GSSAPI providers keep track of the sequence numbers
themselves.
This maps directly to the semantics of gss_wrap/gss_unwrap methods
that are used in many specifications. It replaces the misleading name
which in SSPI API is an equivalent of gss_get_mic/gss_verify_mic.
It also fixes the declaration to actually decode the buffers both
on Windows and Unix. In NTLM the content of the message is sealed
and needs to be decoded.
Note that previously on Unix the VerifySignature API didn't decode the
content. On Windows it did decode the content inside a buffer that was
passed as ReadOnlySpan<byte> but it didn't communicate back the offset
of the decoded data.
The SMTP GSSAPI authentication code was thus reading incorrect data.
In case the underlying authentication was Kerberos the data were
not encrypted and they were located at the beginning of the buffer
so it was not an issue. In case the underlying authentication was
NTLM it was looking at the NTLM signature token which luckily
happens to always start with the bytes 01 00 00 00. That exactly
matched the expected value by accident.
The last token in the GSSAPI SASL authentication mechanism is a bit
mask that specifies the supported security protections offered by the
server and the maximum token size. The client is supposed to choose
one of the protections and reply back. Relax the check to actually
support servers that offer anything but "no protection". As long
as the server also offers no protection we can choose it.
Updated the managed NTLM implementation and the fake servers to
implement the specification quirk:
MS-SPNG section 3.2.5.1 NTLM RC4 Key State for MechListMIC and First
Signed Message specifies that the RC4 sealing keys are reset back to
the initial state for the first message.
Since the managed implementation doesn't expose encryption yet it
didn't affect any observable behavior. Likewise the fake servers
didn't need this code path yet.

@wfurtwfurt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
cc: @SteveSyfuhs for any thoughts on the GSSAPI/SSPI changes.

@wfurt

Copy link
Copy Markdown
Member

contributes to #19436

@wfurtwfurt mentioned this pull request Jun 30, 2022
@wfurt
wfurt merged commit ac9e1f9 into dotnet:mainJun 30, 2022
@karelzkarelz added this to the 7.0.0 milestone Jul 19, 2022
@ghostghost locked as resolved and limited conversation to collaborators Aug 18, 2022
@filipnavara
filipnavara deleted the smtpauth2 branch June 5, 2025 07:39
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Net.Securitycommunity-contributionIndicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@filipnavara@wfurt@karelz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Improve interoperability of NTLM encryption/decryption and authentication - #71373

Merged
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2
Jun 30, 2022
Merged

Improve interoperability of NTLM encryption/decryption and authentication#71373
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2

Conversation

@filipnavara

@filipnavarafilipnavara commented Jun 28, 2022

Copy link
Copy Markdown
Member

Best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

@ghostghost added community-contribution Indicates that the PR has been added by a community member area-System.Net.Security labels Jun 28, 2022
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/ncl, @vcsjones
See info in area-owners.md if you want to be subscribed.

Issue Details

Built on top of #71280, best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

Author:filipnavara
Assignees:-
Labels:

area-System.Net.Security, community-contribution

Milestone:-

NegotiateStream on non-encrypted connections with NTLM sends the
messages in a special `<signature token><plain text message>` format.
That's not something that gss_wrap/gss_unwrap would produce. It can be
produced through gss_get_mic/gss_verify_mic calls though so let's do
that.
The method names were misleading since they wrapped the EncryptMessage
and DecryptMessage native APIs and not the MakeSignature/VerifySignature
APIs that also exist.
…/Decrypt
The SSPI / GSSAPI providers keep track of the sequence numbers
themselves.
This maps directly to the semantics of gss_wrap/gss_unwrap methods
that are used in many specifications. It replaces the misleading name
which in SSPI API is an equivalent of gss_get_mic/gss_verify_mic.
It also fixes the declaration to actually decode the buffers both
on Windows and Unix. In NTLM the content of the message is sealed
and needs to be decoded.
Note that previously on Unix the VerifySignature API didn't decode the
content. On Windows it did decode the content inside a buffer that was
passed as ReadOnlySpan<byte> but it didn't communicate back the offset
of the decoded data.
The SMTP GSSAPI authentication code was thus reading incorrect data.
In case the underlying authentication was Kerberos the data were
not encrypted and they were located at the beginning of the buffer
so it was not an issue. In case the underlying authentication was
NTLM it was looking at the NTLM signature token which luckily
happens to always start with the bytes 01 00 00 00. That exactly
matched the expected value by accident.
The last token in the GSSAPI SASL authentication mechanism is a bit
mask that specifies the supported security protections offered by the
server and the maximum token size. The client is supposed to choose
one of the protections and reply back. Relax the check to actually
support servers that offer anything but "no protection". As long
as the server also offers no protection we can choose it.
Updated the managed NTLM implementation and the fake servers to
implement the specification quirk:
MS-SPNG section 3.2.5.1 NTLM RC4 Key State for MechListMIC and First
Signed Message specifies that the RC4 sealing keys are reset back to
the initial state for the first message.
Since the managed implementation doesn't expose encryption yet it
didn't affect any observable behavior. Likewise the fake servers
didn't need this code path yet.

@wfurtwfurt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
cc: @SteveSyfuhs for any thoughts on the GSSAPI/SSPI changes.

@wfurt

Copy link
Copy Markdown
Member

contributes to #19436

@wfurtwfurt mentioned this pull request Jun 30, 2022
@wfurt
wfurt merged commit ac9e1f9 into dotnet:mainJun 30, 2022
@karelzkarelz added this to the 7.0.0 milestone Jul 19, 2022
@ghostghost locked as resolved and limited conversation to collaborators Aug 18, 2022
@filipnavara
filipnavara deleted the smtpauth2 branch June 5, 2025 07:39
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Net.Securitycommunity-contributionIndicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@filipnavara@wfurt@karelz
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Improve interoperability of NTLM encryption/decryption and authentication - #71373

Merged
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2
Jun 30, 2022
Merged

Improve interoperability of NTLM encryption/decryption and authentication#71373
wfurt merged 11 commits into
dotnet:mainfrom
filipnavara:smtpauth2

Conversation

@filipnavara

@filipnavarafilipnavara commented Jun 28, 2022

Copy link
Copy Markdown
Member

Best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

@ghostghost added community-contribution Indicates that the PR has been added by a community member area-System.Net.Security labels Jun 28, 2022
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/ncl, @vcsjones
See info in area-owners.md if you want to be subscribed.

Issue Details

Built on top of #71280, best reviewed commit by commit.

Firstly, it fixes an interoperability scenario for non-encrypted NTLM communication passed through NegotiateStream between Unix and Windows. It updates the NegotiateStreamPal.Encrypt/Decrypt Unix implementation to have the same quirk as the Windows implementation has.

Secondly, it fixes a bunch of bugs in the SmtpClient GSSAPI authentication and adds a loopback server test. This was also tested against a real Microsoft Exchange server to ensure that it works properly and that the encryption/decryption is applied correctly in context of NTLM authentication.

Author:filipnavara
Assignees:-
Labels:

area-System.Net.Security, community-contribution

Milestone:-

NegotiateStream on non-encrypted connections with NTLM sends the
messages in a special `<signature token><plain text message>` format.
That's not something that gss_wrap/gss_unwrap would produce. It can be
produced through gss_get_mic/gss_verify_mic calls though so let's do
that.
The method names were misleading since they wrapped the EncryptMessage
and DecryptMessage native APIs and not the MakeSignature/VerifySignature
APIs that also exist.
…/Decrypt
The SSPI / GSSAPI providers keep track of the sequence numbers
themselves.
This maps directly to the semantics of gss_wrap/gss_unwrap methods
that are used in many specifications. It replaces the misleading name
which in SSPI API is an equivalent of gss_get_mic/gss_verify_mic.
It also fixes the declaration to actually decode the buffers both
on Windows and Unix. In NTLM the content of the message is sealed
and needs to be decoded.
Note that previously on Unix the VerifySignature API didn't decode the
content. On Windows it did decode the content inside a buffer that was
passed as ReadOnlySpan<byte> but it didn't communicate back the offset
of the decoded data.
The SMTP GSSAPI authentication code was thus reading incorrect data.
In case the underlying authentication was Kerberos the data were
not encrypted and they were located at the beginning of the buffer
so it was not an issue. In case the underlying authentication was
NTLM it was looking at the NTLM signature token which luckily
happens to always start with the bytes 01 00 00 00. That exactly
matched the expected value by accident.
The last token in the GSSAPI SASL authentication mechanism is a bit
mask that specifies the supported security protections offered by the
server and the maximum token size. The client is supposed to choose
one of the protections and reply back. Relax the check to actually
support servers that offer anything but "no protection". As long
as the server also offers no protection we can choose it.
Updated the managed NTLM implementation and the fake servers to
implement the specification quirk:
MS-SPNG section 3.2.5.1 NTLM RC4 Key State for MechListMIC and First
Signed Message specifies that the RC4 sealing keys are reset back to
the initial state for the first message.
Since the managed implementation doesn't expose encryption yet it
didn't affect any observable behavior. Likewise the fake servers
didn't need this code path yet.

@wfurtwfurt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.
cc: @SteveSyfuhs for any thoughts on the GSSAPI/SSPI changes.

@wfurt

Copy link
Copy Markdown
Member

contributes to #19436

@wfurtwfurt mentioned this pull request Jun 30, 2022
@wfurt
wfurt merged commit ac9e1f9 into dotnet:mainJun 30, 2022
@karelzkarelz added this to the 7.0.0 milestone Jul 19, 2022
@ghostghost locked as resolved and limited conversation to collaborators Aug 18, 2022
@filipnavara
filipnavara deleted the smtpauth2 branch June 5, 2025 07:39
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Net.Securitycommunity-contributionIndicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@filipnavara@wfurt@karelz