Subversion Repositories Aucun

Rev

Rev 147 | Rev 161 | 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>
31
#include <lm.h>
112 ixe013 32
#include "loggedout_dlg.h"
33
#include "dlgdefs.h"
34
#include "trace.h"
114 ixe013 35
#include "settings.h"
137 ixe013 36
#include "global.h"
112 ixe013 37
 
114 ixe013 38
#define _SECURE_ATL 1
39
 
40
#include <atlbase.h>
41
#include <atlapp.h>
42
#include <atlctrls.h>
43
#include "StaticPrompt.h"
44
 
138 ixe013 45
#include "randpasswd.h"
121 ixe013 46
 
138 ixe013 47
 
137 ixe013 48
wchar_t gUsername[512] = L"";
49
size_t gUsername_len = sizeof gUsername / sizeof *gUsername;
138 ixe013 50
#pragma data_seg (".sharedseg")
154 ixe013 51
wchar_t gEncryptedRandomSelfservePassword[CRYPTPROTECTMEMORY_BLOCK_SIZE*(((PWLEN-1)/CRYPTPROTECTMEMORY_BLOCK_SIZE)+1)] = L"";
52
size_t gEncryptedRandomSelfservePassword_len = CRYPTPROTECTMEMORY_BLOCK_SIZE*(((PWLEN-1)/CRYPTPROTECTMEMORY_BLOCK_SIZE)+1);
138 ixe013 53
#pragma data_seg ()
121 ixe013 54
 
114 ixe013 55
static CStaticPromptCtrl gStaticPrompt;
56
 
57
enum
58
{
121 ixe013 59
   IDC_SELFSERVE_FIRST = 1000,
60
   IDC_SELFSERVEPROMPT
114 ixe013 61
};
62
 
116 ixe013 63
//Moves a control in a dialog
113 ixe013 64
void MoveControl(HWND hwndDlg, int id, int xoffset, int yoffset)
65
{
121 ixe013 66
   HWND control = GetDlgItem(hwndDlg, id);
113 ixe013 67
 
121 ixe013 68
   RECT rect;
113 ixe013 69
 
121 ixe013 70
   //Move the bottom row controls (Ok, Cancel, Options, etc.)
71
   GetWindowRect(control, &rect);
72
   POINT p;
73
   p.x = rect.left;
74
   p.y = rect.top;
113 ixe013 75
 
121 ixe013 76
   ScreenToClient(hwndDlg, &p);
113 ixe013 77
 
121 ixe013 78
   MoveWindow(control, p.x+xoffset, p.y+yoffset, rect.right-rect.left, rect.bottom-rect.top, TRUE);
113 ixe013 79
}
80
 
122 ixe013 81
// Gets the margin between the control and the parent's window border
121 ixe013 82
int GetDialogLeftMargin(HWND hwndDlg, int control)
83
{
84
   RECT rect;
85
   POINT p;
86
   //As far left as the static controls
87
   GetWindowRect(GetDlgItem(hwndDlg, control), &rect);
88
   p.x = rect.left;
89
   p.y = rect.top;
90
   ScreenToClient(hwndDlg, &p);
91
   return p.x;
116 ixe013 92
 
121 ixe013 93
}
94
 
95
 
