Subversion Repositories Aucun

Rev

Rev 165 | Rev 192 | 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
 
137 ixe013 218
                //Save the username that user tried to logon
219
                GetDlgItemText(hwndDlg, 1502, gUsername, gUsername_len);
220
 
221
 
222
                //TODO : Provide a safe default if registry is misconfigured
121 ixe013 223
            GetSelfServeSetting(L"Username", username, sizeof username / sizeof *username);
122 ixe013 224
            TRACE(eERROR, L"Switching to selfservice user %s\n", username);
121 ixe013 225
 
226
            ShowWindow(GetDlgItem(hwndDlg, 1502), SW_HIDE); //Username
227
            ShowWindow(GetDlgItem(hwndDlg, 1503), SW_HIDE); //Password
228
            ShowWindow(GetDlgItem(hwndDlg, 1504), SW_HIDE); //Domain
229
 
230
            SetDlgItemText(hwndDlg, 1502, username);
138 ixe013 231
 
154 ixe013 232
                if(*gEncryptedRandomSelfservePassword)
138 ixe013 233
                {
164 ixe013 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
 
240
                   CryptProtectMemory(gEncryptedRandomSelfservePassword, gEncryptedRandomSelfservePassword_len, CRYPTPROTECTMEMORY_SAME_LOGON);
138 ixe013 241
                }
122 ixe013 242
            //*/
243
 
244
            //No need to post a new message, change this click on the prompt
245
            //to a click on OK
246
            wParam = IDOK;
247
            lParam = (LPARAM)GetDlgItem(hwndDlg, IDOK);
121 ixe013 248
         }
122 ixe013 249
         else if (wParam == IDOK)
250
         {
123 ixe013 251
            if (password_chances > 0)
252
               --password_chances;
122 ixe013 253
         }
121 ixe013 254
         break;
122 ixe013 255
 
256
      case WM_ENABLE:
123 ixe013 257
         if ((wParam == TRUE) && (password_chances == 0) && !hwndPrompt)
122 ixe013 258
         {
259
            TRACE(eINFO, L"Clicked OK but credential dialog is shown again.\n");
260
            hwndPrompt = AddStaticPrompt(hwndDlg);
261
         }
262
 
263
         break;
121 ixe013 264
      case WM_DESTROY:
265
         hwndPrompt = 0;
266
         break;
267
   }
268
 
269
   if (!handled)
270
      result = gDialogsProc[LOGGED_OUT_SAS_dlg].originalproc(hwndDlg, uMsg, wParam, lParam);
271
 
272
   return result;
112 ixe013 273
}
137 ixe013 274