Subversion Repositories Aucun

Rev

Rev 221 | Rev 223 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
114 ixe013 1
/*
2
 Copyright (c) 2008, Guillaume Seguin ([email protected])
3
 All rights reserved.
4
 
5
 Redistribution and use in source and binary forms, with or without
6
 modification, are permitted provided that the following conditions
7
 are met:
8
 
9
 1. Redistributions of source code must retain the above copyright
10
    notice, this list of conditions and the following disclaimer.
11
 
12
 2. Redistributions in binary form must reproduce the above copyright
13
    notice, this list of conditions and the following disclaimer in the
14
    documentation and/or other materials provided with the distribution.
15
 
16
 THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
17
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
20
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 SUCH DAMAGE.
27
*/
28
 
112 ixe013 29
#include <windows.h>
138 ixe013 30
#include <wincrypt.h>
112 ixe013 31
#include "loggedout_dlg.h"
32
#include "dlgdefs.h"
33
#include "trace.h"
114 ixe013 34
#include "settings.h"
137 ixe013 35
#include "global.h"
112 ixe013 36
 
114 ixe013 37
#define _SECURE_ATL 1
38
 
39
#include <atlbase.h>
191 ixe013 40
#include "atlapp.h"
41
#include "atlctrls.h"
114 ixe013 42
#include "StaticPrompt.h"
43
 
138 ixe013 44
#include "randpasswd.h"
162 ixe013 45
#include "securityhelper.h"
121 ixe013 46
 
138 ixe013 47
 
137 ixe013 48
wchar_t gUsername[512] = L"";
215 ixe013 49
size_t gUsername_len = sizeof gUsername / sizeof * gUsername;
121 ixe013 50
 
164 ixe013 51
//We want a long password (16 chars) that changes at every boot
52
//But we also need a beacon (5 chars) to know if its a left over password
53
//from a previous boot.
54
const wchar_t gEncryptedTag[] = L"AUCUN";
215 ixe013 55
const size_t gEncryptedTag_len = sizeof gEncryptedTag / sizeof * gEncryptedTag;
164 ixe013 56
#define TAGGED_AUCUN_PWLEN (AUCUN_PWLEN+gEncryptedTag_len)
57
//And the buffer must be multiple of the  block size (I guess)
215 ixe013 58
wchar_t gEncryptedRandomSelfservePassword[CRYPTPROTECTMEMORY_BLOCK_SIZE * (((TAGGED_AUCUN_PWLEN - 1) / CRYPTPROTECTMEMORY_BLOCK_SIZE) + 1)] = L"";
221 ixe013 59
const DWORD gEncryptedRandomSelfservePassword_len = CRYPTPROTECTMEMORY_BLOCK_SIZE * (((TAGGED_AUCUN_PWLEN - 1) / CRYPTPROTECTMEMORY_BLOCK_SIZE) + 1);
164 ixe013 60
 
114 ixe013 61
static CStaticPromptCtrl gStaticPrompt;
62
 
63
enum
64
{
215 ixe013 65
    IDC_SELFSERVE_FIRST = 1000,
66
    IDC_SELFSERVEPROMPT
114 ixe013 67
};
68
 
116 ixe013 69
//Moves a control in a dialog
113 ixe013 70
void MoveControl(HWND hwndDlg, int id, int xoffset, int yoffset)
71
{
215 ixe013 72
    HWND control = GetDlgItem(hwndDlg, id);
73
    RECT rect;
74
    //Move the bottom row controls (Ok, Cancel, Options, etc.)
75
    GetWindowRect(control, &rect);
76
    POINT p;
77
    p.x = rect.left;
78
    p.y = rect.top;
79
    ScreenToClient(hwndDlg, &p);
80
    MoveWindow(control, p.x + xoffset, p.y + yoffset, rect.right - rect.left, rect.bottom - rect.top, TRUE);
113 ixe013 81
}
82
 
122 ixe013 83
// Gets the margin between the control and the parent's window border
121 ixe013 84
int GetDialogLeftMargin(HWND hwndDlg, int control)
85
{
215 ixe013 86
    RECT rect;
87
    POINT p;
88
    //As far left as the static controls
89
    GetWindowRect(GetDlgItem(hwndDlg, control), &rect);
90
    p.x = rect.left;
91
    p.y = rect.top;
92
    ScreenToClient(hwndDlg, &p);
93
    return p.x;
121 ixe013 94
}
95
 
96
 
