| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574 |
- #include "./resultWinampAuth.h"
- #include "./common.h"
- #include "./commandWinampAuth.h"
- #include "./loginData.h"
- #include "./dataCredentials.h"
- #include "./loginCredentials.h"
- #include "./loginbox.h"
- #include "../resource.h"
- LoginResultWinampAuth::LoginResultWinampAuth(api_auth *auth, LoginDataCredentials *pInput, Callback fnCallback, void *pUser)
- : ref(1), authApi(auth), input(pInput), callback(fnCallback), user(pUser),
- thread(NULL), abort(NULL), completed(NULL), credentials(NULL), authCode(AUTH_NOT_AUTHORIZED), statusCookie(0)
- {
- InitializeCriticalSection(&lock);
- authApi->AddRef();
- input->AddRef();
- }
- LoginResultWinampAuth::~LoginResultWinampAuth()
- {
- if (NULL != abort)
- CloseHandle(abort);
- if (NULL != completed)
- CloseHandle(completed);
- if (NULL != thread)
- CloseHandle(thread);
-
- authApi->Release();
- input->Release();
-
- if (NULL != credentials)
- credentials->Release();
- DeleteCriticalSection(&lock);
- }
- HRESULT LoginResultWinampAuth::CreateInstance(LoginData *input, Callback callback, void *user, LoginResultWinampAuth **instance)
- {
- if (NULL == instance) return E_POINTER;
- *instance = NULL;
-
- LoginDataCredentials *credentialsInput;
- if (NULL == input || FAILED(input->QueryInterface(IID_LoginDataCredentials, (void**)&credentialsInput)))
- return E_INVALIDARG;
- HRESULT hr;
- api_auth *authApi;
-
- HWND hLoginbox = credentialsInput->GetLoginbox();
- if (NULL == hLoginbox || FALSE == LoginBox_GetAuthApi(hLoginbox, &authApi))
- hr = E_FAIL;
- else
- {
- LoginResultWinampAuth *result = new LoginResultWinampAuth(authApi, credentialsInput, callback, user);
- if (NULL == result)
- hr = E_OUTOFMEMORY;
- else
- {
- hr = result->Start();
- if (FAILED(hr))
- {
- result->Release();
- result = NULL;
- }
- else
- {
- *instance = result;
- }
- }
- authApi->Release();
- }
- credentialsInput->Release();
- return hr;
- }
- STDMETHODIMP_(ULONG) LoginResultWinampAuth::AddRef(void)
- {
- return InterlockedIncrement((LONG*)&ref);
- }
- STDMETHODIMP_(ULONG) LoginResultWinampAuth::Release(void)
- {
- if (0 == ref)
- return ref;
-
- LONG r = InterlockedDecrement((LONG*)&ref);
- if (0 == r)
- delete(this);
-
- return r;
- }
- STDMETHODIMP LoginResultWinampAuth::QueryInterface(REFIID riid, PVOID *ppvObject)
- {
- if (NULL == ppvObject)
- return E_POINTER;
-
- if (IsEqualIID(riid, LCUID_WINAMPAUTH))
- *ppvObject = static_cast<LoginResultWinampAuth*>(this);
- else if (IsEqualIID(riid, IID_IUnknown))
- *ppvObject = static_cast<IUnknown*>(this);
- else
- {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
- if (NULL == *ppvObject)
- return E_UNEXPECTED;
- AddRef();
- return S_OK;
- }
- size_t LoginResultWinampAuth::Wasabi_AddRef()
- {
- return AddRef();
- }
- size_t LoginResultWinampAuth::Wasabi_Release()
- {
- return Release();
- }
- int LoginResultWinampAuth::Wasabi_QueryInterface(GUID iid, void **object)
- {
- return QueryInterface(iid, object);
- }
- HRESULT LoginResultWinampAuth::Start()
- {
- //HRESULT hr;
- HANDLE threadCopy = NULL;
- input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_INITIALIZING));
- EnterCriticalSection(&lock);
- if (NULL != thread)
- {
- //hr = E_PENDING;
- }
- else
- {
- AddRef();
- thread = CreateThread(NULL, 0, WinampAuth_ThreadProcCallback, this, CREATE_SUSPENDED, NULL);
- if (NULL == thread)
- {
- Release();
- }
- else
- {
- if (0 == DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &threadCopy, 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- ResumeThread(thread); // grr...
- threadCopy = NULL;
- }
- }
- }
- LeaveCriticalSection(&lock);
- if (NULL != threadCopy)
- {
- ResumeThread(threadCopy);
- CloseHandle(threadCopy);
- }
- return S_OK;
- }
- DWORD LoginResultWinampAuth::ThreadProc()
- {
- Callback callbackCopy(NULL);
- HANDLE completedCopy(NULL);
- INT resultCode = AUTH_SUCCESS;
- LPWSTR username(NULL), password(NULL);
-
- api_auth::AuthResults authResults;
- SecureZeroMemory(&authResults, sizeof(authResults));
- EnterCriticalSection(&lock);
- authCode = AUTH_NOT_AUTHORIZED;
- if (NULL != credentials)
- {
- credentials->Release();
- credentials = NULL;
- }
- LeaveCriticalSection(&lock);
- username = GetUsername(input->GetUsername(), &resultCode);
-
- if (AUTH_SUCCESS == resultCode)
- password = GetPassword(input->GetPassword(), &resultCode);
-
- if (AUTH_SUCCESS == resultCode)
- {
- if (NULL == input->GetContext())
- {
- resultCode = authApi->Login(username, password, &authResults, this);
- }
- else
- {
- LPWSTR passcode = GetPasscode(input->GetPasscode(), &resultCode);
- if (AUTH_SUCCESS == resultCode)
- {
- resultCode = authApi->LoginSecurID(username, password, input->GetContext(), passcode, &authResults, this);
- LoginBox_FreeStringSecure(passcode);
- }
- }
- }
-
- EnterCriticalSection(&lock);
-
- authCode = resultCode;
- switch(authCode)
- {
- case AUTH_SUCCESS:
- {
- GUID realm;
- if (FAILED(input->GetRealm(&realm)) ||
- FAILED(LoginCredentials::CreateInstance(&realm, username, authResults.session_key,
- authResults.token, authResults.expire, &credentials)))
- {
- authCode = AUTH_UNEXPECTED;
- }
- }
- break;
- case AUTH_SECURID:
- if(FAILED(input->SetContext(authResults.context)))
- authCode = AUTH_NOT_AUTHORIZED;
- break;
- }
-
- INT statusId;
- switch(authCode)
- {
- case AUTH_SUCCESS: statusId = IDS_STATUS_SUCCEEDED; break;
- case AUTH_SECURID: statusId = IDS_STATUS_PASSCODE_REQUIRED; break;
- case AUTH_ABORT: statusId = IDS_STATUS_ABORTED; break;
- default: statusId = IDS_STATUS_FAILED; break;
- }
- input->SetStatus(MAKEINTRESOURCE(statusId));
- CloseHandle(thread);
- thread = NULL;
- callbackCopy = callback;
- if (NULL == completed || FALSE == DuplicateHandle(GetCurrentProcess(), completed,
- GetCurrentProcess(), &completedCopy, 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- completedCopy = NULL;
- }
-
- LeaveCriticalSection(&lock);
- SecureZeroMemory(&authResults, sizeof(authResults));
- LoginBox_FreeStringSecure(username);
- LoginBox_FreeStringSecure(password);
- if (NULL != completedCopy)
- {
- SetEvent(completedCopy);
- CloseHandle(completedCopy);
- }
- if (NULL != callbackCopy)
- callbackCopy(this);
-
- return 0;
- }
- HRESULT LoginResultWinampAuth::GetWaitHandle(HANDLE *handle)
- {
- if (NULL == handle)
- return E_POINTER;
- HRESULT hr = S_OK;
- EnterCriticalSection(&lock);
- if (NULL == completed)
- {
- completed = CreateEvent(NULL, TRUE, (S_OK == IsCompleted()), NULL);
- if (NULL == completed)
- {
- *handle = NULL;
- DWORD error = GetLastError();
- hr = HRESULT_FROM_WIN32(error);
- }
- }
- if (SUCCEEDED(hr) &&
- FALSE == DuplicateHandle(GetCurrentProcess(), completed,
- GetCurrentProcess(), handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
- {
- *handle = NULL;
- DWORD error = GetLastError();
- hr = HRESULT_FROM_WIN32(error);
- }
-
- LeaveCriticalSection(&lock);
- return hr;
- }
- HRESULT LoginResultWinampAuth::GetUser(void **pUser)
- {
- if (NULL == pUser) return E_POINTER;
- EnterCriticalSection(&lock);
- *pUser = user;
- LeaveCriticalSection(&lock);
- return S_OK;
- }
- HRESULT LoginResultWinampAuth::RequestAbort(BOOL fDrop)
- {
- HRESULT hr;
- EnterCriticalSection(&lock);
- if (NULL == abort)
- {
- abort = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (NULL == abort)
- {
- DWORD error = GetLastError();
- hr = HRESULT_FROM_WIN32(error);
- }
- }
-
- if (NULL != abort && FALSE == SetEvent(abort))
- {
- DWORD error = GetLastError();
- hr = HRESULT_FROM_WIN32(error);
- }
- else
- {
- input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_ABORTING));
- }
-
- if (FALSE != fDrop)
- {
- callback = NULL;
- user = NULL;
- }
- LeaveCriticalSection(&lock);
- return hr;
- }
- HRESULT LoginResultWinampAuth::IsCompleted()
- {
- return (NULL == thread) ? S_OK : S_FALSE;
- }
- HRESULT LoginResultWinampAuth::IsAborting()
- {
- return IsAbortingEx(0);
- }
- HRESULT LoginResultWinampAuth::IsAbortingEx(UINT waitMs)
- {
- return (NULL != abort && WAIT_OBJECT_0 == WaitForSingleObjectEx(abort, waitMs, TRUE))?
- S_OK : S_FALSE;
- }
- HRESULT LoginResultWinampAuth::GetLoginData(LoginData **loginData)
- {
- if (NULL == loginData) return E_POINTER;
- EnterCriticalSection(&lock);
-
- *loginData = input;
- if (NULL != input)
- input->AddRef();
- LeaveCriticalSection(&lock);
- return S_OK;
- }
- HRESULT LoginResultWinampAuth::GetResult(INT *pAuthCode, LoginCredentials **ppCredentials)
- {
- if (S_OK != IsCompleted())
- return E_PENDING;
- EnterCriticalSection(&lock);
- if (NULL != pAuthCode)
- *pAuthCode = authCode;
- if (NULL != ppCredentials)
- {
- *ppCredentials = credentials;
- if (NULL != credentials)
- credentials->AddRef();
- }
- LeaveCriticalSection(&lock);
-
- return S_OK;
- }
- int LoginResultWinampAuth::Event_AuthConnecting()
- {
- if (S_OK == IsAbortingEx(0))
- return 1;
- input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_CONNECTING));
- return 0;
- }
- int LoginResultWinampAuth::Event_AuthSending()
- {
- if (S_OK == IsAbortingEx(0))
- return 1;
- input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_SENDING));
- return 0;
- }
- int LoginResultWinampAuth::Event_AuthReceiving()
- {
- if (S_OK == IsAbortingEx(0))
- return 1;
- input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_RECEIVING));
- return 0;
- }
- int LoginResultWinampAuth::Event_AuthIdle()
- {
- if (S_OK == IsAbortingEx(50))
- return 1;
- return 0;
- }
- LPWSTR LoginResultWinampAuth::GetUsername(LPCWSTR pszInput, INT *authError)
- {
- return MakeAuthParam(pszInput, -1, 3, 48, TRUE, TRUE, (0xFFFF & ~C1_CNTRL), AUTH_USERNAME, authError);
- }
- LPWSTR LoginResultWinampAuth::GetPassword(LPCWSTR pszInput, INT *authError)
- {
- return MakeAuthParam(pszInput, -1, 6, 48, TRUE, FALSE, (0xFFFF & ~C1_CNTRL), AUTH_PASSWORD, authError);
- }
- LPWSTR LoginResultWinampAuth::GetPasscode(LPCWSTR pszInput, INT *authError)
- {
- return MakeAuthParam(pszInput, -1, 6, 6, FALSE, FALSE, C1_DIGIT, AUTH_PASSCODE, authError);
- }
- LPWSTR LoginResultWinampAuth::MakeAuthParam(LPCWSTR pszInput, INT cchInput, INT min, INT max, BOOL removeSpaces, BOOL firstLetter, WORD typeMask, INT errorBase, INT *authError)
- {
- if (cchInput < 0 || NULL == pszInput)
- cchInput = (NULL != pszInput) ? lstrlen(pszInput) : 0;
- if (cchInput < min || (FALSE == removeSpaces && cchInput > max))
- {
- if (NULL != authError)
- *authError = errorBase + ((cchInput < min) ? AUTHPARAM_TOOSHORT : AUTHPARAM_TOOLONG);
- return NULL;
- }
- WORD *info = (WORD*)calloc(cchInput, sizeof(WORD));
- if (NULL == info)
- {
- if (NULL != authError) *authError = AUTH_UNEXPECTED;
- return NULL;
- }
- if (FALSE == GetStringTypeW(CT_CTYPE1, pszInput, cchInput, info))
- {
- free(info);
- if (NULL != authError) *authError = AUTH_UNEXPECTED;
- return NULL;
- }
-
- INT error = AUTH_SUCCESS;
- LPWSTR dest = NULL;
-
- BOOL firstChecked = FALSE;
- INT cchSpaces = 0;
- for (INT i = 0; i < cchInput; i++)
- {
- if (FALSE != removeSpaces && 0 != (C1_SPACE & info[i]))
- cchSpaces++;
- else if (0 == (typeMask & info[i]))
- {
- error = errorBase + AUTHPARAM_BADFORMAT;
- break;
- }
- else
- {
- if (FALSE != firstLetter && FALSE == firstChecked)
- {
- if (0 == (C1_ALPHA & info[i]))
- {
- error = errorBase + AUTHPARAM_BADFORMAT;
- break;
- }
- firstChecked = TRUE;
- }
- }
- }
- if (AUTH_SUCCESS == error)
- {
- INT cchTotal = cchInput - cchSpaces;
- if (cchTotal < min)
- error = errorBase + AUTHPARAM_TOOSHORT;
- else if (cchTotal > max)
- error = errorBase + AUTHPARAM_TOOLONG;
- else
- {
- dest = LoginBox_MallocString(cchTotal + 1);
- if (NULL == dest)
- error = AUTH_UNEXPECTED;
- else
- {
- if (FALSE != removeSpaces)
- {
- LPCWSTR s = pszInput;
- LPWSTR d = dest;
- for (INT i = 0; i < cchInput; i++, s++)
- {
- if (0 == (C1_SPACE & info[i]))
- {
- *d = *s;
- d++;
- }
- }
- *d = L'\0';
- }
- else
- {
- CopyMemory(dest, pszInput, (cchInput * sizeof(WCHAR)));
- dest[cchInput] = L'\0';
- }
- }
- }
- }
-
-
- free(info);
- if (NULL != authError)
- *authError = error;
- return dest;
- }
- static DWORD WINAPI WinampAuth_ThreadProcCallback(void *param)
- {
- LoginResultWinampAuth *result =(LoginResultWinampAuth*)param;
- if (NULL == result) return 1;
-
- INT exitCode = result->ThreadProc();
- result->Release();
- return exitCode;
- }
- #define CBCLASS LoginResultWinampAuth
- START_DISPATCH;
- CB(ADDREF, Wasabi_AddRef)
- CB(RELEASE, Wasabi_Release)
- CB(QUERYINTERFACE, Wasabi_QueryInterface)
- CB(ONCONNECTING, Event_AuthConnecting)
- CB(ONSENDING, Event_AuthSending)
- CB(ONRECEIVING, Event_AuthReceiving)
- CB(ONIDLE, Event_AuthIdle)
- END_DISPATCH;
- #undef CBCLASS
|