@@ -94,6 +94,12 @@ void ESP8266WebServer::begin() {
94
94
collectHeaders (0 , 0 );
95
95
}
96
96
97
+ String ESP8266WebServer::_exractParam (String& authReq,const String& param,const char delimit){
98
+ int _begin = authReq.indexOf (param);
99
+ if (_begin==-1 ) return " " ;
100
+ return authReq.substring (_begin+param.length (),authReq.indexOf (delimit,_begin+param.length ()));
101
+ }
102
+
97
103
bool ESP8266WebServer::authenticate (const char * username, const char * password){
98
104
if (hasHeader (AUTHORIZATION_HEADER)){
99
105
String authReq = header (AUTHORIZATION_HEADER);
@@ -121,15 +127,106 @@ bool ESP8266WebServer::authenticate(const char * username, const char * password
121
127
}
122
128
delete[] toencode;
123
129
delete[] encoded;
130
+ }else if (authReq.startsWith (" Digest" )){
131
+ authReq = authReq.substring (7 );
132
+ #ifdef DEBUG_ESP_HTTP_SERVER
133
+ DEBUG_OUTPUT.println (authReq);
134
+ #endif
135
+ String _username = _exractParam (authReq," username=\" " );
136
+ if ((!_username.length ())||_username!=String (username)){
137
+ authReq = String ();
138
+ return false ;
139
+ }
140
+ // extracting required parameters for RFC 2069 simpler Digest
141
+ String _realm = _exractParam (authReq," realm=\" " );
142
+ String _nonce = _exractParam (authReq," nonce=\" " );
143
+ String _uri = _exractParam (authReq," uri=\" " );
144
+ String _response = _exractParam (authReq," response=\" " );
145
+ String _opaque = _exractParam (authReq," opaque=\" " );
146
+
147
+ if ((!_realm.length ())||(!_nonce.length ())||(!_uri.length ())||(!_response.length ())||(!_opaque.length ())){
148
+ authReq = String ();
149
+ return false ;
150
+ }
151
+ if ((_opaque!=_sopaque)||(_nonce!=_snonce)||(_realm!=_srealm)){
152
+ authReq = String ();
153
+ return false ;
154
+ }
155
+ // parameters for the RFC 2617 newer Digest
156
+ String _nc,_cnonce;
157
+ if (authReq.indexOf (" qop=auth" ) != -1 ){
158
+ _nc = _exractParam (authReq," nc=" ,' ,' );
159
+ _cnonce = _exractParam (authReq," cnonce=\" " );
160
+ }
161
+ MD5Builder md5;
162
+ md5.begin ();
163
+ md5.add (String (username)+" :" +_realm+" :" +String (password)); // md5 of the user:realm:user
164
+ md5.calculate ();
165
+ String _H1 = md5.toString ();
166
+ #ifdef DEBUG_ESP_HTTP_SERVER
167
+ DEBUG_OUTPUT.println (" Hash of user:realm:pass=" + _H1);
168
+ #endif
169
+ md5.begin ();
170
+ if (_currentMethod == HTTP_GET){
171
+ md5.add (" GET:" +_uri);
172
+ }else if (_currentMethod == HTTP_POST){
173
+ md5.add (" POST:" +_uri);
174
+ }else if (_currentMethod == HTTP_PUT){
175
+ md5.add (" PUT:" +_uri);
176
+ }else if (_currentMethod == HTTP_DELETE){
177
+ md5.add (" DELETE:" +_uri);
178
+ }else {
179
+ md5.add (" GET:" +_uri);
180
+ }
181
+ md5.calculate ();
182
+ String _H2 = md5.toString ();
183
+ #ifdef DEBUG_ESP_HTTP_SERVER
184
+ DEBUG_OUTPUT.println (" Hash of GET:uri=" + _H2);
185
+ #endif
186
+ md5.begin ();
187
+ if (authReq.indexOf (" qop=auth" ) != -1 ){
188
+ md5.add (_H1+" :" +_nonce+" :" +_nc+" :" +_cnonce+" :auth:" +_H2);
189
+ }else {
190
+ md5.add (_H1+" :" +_nonce+" :" +_H2);
191
+ }
192
+ md5.calculate ();
193
+ String _responsecheck = md5.toString ();
194
+ #ifdef DEBUG_ESP_HTTP_SERVER
195
+ DEBUG_OUTPUT.println (" The Proper response=" +_responsecheck);
196
+ #endif
197
+ if (_response==_responsecheck){
198
+ authReq = String ();
199
+ return true ;
200
+ }
124
201
}
125
202
authReq = String ();
126
203
}
127
204
return false ;
128
205
}
129
206
130
- void ESP8266WebServer::requestAuthentication (){
131
- sendHeader (" WWW-Authenticate" , " Basic realm=\" Login Required\" " );
132
- send (401 );
207
+ String ESP8266WebServer::_getRandomHexString (){
208
+ char buffer[33 ]; // buffer to hold 32 Hex Digit + /0
209
+ int i;
210
+ for (i=0 ;i<4 ;i++){
211
+ sprintf (buffer+(i*8 ), " %08x" , RANDOM_REG32);
212
+ }
213
+ return String (buffer);
214
+ }
215
+
216
+ void ESP8266WebServer::requestAuthentication (HTTPAuthMethod mode, const char * realm, const String& authFailMsg){
217
+ if (realm==NULL ){
218
+ _srealm = " Login Required" ;
219
+ }else {
220
+ _srealm = String (realm);
221
+ }
222
+ if (mode==BASIC_AUTH){
223
+ sendHeader (" WWW-Authenticate" , " Basic realm=\" " + _srealm + " \" " );
224
+ }else {
225
+ _snonce=_getRandomHexString ();
226
+ _sopaque=_getRandomHexString ();
227
+ sendHeader (" WWW-Authenticate" , " Digest realm=\" " +_srealm + " \" , qop=\" auth\" , nonce=\" " +_snonce+" \" , opaque=\" " +_sopaque+" \" " );
228
+ }
229
+ send (401 ," text/html" ,authFailMsg);
133
230
}
134
231
135
232
void ESP8266WebServer::on (const String &uri, ESP8266WebServer::THandlerFunction handler) {
0 commit comments