diff --git a/CredImport/Main.cpp b/CredImport/Main.cpp deleted file mode 100644 index 394386f..0000000 --- a/CredImport/Main.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright 2015-2016 Amebis - Copyright 2016 GÉANT - - This file is part of GEANTLink. - - GEANTLink is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - GEANTLink is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GEANTLink. If not, see . -*/ - -#include "StdAfx.h" - -using namespace std; -using namespace winstd; - - -int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) -{ - UNREFERENCED_PARAMETER(hInstance); - UNREFERENCED_PARAMETER(hPrevInstance); - UNREFERENCED_PARAMETER(lpCmdLine); - UNREFERENCED_PARAMETER(nCmdShow); - - int nArgs; - unique_ptr > pwcArglist(CommandLineToArgvW(GetCommandLineW(), &nArgs)); - if (pwcArglist == NULL) { - OutputDebugStr(_T("CommandLineToArgvW failed (error %i).\n"), GetLastError()); - return 1; - } - - if (nArgs < 3) { - OutputDebugStr(_T("Not enough parameters.\n")); - return -1; - } - - // Decode password (Base64 >> UTF-8 >> UTF-16). - sanitizing_vector password_utf8; - { - base64_dec dec; - bool is_last; - dec.decode(password_utf8, is_last, pwcArglist[2], (size_t)-1); - } - sanitizing_wstring password; - MultiByteToWideChar(CP_UTF8, 0, password_utf8.data(), (int)password_utf8.size(), password); - - return 0; -} diff --git a/CredImport/.gitignore b/CredWrite/.gitignore similarity index 100% rename from CredImport/.gitignore rename to CredWrite/.gitignore diff --git a/CredImport/CredImport.props b/CredWrite/CredWrite.props similarity index 74% rename from CredImport/CredImport.props rename to CredWrite/CredWrite.props index 3a8bb73..2b4b508 100644 --- a/CredImport/CredImport.props +++ b/CredWrite/CredWrite.props @@ -7,7 +7,7 @@ - ..\include;..\lib\WinStd\include;%(AdditionalIncludeDirectories) + ..\lib\WinStd\include;%(AdditionalIncludeDirectories) diff --git a/CredImport/CredImport.rc b/CredWrite/CredWrite.rc similarity index 99% rename from CredImport/CredImport.rc rename to CredWrite/CredWrite.rc index c978e78..c4aed2a 100644 Binary files a/CredImport/CredImport.rc and b/CredWrite/CredWrite.rc differ diff --git a/CredImport/CredImport.vcxproj b/CredWrite/CredWrite.vcxproj similarity index 93% rename from CredImport/CredImport.vcxproj rename to CredWrite/CredWrite.vcxproj index ca8eed0..a8fdccc 100644 --- a/CredImport/CredImport.vcxproj +++ b/CredWrite/CredWrite.vcxproj @@ -21,7 +21,7 @@ {2D3CE079-7EB1-4F47-B79E-F0310671ECCB} Win32Proj - CredImport + CredWrite @@ -53,25 +53,25 @@ - + - + - + - + @@ -95,7 +95,7 @@ - + diff --git a/CredImport/CredImport.vcxproj.filters b/CredWrite/CredWrite.vcxproj.filters similarity index 93% rename from CredImport/CredImport.vcxproj.filters rename to CredWrite/CredWrite.vcxproj.filters index 27fee2b..3b68d98 100644 --- a/CredImport/CredImport.vcxproj.filters +++ b/CredWrite/CredWrite.vcxproj.filters @@ -28,7 +28,7 @@ - + Resource Files diff --git a/CredWrite/Main.cpp b/CredWrite/Main.cpp new file mode 100644 index 0000000..f804109 --- /dev/null +++ b/CredWrite/Main.cpp @@ -0,0 +1,106 @@ +/* + Copyright 2015-2016 Amebis + Copyright 2016 GÉANT + + This file is part of GEANTLink. + + GEANTLink is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + GEANTLink is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GEANTLink. If not, see . +*/ + +#include "StdAfx.h" + +using namespace std; +using namespace winstd; + + +int CALLBACK WinMain(_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) +{ + UNREFERENCED_PARAMETER(hInstance); + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpCmdLine); + UNREFERENCED_PARAMETER(nCmdShow); + + int nArgs; + unique_ptr > pwcArglist(CommandLineToArgvW(GetCommandLineW(), &nArgs)); + if (pwcArglist == NULL) { + OutputDebugStr(_T("CommandLineToArgvW failed (error %u).\n"), GetLastError()); + return 1; + } + + if (nArgs < 3) { + OutputDebugStr(_T("Not enough parameters.\n")); + return -1; + } + + // Generate target name (aka realm). + tstring target_name(_T(PRODUCT_NAME_STR) _T("/")); + if (nArgs > 3) { + // User explicitly set the realm. + target_name += pwcArglist[3]; + } else { + // Get the realm from user name. + LPCTSTR domain = _tcschr(pwcArglist[1], _T('@')); + target_name += domain ? ++domain : _T("*"); + } + assert(target_name.length() < CRED_MAX_GENERIC_TARGET_NAME_LENGTH); + + // Prepare password. + string password_enc_utf8; + { + // Convert Base64 >> UTF-8. + sanitizing_vector password_utf8; + base64_dec dec; + bool is_last; + dec.decode(password_utf8, is_last, pwcArglist[2], (size_t)-1); + + // Convert UTF-8 >> UTF-16. + sanitizing_wstring password; + MultiByteToWideChar(CP_UTF8, 0, password_utf8.data(), (int)password_utf8.size(), password); + + // Encrypt the password. + wstring password_enc; + CRED_PROTECTION_TYPE cpt; + if (!CredProtect(TRUE, password.data(), (DWORD)password.size(), password_enc, &cpt)) { + OutputDebugStr(_T("CredProtect failed (error %u).\n"), GetLastError()); + return 2; + } + + // Convert UTF-16 >> UTF-8. + WideCharToMultiByte(CP_UTF8, 0, password_enc.data(), (int)password_enc.size(), password_enc_utf8, NULL, NULL); + } + assert(password_enc_utf8.size()*sizeof(char) < CRED_MAX_CREDENTIAL_BLOB_SIZE); + + // Write credentials. + CREDENTIAL cred = { + 0, // Flags + CRED_TYPE_GENERIC, // Type + (LPWSTR)target_name.c_str(), // TargetName + _T(""), // Comment + { 0, 0 }, // LastWritten + (DWORD)password_enc_utf8.size()*sizeof(char), // CredentialBlobSize + (LPBYTE)password_enc_utf8.data(), // CredentialBlob + CRED_PERSIST_ENTERPRISE, // Persist + 0, // AttributeCount + NULL, // Attributes + NULL, // TargetAlias + pwcArglist[1] // UserName + }; + if (!CredWrite(&cred, 0)) { + OutputDebugStr(_T("CredWrite failed (error %u).\n"), GetLastError()); + return 3; + } + + return 0; +} + diff --git a/CredWrite/README.md b/CredWrite/README.md new file mode 100644 index 0000000..c955577 --- /dev/null +++ b/CredWrite/README.md @@ -0,0 +1,20 @@ +#CredWrite +Imports given credentials to Windows Credential Manager for GEANTLink use + +##Usage +``` +CredWrite [] +``` + +- `username` - a user name usually of the form user@domain +- `password` - Base64 encoded UTF-8 user password +- `realm` - A realm ID to allow grouping of credentials over different WLAN profiles (optional, default is domain part of `username`) + +The credentials are stored to Windows Credential Manager in invoking user's roaming profile. + +Return codes: +- -1 = Invalid parameters +- 0 = Success +- 1 = Error parsing command line +- 2 = Error encrypting password +- 3 = Error writing credentials to Credential Manager diff --git a/CredImport/StdAfx.cpp b/CredWrite/StdAfx.cpp similarity index 100% rename from CredImport/StdAfx.cpp rename to CredWrite/StdAfx.cpp diff --git a/CredImport/StdAfx.h b/CredWrite/StdAfx.h similarity index 90% rename from CredImport/StdAfx.h rename to CredWrite/StdAfx.h index f4cea8d..a98e00e 100644 --- a/CredImport/StdAfx.h +++ b/CredWrite/StdAfx.h @@ -20,7 +20,10 @@ #pragma once +#include "../include/Version.h" + #include +#include #include #include diff --git a/VS10Solution.sln b/VS10Solution.sln index 6eb7bdf..24c056d 100644 --- a/VS10Solution.sln +++ b/VS10Solution.sln @@ -16,7 +16,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinStd", "lib\WinStd\build\ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utilities", "Utilities", "{7B5EC9B7-208C-426A-941D-DAF9271BD4A4}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CredImport", "CredImport\CredImport.vcxproj", "{2D3CE079-7EB1-4F47-B79E-F0310671ECCB}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CredWrite", "CredWrite\CredWrite.vcxproj", "{2D3CE079-7EB1-4F47-B79E-F0310671ECCB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/lib/WinStd b/lib/WinStd index 2cb830b..f6029b2 160000 --- a/lib/WinStd +++ b/lib/WinStd @@ -1 +1 @@ -Subproject commit 2cb830b341ea49e9c69ec332b060e165ad75e1a7 +Subproject commit f6029b2f04f52ae2b692980cb4d5734031568d91