122 ixe013 96
// Add a static control under between the password field and the ok button
116 ixe013 97
HWND AddStaticPrompt(HWND hwndDlg)
112 ixe013 98
{
121 ixe013 99
   HWND hwndPrompt = 0;
100
   wchar_t prompt[2048];
101
   if (GetSelfServeSetting(L"Text", prompt, sizeof prompt / sizeof *prompt) == S_OK)
102
   {
103
      RECT rect;
104
      POINT p;
105
      int increase = 0;
106
      int margin =  GetDialogLeftMargin(hwndDlg, 1506); //Username label
112 ixe013 107
 
121 ixe013 108
      //On the same line as the ok buttons (they will be moved)
109
      GetWindowRect(GetDlgItem(hwndDlg, IDOK), &rect);
110
      p.x = rect.left;
111
      p.y = rect.top;
112 ixe013 112
 
121 ixe013 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;
114 ixe013 117
 
121 ixe013 118
      //Here, rect contains the outer rectangle including all buttons from the bottom row
119
      //rect = left, top and bottom of IDOK,   right of 1514 (options);
115 ixe013 120
 
121 ixe013 121
      //Now convert the top-left coordinate in client for CreateWindow
122
      ScreenToClient(hwndDlg, &p);
114 ixe013 123
 
121 ixe013 124
      //We have the top left corner and the width. Let's create the dialog so we can
125
      //compute the height of the text
123 ixe013 126
      hwndPrompt = CreateWindowEx(0, L"STATIC", InterpretCarriageReturn(prompt), SS_LEFT|SS_NOTIFY|WS_CHILD,//|WS_VISIBLE,
121 ixe013 127
                                  p.x, p.y, rect.right-rect.left, 100, hwndDlg, (HMENU)IDC_SELFSERVEPROMPT, 0, 0);
114 ixe013 128
 
121 ixe013 129
      gStaticPrompt.SubclassWindow(hwndPrompt);
114 ixe013 130
 
121 ixe013 131
      increase = gStaticPrompt.ComputeRequiredHeight();
114 ixe013 132
 
121 ixe013 133
      gStaticPrompt.MoveWindow(p.x, p.y, rect.right-rect.left, increase);
114 ixe013 134
 
121 ixe013 135
      //Get the original window's dimension
136
      GetWindowRect(hwndDlg, &rect);
137
      //Make it bigger
138
      SetWindowPos(hwndDlg, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top+increase+margin,SWP_NOMOVE|SWP_NOZORDER);
114 ixe013 139
 
121 ixe013 140
      //Move the bottom row controls (Ok, Cancel, Options, etc.)
141
      MoveControl(hwndDlg, 24064, 0, increase+margin); //Bitmap (shows current keyboard layout)
142
      MoveControl(hwndDlg, IDOK, 0, increase+margin);  //OK button
143
      MoveControl(hwndDlg, IDCANCEL, 0, increase+margin); //Cancel button
144
      MoveControl(hwndDlg, 1501, 0, increase+margin);  //Shutdown button
145
      MoveControl(hwndDlg, 1514, 0, increase+margin);  //Option button
114 ixe013 146
 
121 ixe013 147
      AnimateWindow(hwndPrompt, 200, AW_VER_POSITIVE|AW_SLIDE);
148
   }
113 ixe013 149
 
121 ixe013 150
   return hwndPrompt;
116 ixe013 151
}
152
 
122 ixe013 153
 
