Asked by:
Configure EAP-TTLS-PAP user credentials using WlanSetProfileEapXmlUserData

Question
-
Hi,
I'm currently working on an app that must connect automatically to WiFi networks without user interaction. I am trying to store EAPTTLS UserProperties credentials using WlanSetProfileEapXmlUserData.
While issuing WlanSetProfileEapXmlUserData I am getting the error 57893
I am using the UserProperties.xml which is generated using EAP-TTLS-PAP UserProperties schema as below.
EAP-TTLS-PAP schema:
------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
targetNamespace="http://www.microsoft.com/provisioning/EapTtlsUserPropertiesV1"
elementFormDefault="qualified"
xmlns="http://www.microsoft.com/provisioning/EapTtlsUserPropertiesV1"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapUserPropertiesV1"
version="1.0"
>
<xs:import
namespace="http://www.microsoft.com/provisioning/BaseEapUserPropertiesV1"
schemaLocation="BaseEapUserPropertiesV1.xsd"
/>
<xs:element name="eapTtls" type="EapTtls"/>
<xs:complexType name="EapTtls">
<xs:complexContent>
<xs:extension base="TtlsCred"/>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="TtlsCred">
<xs:sequence>
<xs:element name="Username" type="xs:string" minOccurs="0"/>
<xs:element name="Password" type="xs:string" minOccurs="0"/>
<xs:element ref="baseEap:Eap" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Generates UserProperties.xml file
---------------------------------
<?xml version="1.0"?>
<EapHostUserCredentials xmlns="http://www.microsoft.com/provisioning/EapHostUserCredentials" xmlns:eapCommon="http://www.microsoft.com/provisioning/EapCommon" xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapMethodUserCredentials">
<EapMethod>
<eapCommon:Type>21</eapCommon:Type>
<eapCommon:AuthorId>311</eapCommon:AuthorId>
</EapMethod>
<Credentials xmlns:eapUser="http://www.microsoft.com/provisioning/EapUserPropertiesV1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapUserPropertiesV1" xmlns:EapTtls="http://www.microsoft.com/provisioning/EapTtlsUserPropertiesV1">
<baseEap:Eap>
<baseEap:Type>21</baseEap:Type>
<baseEap:EapTtls xmlns="http://www.microsoft.com/provisioning/EapTtlsUserPropertiesV1">
<EapTtls:TtlsCred>
<Username>test@abc.com</Username>
<Password>testABC</Password>
<baseEap:Eap xmlns="http://www.microsoft.com/provisioning/BaseEapUserPropertiesV1">
<Type>21</Type>
</baseEap:Eap>
</EapTtls:TtlsCred>
</baseEap:EapTtls>
</baseEap:Eap>
</Credentials>
</EapHostUserCredentials>
When I try to use the WlanSetProfileEapXmlUserData function for a successful set profile using PEAP MSCHAPV2.
OS:Win10 64 bit.
Can any help with an sample to set user properties for EAP-TTLS-PAP.
Thanks in advance,
SriniTuesday, May 21, 2019 10:51 AM
All replies
-
Hi,
It seems that there are few such documents. I tried to extract this example from MSDN, hoping to help you.
<?xml version="1.0" encoding="utf-8"?> <xs:schema targetNamespace="http://www.microsoft.com/provisioning/EapTtlsConnectionPropertiesV1" elementFormDefault="qualified" xmlns="http://www.microsoft.com/provisioning/EapTtlsConnectionPropertiesV1" xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1" xmlns:xs="http://www.w3.org/2001/XMLSchema" > <xs:import namespace="http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1" schemaLocation="BaseEapConnectionPropertiesV1.xsd" /> <xs:element name="eapTtls" type="EapTtls"/> <xs:complexType name="EapTtls"> <xs:complexContent> <xs:extension base="TtlsConfig"/> </xs:complexContent> </xs:complexType> <xs:complexType name="TtlsConfig"> <xs:sequence> <xs:element name="ServerValidation" type="ServerValidationParameters" minOccurs="0"/> <xs:element name="Phase2Authentication" type="Phase2AuthenticationParameters" minOccurs="0"/> <xs:element name="Phase1Identity" type="Phase1IdentityParameters" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="ServerValidationParameters"> <xs:sequence> <xs:element name="ServerNames" type="xs:string" minOccurs="0"/> <xs:element name="TrustedRootCAHashes" type="xs:hexBinary" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="DisablePrompt" type="xs:boolean" default="false" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="Phase2AuthenticationParameters"> <xs:sequence> <xs:choice> <xs:element ref="baseEap:Eap" minOccurs="0" maxOccurs="unbounded"/> <xs:element name="PAPAuthentication" type="emptyString" minOccurs="0"/> <xs:element name="CHAPAuthentication" type="emptyString" minOccurs="0"/> <xs:element name="MSCHAPAuthentication" type="emptyString" minOccurs="0"/> <xs:element name="MSCHAPv2Authentication" type="MSCHAPv2AuthenticationParameters" minOccurs="0"/> </xs:choice> </xs:sequence> </xs:complexType> <xs:complexType name="Phase1IdentityParameters"> <xs:sequence> <xs:element name="IdentityPrivacy" type="xs:boolean" default="true" minOccurs="0"/> <xs:element name="AnonymousIdentity" type="xs:string" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:complexType name="MSCHAPv2AuthenticationParameters"> <xs:sequence> <xs:element name="UseWinlogonCredentials" type="xs:boolean" default="false" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:simpleType name="emptyString"> <xs:restriction base="xs:string"> <xs:maxLength value="0"/> </xs:restriction> </xs:simpleType> </xs:schema>
Best regards,
Strive
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.Wednesday, May 22, 2019 9:45 AM -
Hi Strive,
Thanks for the reply.
XSD which you attached is about connection profile.
I am able to set the EAP-TTLS PAP connection profile successfully.
I am facing an issue with setting the EAP-TTLS PAP user credential profile using "WlanSetProfileEapXmlUserData" API.
Connection profile:
--------------------
<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
<name>Passpoint</name>
<SSIDConfig>
<SSID>
<hex>50617373706F696E74</hex>
<name>Passpoint</name>
</SSID>
<nonBroadcast>false</nonBroadcast>
</SSIDConfig>
<Hotspot2>
<DomainName>test.com</DomainName>
<NAIRealm>
<name>test.com</name>
</NAIRealm>
</Hotspot2>
<connectionType>ESS</connectionType>
<connectionMode>manual</connectionMode>
<autoSwitch>false</autoSwitch>
<MSM>
<security>
<authEncryption>
<authentication>WPA2</authentication>
<encryption>AES</encryption>
<useOneX>true</useOneX>
</authEncryption>
<OneX xmlns="http://www.microsoft.com/networking/OneX/v1">
<EAPConfig><EapHostConfig xmlns="http://www.microsoft.com/provisioning/EapHostConfig"><EapMethod><Type xmlns="http://www.microsoft.com/provisioning/EapCommon">21</Type><VendorId xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorId><VendorType xmlns="http://www.microsoft.com/provisioning/EapCommon">0</VendorType><AuthorId xmlns="http://www.microsoft.com/provisioning/EapCommon">311</AuthorId></EapMethod><Config xmlns="http://www.microsoft.com/provisioning/EapHostConfig"><EapTtls xmlns="http://www.microsoft.com/provisioning/EapTtlsConnectionPropertiesV1"><ServerValidation><ServerNames></ServerNames><DisablePrompt>false</DisablePrompt></ServerValidation><Phase2Authentication><PAPAuthentication/></Phase2Authentication><Phase1Identity><IdentityPrivacy>true</IdentityPrivacy><AnonymousIdentity>anonymous@test.com</AnonymousIdentity></Phase1Identity></EapTtls></Config></EapHostConfig></EAPConfig>
</OneX>
</security>
</MSM>
</WLANProfile>
User credential profile
------------------------
<?xml version="1.0"?>
<EapHostUserCredentials xmlns="http://www.microsoft.com/provisioning/EapHostUserCredentials" xmlns:eapCommon="http://www.microsoft.com/provisioning/EapCommon" xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapMethodUserCredentials">
<EapMethod>
<eapCommon:Type>21</eapCommon:Type>
<eapCommon:AuthorId>311</eapCommon:AuthorId>
</EapMethod>
<Credentials xmlns:eapUser="http://www.microsoft.com/provisioning/EapUserPropertiesV1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapUserPropertiesV1" xmlns:EapTtls="http://www.microsoft.com/provisioning/EapTtlsUserPropertiesV1">
<baseEap:Eap>
<baseEap:Type>21</baseEap:Type>
<baseEap:EapTtls xmlns="http://www.microsoft.com/provisioning/EapTtlsUserPropertiesV1">
<EapTtls:TtlsCred>
<Username>test@abc.com</Username>
<Password>testABC</Password>
<baseEap:Eap xmlns="http://www.microsoft.com/provisioning/BaseEapUserPropertiesV1">
<Type>21</Type>
</baseEap:Eap>
</EapTtls:TtlsCred>
</baseEap:EapTtls>
</baseEap:Eap>
</Credentials>
</EapHostUserCredentials>
Please let me know any changes required for User credential profile.
Thanks,
SriniThursday, May 23, 2019 7:09 AM -
Hi, ssriusav
I'm sorry to reply to you now. I don't know if your problem has been solved.
I want to make sure that you use WlanSetProfileEapXmlUserData correctly.Like this sample
void SetProfileEAPXmlUserData(String^ profileName, String^ userData, bool allUsers)
{
GUID g;
WlanProfile::ConvertNative(guid, &g);
pin_ptr<const wchar_t> xml = PtrToStringChars(userData);
pin_ptr<const wchar_t> name = PtrToStringChars(profileName);
DWORD result = WlanSetProfileEapXmlUserData((HANDLE)(void*)handle, &g, name, allUsers ? 1 : 0, xml, NULL);
if (result != ERROR_SUCCESS)
{
System::Runtime::InteropServices::Marshal::ThrowExceptionForHR(HRESULT_FROM_WIN32(result));
}
}In addition, I can't reproduce your error, is it just the user credentials profile error?
Best regards,
Strive
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.Tuesday, June 4, 2019 8:05 AM -
Hi Strive,
Yes, this is user credentials profile error.I am successfully set the user profile for PEAP MSCHAPV2 using WlanSetProfileEapXmlUserData.
When I am trying for EAP-TTLS-PAP user profile I am getting this error.
I think this is a user credential profile configuration problem.<?xml version="1.0"?><EapHostUserCredentials xmlns="http://www.microsoft.com/provisioning/EapHostUserCredentials" xmlns:eapCommon="http://www.microsoft.com/provisioning/EapCommon" xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapMethodUserCredentials">
<EapMethod>
<eapCommon:Type>21</eapCommon:Type>
<eapCommon:AuthorId>311</eapCommon:AuthorId>
</EapMethod>
<Credentials xmlns:eapUser="http://www.microsoft.com/provisioning/EapUserPropertiesV1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapUserPropertiesV1" xmlns:EapTtls="http://www.microsoft.com/provisioning/EapTtlsUserPropertiesV1">
<baseEap:Eap>
<baseEap:Type>21</baseEap:Type>
<baseEap:EapTtls xmlns="http://www.microsoft.com/provisioning/EapTtlsUserPropertiesV1">
<EapTtls:TtlsCred>
<Username>test@abc.com</Username>
<Password>testABC</Password>
<baseEap:Eap xmlns="http://www.microsoft.com/provisioning/BaseEapUserPropertiesV1">
<Type>21</Type>
</baseEap:Eap>
</EapTtls:TtlsCred>
</baseEap:EapTtls>
</baseEap:Eap>
</Credentials>
</EapHostUserCredentials>I did not find any sample user credential profile from MSDN.Please let me know any changes required for User credential profile.
Thanks,
Srini
Tuesday, June 4, 2019 10:46 AM -
Hi Srini,
Thanks for the detailed explanation for this issue. I am also able to reproduce this issue on my side and trying to contact the corresponding engineer to work on this issue.
I will be back to update at 6/14/2019 or as soon as possible if there is any progress for this issue.
Update
We are still investing on this issue your patience is appreciate.
Regards & Fei
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.- Edited by Fei XueMicrosoft employee Tuesday, June 18, 2019 2:16 AM
Friday, June 7, 2019 6:26 AM -
Hi.
may i see your successfully set the user profile for PEAP MSCHAPV2 using WlanSetProfileEapXmlUserData?
Thanks
Monday, June 10, 2019 8:32 AM -
Hi,
PEAP MSCHAPV2 - User data
-------------------------------------------
<EapHostUserCredentials xmlns="http://www.microsoft.com/provisioning/EapHostUserCredentials" xmlns:eapCommon="http://www.microsoft.com/provisioning/EapCommon" xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapMethodUserCredentials">
<EapMethod>
<eapCommon:Type>25</eapCommon:Type>
<eapCommon:AuthorId>0</eapCommon:AuthorId>
</EapMethod>
<Credentials xmlns:eapUser="http://www.microsoft.com/provisioning/EapUserPropertiesV1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:baseEap="http://www.microsoft.com/provisioning/BaseEapUserPropertiesV1" xmlns:MsPeap="http://www.microsoft.com/provisioning/MsPeapUserPropertiesV1" xmlns:MsChapV2="http://www.microsoft.com/provisioning/MsChapV2UserPropertiesV1">
<baseEap:Eap>
<baseEap:Type>25</baseEap:Type>
<MsPeap:EapType>
<MsPeap:RoutingIdentity>username@abc.com</MsPeap:RoutingIdentity>
<baseEap:Eap>
<baseEap:Type>26</baseEap:Type>
<MsChapV2:EapType>
<MsChapV2:Username>username@abc.com</MsChapV2:Username>
<MsChapV2:Password>xxxxxxxx</MsChapV2:Password>
</MsChapV2:EapType>
</baseEap:Eap>
</MsPeap:EapType>
</baseEap:Eap>
</Credentials>
</EapHostUserCredentials>Currently, I am working on hotspot2(Passpoint). I am able to set the WLAN profile for EAP-TTLS-PAP.
I am facing an issue with set user profile data for EAP-TTLS-PAP.Thanks,
Srini
Monday, June 10, 2019 9:18 AM -
Hi ssriusav,
Based on the our support engineer's feedback, the issue is relative to that nodes in the XML input file has some issues with respect to Schema. We are still debugging through the trace and trying to identify the node. Here is the detail info:
0:000> kL
# ChildEBP RetAddr
00 00afc668 63e1486d OLEAUT32!SysAllocStringLen+0x42
01 (Inline) -------- msxml6!String::getSafeBSTR+0xc
02 00afc6a8 69a0b096 msxml6!DOMError::get_reason+0x5d
03 00afcaf8 699fe946 TtlsCfg!EapMethodXmlUtil::validateDoc+0xba
04 00afcc24 6dc30f64 TtlsCfg!EapPeerCredentialsXml2Blob+0x266
05 00afdd04 6dc1fc3a eappcfg!EapLm::Peer::EapMethodConfig::CredentialsXml2Blob+0x214
06 00afe570 6dc21c59 eappcfg!EapHost::Peer::GetCredentailsFromXml+0x1ab
07 00aff64c 60d8107e eappcfg!EapHostPeerCredentialsXml2Blob+0x549
08 00aff6dc 60d68bf1 wlanapi!EapHlpGetEapBlobFromXmlUserData+0xff
09 00aff774 011ee438 wlanapi!WlanSetProfileEapXmlUserData+0x361
WARNING: Stack unwind information not available. Following frames may be wrong.
0a 00aff914 011ef51e eapDemo+0x1e438
0b 00aff928 011ef387 eapDemo+0x1f51e
0c 00aff984 011ef21d eapDemo+0x1f387
0d 00aff98c 011ef598 eapDemo+0x1f21d
0e 00aff994 761b0419 eapDemo+0x1f598
0f 00aff9a4 778e662d KERNEL32!BaseThreadInitThunk+0x19
10 00affa00 778e65fd ntdll!__RtlUserThreadStart+0x2f
11 00affa10 00000000 ntdll!_RtlUserThreadStart+0x1b
0:000> dv
psz = 0x1b61eea0 "The node is neither valid nor invalid because no DTD/Schema declaration was found..."
len = 0x54
pappdata = <value unavailable>
cbTotal = <value unavailable>
bstr = 0x00195368 "Р???"
And would you mind let me know if the XML data from the link below works for you?
https://docs.microsoft.com/en-us/windows/desktop/eaphost/eap-tls-user-properties
Regards & Fei
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.Wednesday, June 26, 2019 1:26 AM -
Hi Fei,
The EAP-TLS User Properties which you provided in the link is not working.I am looking for EAP-TTLS User Properties.
Thanks,
Srini
Friday, June 28, 2019 5:18 AM -
Hi Srini,
Thanks for this info.
Our engineer is still working on this issue and any progress I will also update here immediately.
Update
Please feel free to let me know if the XML below works for you to set the user name and password for EAP-TTLS:
<?xml version=\"1.0\" encoding=\"UTF-8\"?> <EapHostUserCredentials xmlns=\"http://www.microsoft.com/provisioning/EapHostUserCredentials\" xmlns:eapCommon=\"http://www.microsoft.com/provisioning/EapCommon\" xmlns:baseEap=\"http://www.microsoft.com/provisioning/BaseEapMethodUserCredentials\"> <EapMethod> <eapCommon:Type>21</eapCommon:Type> <eapCommon:AuthorId>311</eapCommon:AuthorId> </EapMethod> <Credentials xmlns=\"http://www.microsoft.com/provisioning/EapHostUserCredentials\"> <EapTtls xmlns=\"http://www.microsoft.com/provisioning/EapTtlsUserPropertiesV1\"> <Username>eapauto</Username> <Password>!password1</Password> </EapTtls> </Credentials> </EapHostUserCredentials>";
Regards & Fei
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.- Edited by Fei XueMicrosoft employee Friday, July 12, 2019 7:59 AM
Wednesday, July 3, 2019 1:07 AM -
I am trying to do something similar to Srini but that XML you posted doesn't work for me. I get the following error:
1206: ERROR_BAD_PROFILEFriday, August 23, 2019 8:27 PM -
Have there been any updates about this? I seem to be only running into dead threads about this.Tuesday, February 25, 2020 3:27 PM
-
I'm having the same issues. I got past the profile errors (which was no small feat without any working examples or functional documentation), but ultimately I get an access violation reading 0x000... from TtlsCfg.dll.
I can give you a few clues here, where you'll get past the config errors, but eventually will hit the access violation in TtlsCfg.dll.
In C:\Windows\schemas\, you will find two folders: EAPHost and EAPMethods. Inside those folders, you will find the schemas for all of these xml namespaces, so that will help resolve some of the mystery (especially for EapTtlsUserPropertiesv1, which has no documentation online).
Now that you're familiar with that, take a close look at EapTtlsUserPropertiesv1. The element name under which Username and Password go, is "eapTtls" (case sensitive). So, in the example above (from Fei Xue), that would fail with a non-zero return code when passed to WlanSetProfileEapXmlUserData(). When you get to <EapTtls... you need another level there. Like this...
<EapTtls xmlns=\"http://www.microsoft.com/provisioning/EapTtlsUserPropertiesV1\">
Don't get too excited, though. That will get you past the return code errors, and will lead you down the path of extreme frustration with access violation in TtlsCfg.dll. I still have no been able to solve that.
<eapTtls>
<Username>eapauto</Username> <Password>!password1</Password>
</eapTtls>
</EapTtls>
However, I do have another suspicion... Notice that EapTtlsUserCredentialsv1 imports BaseEapUserPropertiesv1 -- like a parent/child class relationship. Go ahead and open that up, you'll find it in those folders I mentioned. Now, direct your eyes at this part:
<xs:element name="EapType" type="BaseEapTypeParameters" abstract="true"/>
<xs:element name="Identity" type="xs:string" abstract="true" />
I don't claim to know exactly how this stuff works, but I do understand classes with abstract elements -- and these xml notations smell a lot like that. So, what we have here is a child class, EapTtlsUserPropertiesv1 that inherits from a parent class with abstract elements. But it's not overriding/implementing them. Oops!
To back up this hunch... since PEAP works, open up MsPeapUserPropertiesv1. Take a look at these lines:
<xs:element name="RoutingIdentity" substitutionGroup="baseEap:Identity"/>
<xs:element name="EapType" substitutionGroup="baseEap:EapType">
You can follow those further, but basically, peap has the substitutionGroup attribute in there, which appears to be implementing those abstract elements. And, since MSCHAPv2 is usually used with PEAP, you can open up that one and see similar things in there:
<xs:element name="Username" substitutionGroup="baseEap:Identity"/>
<xs:element name="EapType" substitutionGroup="baseEap:EapType">
The mschapv2 stuff goes in a baseEap:Eap node tree below the MsPeap tree, further overriding those abstracts. EapTtlsUserPropertiesv1 is not doing any of that.
I've been poking around to see if I can unravel some of those other APIs shown in the stack dump above, such as EapHostPeerCredentialsXml2Blob, to try to figure out how to construct the blob directly and use WlanSetProfileEapUserData() with the blob instead of WlanSetProfileEapXmlUserData() with the xml; since something looks broken with the xml interpretation for Ttls -- either because the EapTtlsUserPropertiesv1 schema is wrong, or because those xml interpretation apis have a problem. If the underlying classes and code in TtlsCfg.dll are broken, then none of this will help. I just don't know.
And I'm not so confident to rule out the possibility that we're messing up this ttls xml because we're not burying mschapv2 within it, as is done with PEAP -- but the EapTtlsUserPropertiesv1 doesn't seem to have the same extensions section available to be able to do that.
Help from MS would be greatly appreciated here. As with the poster IncPlusPlus above, all I run into on this problem are dead threads as well.
- Edited by matt_hamilton Thursday, March 5, 2020 11:29 PM Edited references to other posts
Thursday, March 5, 2020 11:21 PM