Subversion Repositories Aucun

Rev

Rev 192 | Rev 215 | 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"";
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";
55
const size_t gEncryptedTag_len = sizeof gEncryptedTag / sizeof *gEncryptedTag;
56
#define TAGGED_AUCUN_PWLEN (AUCUN_PWLEN+gEncryptedTag_len)
57
//And the buffer must be multiple of the  block size (I guess)
58
wchar_t gEncryptedRandomSelfservePassword[CRYPTPROTECTMEMORY_BLOCK_SIZE*(((TAGGED_AUCUN_PWLEN-1)/CRYPTPROTECTMEMORY_BLOCK_SIZE)+1)] = L"";
59
const size_t gEncryptedRandomSelfservePassword_len = CRYPTPROTECTMEMORY_BLOCK_SIZE*(((TAGGED_AUCUN_PWLEN-1)/CRYPTPROTECTMEMORY_BLOCK_SIZE)+1);
60
 
114 ixe013 61
static CStaticPromptCtrl gStaticPrompt;
62
 
63
enum
64
{
121 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
{
121 ixe013 72
   HWND control = GetDlgItem(hwndDlg, id);
113 ixe013 73
 
121 ixe013 74
   RECT rect;
113 ixe013 75
 
121 ixe013 76
   //Move the bottom row controls (Ok, Cancel, Options, etc.)
77
   GetWindowRect(control, &rect);
78
   POINT p;
79
   p.x = rect.left;
80
   p.y = rect.top;
113 ixe013 81
 
121 ixe013 82
   ScreenToClient(hwndDlg, &p);
113 ixe013 83
 
121 ixe013 84
   MoveWindow(control, p.x+xoffset, p.y+yoffset, rect.right-rect.left, rect.bottom-rect.top, TRUE);
113 ixe013 85
}
86
 
122 ixe013 87
// Gets the margin between the control and the parent's window border
121 ixe013 88
int GetDialogLeftMargin(HWND hwndDlg, int control)
89
{
90
   RECT rect;
91
   POINT p;
92
   //As far left as the static controls
93
   GetWindowRect(GetDlgItem(hwndDlg, control), &rect);
94
   p.x = rect.left;
95
   p.y = rect.top;
96
   ScreenToClient(hwndDlg, &p);
97
   return p.x;
116 ixe013 98
 
121 ixe013 99
}
100
 
101
 
122 ixe013 102
// Add a static control under between the password field and the ok button
116 ixe013 103
HWND AddStaticPrompt(HWND hwndDlg)
112 ixe013 104
{
121 ixe013 105
   HWND hwndPrompt = 0;
106
   wchar_t prompt[2048];
107
   if (GetSelfServeSetting(L"Text", prompt, sizeof prompt / sizeof *prompt) == S_OK)
108
   {
109
      RECT rect;
110
      POINT p;
111
      int increase = 0;
112
      int margin =  GetDialogLeftMargin(hwndDlg, 1506); //Username label
112 ixe013 113
 
121 ixe013 114
      //On the same line as the ok buttons (they will be moved)
115
      GetWindowRect(GetDlgItem(hwndDlg, IDOK), &rect);
116
      p.x = rect.left;
117
      p.y = rect.top;
112 ixe013 118
 
121 ixe013 119
      //As far right as the Option button
120
      GetWindowRect(GetDlgItem(hwndDlg, 1514), &rect);
121
      //As far left as the Ok button
122
      rect.left = p.x;
114 ixe013 123
 
121 ixe013 124
      //Here, rect contains the outer rectangle including all buttons from the bottom row
125
      //rect = left, top and bottom of IDOK,   right of 1514 (options);
115 ixe013 126
 
121 ixe013 127
      //Now convert the top-left coordinate in client for CreateWindow
128
      ScreenToClient(hwndDlg, &p);
114 ixe013 129
 
121 ixe013 130
      //We have the top left corner and the width. Let's create the dialog so we can
131
      //compute the height of the text
123 ixe013 132
      hwndPrompt = CreateWindowEx(0, L"STATIC", InterpretCarriageReturn(prompt), SS_LEFT|SS_NOTIFY|WS_CHILD,//|WS_VISIBLE,
121 ixe013 133
                                  p.x, p.y, rect.right-rect.left, 100, hwndDlg, (HMENU)IDC_SELFSERVEPROMPT, 0, 0);
114 ixe013 134
 
121 ixe013 135
      gStaticPrompt.SubclassWindow(hwndPrompt);
114 ixe013 136
 
121 ixe013 137
      increase = gStaticPrompt.ComputeRequiredHeight();
114 ixe013 138
 
121 ixe013 139
      gStaticPrompt.MoveWindow(p.x, p.y, rect.right-rect.left, increase);
114 ixe013 140
 
121 ixe013 141
      //Get the original window's dimension
142
      GetWindowRect(hwndDlg, &rect);
143
      //Make it bigger
144
      SetWindowPos(hwndDlg, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top+increase+margin,SWP_NOMOVE|SWP_NOZORDER);
114 ixe013 145
 
121 ixe013 146
      //Move the bottom row controls (Ok, Cancel, Options, etc.)
147
      MoveControl(hwndDlg, 24064, 0, increase+margin); //Bitmap (shows current keyboard layout)
148
      MoveControl(hwndDlg, IDOK, 0, increase+margin);  //OK button
149
      MoveControl(hwndDlg, IDCANCEL, 0, increase+margin); //Cancel button
150
      MoveControl(hwndDlg, 1501, 0, increase+margin);  //Shutdown button
151
      MoveControl(hwndDlg, 1514, 0, increase+margin);  //Option button
114 ixe013 152
 
121 ixe013 153
      AnimateWindow(hwndPrompt, 200, AW_VER_POSITIVE|AW_SLIDE);
154
   }
113 ixe013 155
 
121 ixe013 156
   return hwndPrompt;
116 ixe013 157
}
158
 
122 ixe013 159
 
116 ixe013 160
INT_PTR CALLBACK MyWlxWkstaLoggedOutSASDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
161
{
121 ixe013 162
   static HWND hwndPrompt = 0;
123 ixe013 163
   static int password_chances = -1;
121 ixe013 164
   bool handled = false;
165
   INT_PTR result = 0;
116 ixe013 166
 
121 ixe013 167
   switch (uMsg)
168
   {
169
      case WM_INITDIALOG :
170
      {
122 ixe013 171
         wchar_t buf[32];
172
 
123 ixe013 173
         result = gDialogsProc[LOGGED_OUT_SAS_dlg].originalproc(hwndDlg, uMsg, wParam, lParam);;
174
         handled = true;
122 ixe013 175
 
163 ixe013 176
            if(*gEncryptedRandomSelfservePassword
177
         &&(GetSelfServeSetting(L"Attemps", buf, sizeof buf / sizeof *buf) == S_OK))
123 ixe013 178
         {
179
            password_chances = _wtoi(buf);
180
 
181
            if (password_chances > 16)   //Some hardcoded limit to 16
182
               password_chances = 3;
183
                else if(password_chances == 0)
184
                hwndPrompt = AddStaticPrompt(hwndDlg); //Add the prompt right away
185
         }
186
         else
187
         {
188
                password_chances = -1;
189
         }
121 ixe013 190
      }
191
      break;
113 ixe013 192
 
121 ixe013 193
      case WM_COMMAND :
194
         if ((HIWORD(wParam) == STN_CLICKED) && (LOWORD(wParam == IDC_SELFSERVEPROMPT)))
195
         {
196
            RECT rect;
197
            wchar_t username[255];
198
            int decrease;
199
            int margin =  GetDialogLeftMargin(hwndDlg, 1506); //Username label
114 ixe013 200
 
121 ixe013 201
            gStaticPrompt.GetWindowRect(&rect);
202
            decrease = rect.bottom-rect.top;
113 ixe013 203
 
121 ixe013 204
            gStaticPrompt.ShowWindow(SW_HIDE);
205
            //AnimateWindow(hwndPrompt, 200, AW_VER_NEGATIVE|AW_SLIDE|AW_HIDE);
114 ixe013 206
 
121 ixe013 207
            //Move the bottom row controls (Ok, Cancel, Options, etc.)
208
            MoveControl(hwndDlg, 24064, 0, -decrease-margin); //Bitmap (shows current keyboard layout)
209
            MoveControl(hwndDlg, IDOK, 0, -decrease-margin);  //OK button
210
            MoveControl(hwndDlg, IDCANCEL, 0, -decrease-margin); //Cancel button
211
            MoveControl(hwndDlg, 1501, 0, -decrease-margin);  //Shutdown button
212
            MoveControl(hwndDlg, 1514, 0, -decrease-margin);  //Option button
112 ixe013 213
 
121 ixe013 214
            GetWindowRect(hwndDlg, &rect);
116 ixe013 215
 
121 ixe013 216
            SetWindowPos(hwndDlg, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top-decrease-margin, SWP_NOMOVE|SWP_FRAMECHANGED);
217
 
192 ixe013 218
            //Save the username that user tried to logon
219
            GetDlgItemText(hwndDlg, 1502, gUsername, (int)gUsername_len);
137 ixe013 220
 
192 ixe013 221
            //TODO : Provide a safe default if registry is misconfigured
121 ixe013 222
            GetSelfServeSetting(L"Username", username, sizeof username / sizeof *username);
122 ixe013 223
            TRACE(eERROR, L"Switching to selfservice user %s\n", username);
121 ixe013 224
 
225
            ShowWindow(GetDlgItem(hwndDlg, 1502), SW_HIDE); //Username
226
            ShowWindow(GetDlgItem(hwndDlg, 1503), SW_HIDE); //Password
227
            ShowWindow(GetDlgItem(hwndDlg, 1504), SW_HIDE); //Domain
228
 
229
            SetDlgItemText(hwndDlg, 1502, username);
138 ixe013 230
 
154 ixe013 231
                if(*gEncryptedRandomSelfservePassword)
138 ixe013 232
                {
213 ixe013 233
                    //TODO : Decrypt password
234
                   //CryptUnprotectMemory(gEncryptedRandomSelfservePassword, gEncryptedRandomSelfservePassword_len, CRYPTPROTECTMEMORY_SAME_LOGON);
138 ixe013 235
 
165 ixe013 236
                    TRACE(eINFO, L"Password is %s", gEncryptedRandomSelfservePassword+gEncryptedTag_len-1);
164 ixe013 237
 
165 ixe013 238
               SetDlgItemText(hwndDlg, 1503, gEncryptedRandomSelfservePassword+gEncryptedTag_len-1);
164 ixe013 239
 
213 ixe013 240
                    //TODO : Encrypt memory
241
                   //CryptProtectMemory(gEncryptedRandomSelfservePassword, gEncryptedRandomSelfservePassword_len, CRYPTPROTECTMEMORY_SAME_LOGON);
138 ixe013 242
                }
122 ixe013 243
            //*/
244
 
245
            //No need to post a new message, change this click on the prompt
246
            //to a click on OK
247
            wParam = IDOK;
248
            lParam = (LPARAM)GetDlgItem(hwndDlg, IDOK);
121 ixe013 249
         }
122 ixe013 250
         else if (wParam == IDOK)
251
         {
123 ixe013 252
            if (password_chances > 0)
253
               --password_chances;
122 ixe013 254
         }
121 ixe013 255
         break;
122 ixe013 256
 
257
      case WM_ENABLE:
123 ixe013 258
         if ((wParam == TRUE) && (password_chances == 0) && !hwndPrompt)
122 ixe013 259
         {
260
            TRACE(eINFO, L"Clicked OK but credential dialog is shown again.\n");
261
            hwndPrompt = AddStaticPrompt(hwndDlg);
262
         }
263
 
264
         break;
121 ixe013 265
      case WM_DESTROY:
266
         hwndPrompt = 0;
267
         break;
268
   }
269
 
270
   if (!handled)
271
      result = gDialogsProc[LOGGED_OUT_SAS_dlg].originalproc(hwndDlg, uMsg, wParam, lParam);
272
 
273
   return result;
112 ixe013 274
}
137 ixe013 275