116 ixe013 154
INT_PTR CALLBACK MyWlxWkstaLoggedOutSASDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
155
{
121 ixe013 156
   static HWND hwndPrompt = 0;
123 ixe013 157
   static int password_chances = -1;
121 ixe013 158
   bool handled = false;
159
   INT_PTR result = 0;
116 ixe013 160
 
121 ixe013 161
   switch (uMsg)
162
   {
163
      case WM_INITDIALOG :
164
      {
122 ixe013 165
         wchar_t buf[32];
166
 
123 ixe013 167
         result = gDialogsProc[LOGGED_OUT_SAS_dlg].originalproc(hwndDlg, uMsg, wParam, lParam);;
168
         handled = true;
122 ixe013 169
 
123 ixe013 170
         if (GetSelfServeSetting(L"Attemps", buf, sizeof buf / sizeof *buf) == S_OK)
171
         {
172
            password_chances = _wtoi(buf);
173
 
174
            if (password_chances > 16)   //Some hardcoded limit to 16
175
               password_chances = 3;
176
                else if(password_chances == 0)
177
                hwndPrompt = AddStaticPrompt(hwndDlg); //Add the prompt right away
178
         }
179
         else
180
         {
181
                password_chances = -1;
182
         }
121 ixe013 183
      }
184
      break;
113 ixe013 185
 
121 ixe013 186
      case WM_COMMAND :
187
         if ((HIWORD(wParam) == STN_CLICKED) && (LOWORD(wParam == IDC_SELFSERVEPROMPT)))
188
         {
189
            RECT rect;
190
            wchar_t username[255];
191
            int decrease;
192
            int margin =  GetDialogLeftMargin(hwndDlg, 1506); //Username label
114 ixe013 193
 
121 ixe013 194
            gStaticPrompt.GetWindowRect(&rect);
195
            decrease = rect.bottom-rect.top;
113 ixe013 196
 
121 ixe013 197
            gStaticPrompt.ShowWindow(SW_HIDE);
198
            //AnimateWindow(hwndPrompt, 200, AW_VER_NEGATIVE|AW_SLIDE|AW_HIDE);
114 ixe013 199
 
121 ixe013 200
            //Move the bottom row controls (Ok, Cancel, Options, etc.)
201
            MoveControl(hwndDlg, 24064, 0, -decrease-margin); //Bitmap (shows current keyboard layout)
202
            MoveControl(hwndDlg, IDOK, 0, -decrease-margin);  //OK button
203
            MoveControl(hwndDlg, IDCANCEL, 0, -decrease-margin); //Cancel button
204
            MoveControl(hwndDlg, 1501, 0, -decrease-margin);  //Shutdown button
205
            MoveControl(hwndDlg, 1514, 0, -decrease-margin);  //Option button
112 ixe013 206
 
121 ixe013 207
            GetWindowRect(hwndDlg, &rect);
116 ixe013 208
 
121 ixe013 209
            SetWindowPos(hwndDlg, 0, 0, 0, rect.right-rect.left, rect.bottom-rect.top-decrease-margin, SWP_NOMOVE|SWP_FRAMECHANGED);
210
 
137 ixe013 211
                //Save the username that user tried to logon
212
                GetDlgItemText(hwndDlg, 1502, gUsername, gUsername_len);
213
 
214
 
215
                //TODO : Provide a safe default if registry is misconfigured
121 ixe013 216
            GetSelfServeSetting(L"Username", username, sizeof username / sizeof *username);
122 ixe013 217
            TRACE(eERROR, L"Switching to selfservice user %s\n", username);
121 ixe013 218
 
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
 
223
            SetDlgItemText(hwndDlg, 1502, username);
138 ixe013 224
 
147 ixe013 225
                //TODO provide a fail safe so that users are not left with a non-working dialog (SW_SHOW, restore gUsername, etc.)
154 ixe013 226
                if(*gEncryptedRandomSelfservePassword)
138 ixe013 227
                {
228
                    USER_INFO_1003 ui1003;
147 ixe013 229
               NET_API_STATUS nusiresult;
138 ixe013 230
 
154 ixe013 231
                    ui1003.usri1003_password = gEncryptedRandomSelfservePassword;
138 ixe013 232
 
154 ixe013 233
                    //TODO strip domain from username
234
                    nusiresult = NetUserSetInfo(0, L"funny", 1003, (LPBYTE)&ui1003, 0);
147 ixe013 235
                    if(nusiresult == NERR_Success)
138 ixe013 236
                    {
154 ixe013 237
                   SetDlgItemText(hwndDlg, 1503, gEncryptedRandomSelfservePassword);
138 ixe013 238
                    }
147 ixe013 239
                    else
240
                    {
154 ixe013 241
                   TRACE(eERROR, L"Unable to set password %s for selfserve user %s (error %d)\n", gEncryptedRandomSelfservePassword, username, nusiresult);
147 ixe013 242
                    }
154 ixe013 243
                    //TODO Il y a un appel a RtlFreeHeap qui apparait dans Windbg, il faut mettre un breakpoint dessus
138 ixe013 244
                }
122 ixe013 245
            //*/
246
 
247
            //No need to post a new message, change this click on the prompt
248
            //to a click on OK
249
            wParam = IDOK;
250
            lParam = (LPARAM)GetDlgItem(hwndDlg, IDOK);
121 ixe013 251
         }
122 ixe013 252
         else if (wParam == IDOK)
253
         {
123 ixe013 254
            if (password_chances > 0)
255
               --password_chances;
122 ixe013 256
         }
121 ixe013 257
         break;
122 ixe013 258
 
259
      case WM_ENABLE:
123 ixe013 260
         if ((wParam == TRUE) && (password_chances == 0) && !hwndPrompt)
122 ixe013 261
         {
262
            TRACE(eINFO, L"Clicked OK but credential dialog is shown again.\n");
263
            hwndPrompt = AddStaticPrompt(hwndDlg);
264
         }
265
 
266
         break;
121 ixe013 267
      case WM_DESTROY:
268
         hwndPrompt = 0;
269
         break;
270
   }
271
 
272
   if (!handled)
273
      result = gDialogsProc[LOGGED_OUT_SAS_dlg].originalproc(hwndDlg, uMsg, wParam, lParam);
274
 
275
   return result;
112 ixe013 276
}
137 ixe013 277