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