122 ixe013 97
// Add a static control under between the password field and the ok button
116 ixe013 98
HWND AddStaticPrompt(HWND hwndDlg)
112 ixe013 99
{
215 ixe013 100
    HWND hwndPrompt = 0;
101
    wchar_t prompt[2048];
112 ixe013 102
 
215 ixe013 103
    if (GetSelfServeSetting(L"Text", prompt, sizeof prompt / sizeof * prompt) == S_OK)
104
    {
105
        RECT rect;
106
        POINT p;
107
        int increase = 0;
108
        int margin =  GetDialogLeftMargin(hwndDlg, 1506); //Username label
109
        //On the same line as the ok buttons (they will be moved)
110
        GetWindowRect(GetDlgItem(hwndDlg, IDOK), &rect);
111
        p.x = rect.left;
112
        p.y = rect.top;
113
        //As far right as the Option button
114
        GetWindowRect(GetDlgItem(hwndDlg, 1514), &rect);
115
        //As far left as the Ok button
116
        rect.left = p.x;
117
        //Here, rect contains the outer rectangle including all buttons from the bottom row
118
        //rect = left, top and bottom of IDOK,   right of 1514 (options);
119
        //Now convert the top-left coordinate in client for CreateWindow
120
        ScreenToClient(hwndDlg, &p);
121
        //We have the top left corner and the width. Let's create the dialog so we can
122
        //compute the height of the text
123
        hwndPrompt = CreateWindowEx(0, L"STATIC", InterpretCarriageReturn(prompt), SS_LEFT | SS_NOTIFY | WS_CHILD, //|WS_VISIBLE,
124
                                    p.x, p.y, rect.right - rect.left, 100, hwndDlg, (HMENU)IDC_SELFSERVEPROMPT, 0, 0);
125
        gStaticPrompt.SubclassWindow(hwndPrompt);
126
        increase = gStaticPrompt.ComputeRequiredHeight();
127
        gStaticPrompt.MoveWindow(p.x, p.y, rect.right - rect.left, increase);
128
        //Get the original window's dimension
129
        GetWindowRect(hwndDlg, &rect);
130
        //Make it bigger
131
        SetWindowPos(hwndDlg, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top + increase + margin, SWP_NOMOVE | SWP_NOZORDER);
132
        //Move the bottom row controls (Ok, Cancel, Options, etc.)
133
        MoveControl(hwndDlg, 24064, 0, increase + margin); //Bitmap (shows current keyboard layout)
134
        MoveControl(hwndDlg, IDOK, 0, increase + margin); //OK button
135
        MoveControl(hwndDlg, IDCANCEL, 0, increase + margin); //Cancel button
136
        MoveControl(hwndDlg, 1501, 0, increase + margin); //Shutdown button
137
        MoveControl(hwndDlg, 1514, 0, increase + margin); //Option button
138
        AnimateWindow(hwndPrompt, 200, AW_VER_POSITIVE | AW_SLIDE);
139
    }
112 ixe013 140
 
215 ixe013 141
    return hwndPrompt;
116 ixe013 142
}
143
 
122 ixe013 144
 
116 ixe013 145
INT_PTR CALLBACK MyWlxWkstaLoggedOutSASDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
146
{
215 ixe013 147
    static HWND hwndPrompt = 0;
148
    static int password_chances = -1;
149
    bool handled = false;
150
    INT_PTR result = 0;
116 ixe013 151
 
215 ixe013 152
    switch (uMsg)
153
    {
154
        case WM_INITDIALOG :
155
            {
156
                wchar_t buf[32];
217 ixe013 157
 
158
                DialogLParamHook* myinitparam = (DialogLParamHook*)lParam;
159
                lParam = myinitparam->HookedLPARAM;
160
 
161
                result = gDialogsProc[LOGGED_OUT_SAS_dlg].originalproc(hwndDlg, uMsg, wParam, lParam);
215 ixe013 162
                handled = true;
122 ixe013 163
 
215 ixe013 164
                if(pgAucunContext->mLogonScenario == eAutoLogon)
165
                {
166
                    SetDlgItemText(hwndDlg, 1502, gUsername);
167
                    SetDlgItemText(hwndDlg, 1503, gEncryptedRandomSelfservePassword);
168
 
169
                    //TODO : wipe gEncryptedRandomSelfservePassword
170
 
171
                    //Click on OK for the user
172
                    PostMessage(hwndDlg, WM_COMMAND, MAKEWPARAM(IDOK, 0), 0);
173
                }
174
                else if(*gEncryptedRandomSelfservePassword
175
                        && (GetSelfServeSetting(L"Attemps", buf, sizeof buf / sizeof * buf) == S_OK))
176
                {
177
                    password_chances = _wtoi(buf);
122 ixe013 178
 
215 ixe013 179
                    if (password_chances > 16)   //Some hardcoded limit to 16
180
                    {
181
                        password_chances = 3;
182
                    }
183
                    else if(password_chances == 0)
184
                    {
185
                        hwndPrompt = AddStaticPrompt(hwndDlg);    //Add the prompt right away
186
                    }
187
                }
188
                else
189
                {
190
                    password_chances = -1;
191
                }
192
            }
193
            break;
194
        case WM_COMMAND :
123 ixe013 195
 
215 ixe013 196
            if ((HIWORD(wParam) == STN_CLICKED) && (LOWORD(wParam == IDC_SELFSERVEPROMPT)))
197
            {
198
                RECT rect;
199
                wchar_t username[255];
200
                int decrease;
201
                int margin =  GetDialogLeftMargin(hwndDlg, 1506); //Username label
202
                gStaticPrompt.GetWindowRect(&rect);
203
                decrease = rect.bottom - rect.top;
204
                gStaticPrompt.ShowWindow(SW_HIDE);
205
                //AnimateWindow(hwndPrompt, 200, AW_VER_NEGATIVE|AW_SLIDE|AW_HIDE);
206
                //Move the bottom row controls (Ok, Cancel, Options, etc.)
207
                MoveControl(hwndDlg, 24064, 0, -decrease - margin); //Bitmap (shows current keyboard layout)
208
                MoveControl(hwndDlg, IDOK, 0, -decrease - margin); //OK button
209
                MoveControl(hwndDlg, IDCANCEL, 0, -decrease - margin); //Cancel button
210
                MoveControl(hwndDlg, 1501, 0, -decrease - margin); //Shutdown button
211
                MoveControl(hwndDlg, 1514, 0, -decrease - margin); //Option button
212
                GetWindowRect(hwndDlg, &rect);
213
                SetWindowPos(hwndDlg, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top - decrease - margin, SWP_NOMOVE | SWP_FRAMECHANGED);
214
                //Save the username that user tried to logon
215
                GetDlgItemText(hwndDlg, 1502, gUsername, (int)gUsername_len);
216
                //TODO : Provide a safe default if registry is misconfigured
217
                GetSelfServeSetting(L"Username", username, sizeof username / sizeof * username);
218
                TRACE(eERROR, L"Switching to selfservice user %s\n", username);
219
                ShowWindow(GetDlgItem(hwndDlg, 1502), SW_HIDE); //Username
220
                ShowWindow(GetDlgItem(hwndDlg, 1503), SW_HIDE); //Password
221
                ShowWindow(GetDlgItem(hwndDlg, 1504), SW_HIDE); //Domain
222
                SetDlgItemText(hwndDlg, 1502, username);
113 ixe013 223
 
215 ixe013 224
                if(*gEncryptedRandomSelfservePassword)
225
                {
213 ixe013 226
                    //TODO : Decrypt password
215 ixe013 227
                    //CryptUnprotectMemory(gEncryptedRandomSelfservePassword, gEncryptedRandomSelfservePassword_len, CRYPTPROTECTMEMORY_SAME_LOGON);
228
                    TRACE(eINFO, L"Password is %s", gEncryptedRandomSelfservePassword + gEncryptedTag_len - 1);
229
                    SetDlgItemText(hwndDlg, 1503, gEncryptedRandomSelfservePassword + gEncryptedTag_len - 1);
230
                    //TODO : Encrypt memory
231
                    //CryptProtectMemory(gEncryptedRandomSelfservePassword, gEncryptedRandomSelfservePassword_len, CRYPTPROTECTMEMORY_SAME_LOGON);
232
                }
138 ixe013 233
 
215 ixe013 234
                //*/
235
                //No need to post a new message, change this click on the prompt
236
                //to a click on OK
237
                wParam = IDOK;
238
                lParam = (LPARAM)GetDlgItem(hwndDlg, IDOK);
239
            }
240
            else if (wParam == IDOK)
241
            {
242
                if (password_chances > 0)
243
                {
244
                    --password_chances;
245
                }
246
            }
164 ixe013 247
 
215 ixe013 248
            break;
249
        case WM_ENABLE:
164 ixe013 250
 
215 ixe013 251
            if ((wParam == TRUE) && (password_chances == 0) && !hwndPrompt)
252
            {
253
                TRACE(eINFO, L"Clicked OK but credential dialog is shown again.\n");
254
                hwndPrompt = AddStaticPrompt(hwndDlg);
222 ixe013 255
            } else {
256
                ShowWindow(GetDlgItem(hwndDlg, 1502), SW_SHOW); //Username
257
                ShowWindow(GetDlgItem(hwndDlg, 1503), SW_SHOW); //Password
258
                ShowWindow(GetDlgItem(hwndDlg, 1504), SW_SHOW); //Domain
215 ixe013 259
            }
122 ixe013 260
 
215 ixe013 261
            break;
262
        case WM_DESTROY:
263
            hwndPrompt = 0;
264
            break;
265
    }
122 ixe013 266
 
215 ixe013 267
    if (!handled)
268
    {
269
        result = gDialogsProc[LOGGED_OUT_SAS_dlg].originalproc(hwndDlg, uMsg, wParam, lParam);
270
    }
122 ixe013 271
 
215 ixe013 272
    return result;
112 ixe013 273
}
137 ixe013 274