~ubuntu-branches/ubuntu/intrepid/kdebluetooth/intrepid-proposed

« back to all changes in this revision

Viewing changes to kdebluetooth/libqobex/qobex/qobexauth.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Mercatante
  • Date: 2008-08-07 09:49:47 UTC
  • mto: This revision was merged to the branch mainline in revision 56.
  • Revision ID: james.westby@ubuntu.com-20080807094947-pj6q3uxwuv7l844q
Tags: upstream-0.1
ImportĀ upstreamĀ versionĀ 0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    This file is part of libqobex.
3
 
 
4
 
    Copyright (C) 2000 Stefan Westerfeld stefan@space.twc.de
5
 
    Copyright (c) 2003 Mathias Froehlich <Mathias.Froehlich@web.de>
6
 
 
7
 
    This library is free software; you can redistribute it and/or
8
 
    modify it under the terms of the GNU Library General Public
9
 
    License as published by the Free Software Foundation; either
10
 
    version 2 of the License, or (at your option) any later version.
11
 
 
12
 
    This library is distributed in the hope that it will be useful,
13
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 
    Library General Public License for more details.
16
 
 
17
 
    You should have received a copy of the GNU Library General Public License
18
 
    along with this library; see the file COPYING.LIB.  If not, write to
19
 
    the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
20
 
    Boston, MA 02110-1301, USA.
21
 
*/
22
 
 
23
 
#include <stdlib.h>
24
 
#include <string.h>
25
 
#include <ctype.h>
26
 
 
27
 
#include <qstring.h>
28
 
#include <qcstring.h>
29
 
#include <qtextstream.h>
30
 
#include <qtextcodec.h>
31
 
 
32
 
#include "qobexlengthvaluebase.h"
33
 
#include "qobexarray.h"
34
 
#include "qobexauth.h"
35
 
 
36
 
#undef DEBUG
37
 
// #define DEBUG
38
 
#ifdef DEBUG
39
 
#define myDebug(a) qDebug a
40
 
#else
41
 
#define myDebug(a) (void)0
42
 
#endif
43
 
 
44
 
namespace {
45
 
  /*
46
 
    Yet an other md5 sum implementation. The first cut was copied from arts
47
 
    in the KDE cvs tree. Then modified it to fit here.
48
 
    If you find libqobex as part of kde, note that we don't use kde's md5
49
 
    routine since libqobex should also work without kde.
50
 
  */
51
 
 
52
 
  /*
53
 
   * I used the central part of Colin Plumb's public domain MD5 implementation
54
 
   */
55
 
  
56
 
  /*
57
 
   * This code implements the MD5 message-digest algorithm.
58
 
   * The algorithm is due to Ron Rivest.        This code was
59
 
   * written by Colin Plumb in 1993, no copyright is claimed.
60
 
   * This code is in the public domain; do with it what you wish.
61
 
   *
62
 
   * Equivalent code is available from RSA Data Security, Inc.
63
 
   * This code has been tested against that, and is equivalent,
64
 
   * except that you don't need to include two pages of legalese
65
 
   * with every copy.
66
 
   */
67
 
  
68
 
  
69
 
  /* The four core functions - F1 is optimized somewhat */
70
 
  
71
 
  /* #define F1(x, y, z) (x & y | ~x & z) */
72
 
#define F1(x, y, z) (z ^ (x & (y ^ z)))
73
 
#define F2(x, y, z) F1(z, x, y)
74
 
#define F3(x, y, z) (x ^ y ^ z)
75
 
#define F4(x, y, z) (y ^ (x | ~z))
76
 
  
77
 
  /* This is the central step in the MD5 algorithm. */
78
 
#define MD5STEP(f, w, x, y, z, data, s) \
79
 
        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
80
 
  
81
 
  /*
82
 
   * The core of the MD5 algorithm, this alters an existing MD5 hash to
83
 
   * reflect the addition of 16 longwords of new data.  MD5Update blocks
84
 
   * the data and converts bytes into longwords for this routine.
85
 
   */
86
 
  void MD5Transform(Q_UINT32 buf[4], Q_UINT32 in[16])
87
 
  {
88
 
    myDebug(( "MD5Transform()" ));
89
 
    Q_UINT32 a = buf[0];
90
 
    Q_UINT32 b = buf[1];
91
 
    Q_UINT32 c = buf[2];
92
 
    Q_UINT32 d = buf[3];
93
 
    
94
 
    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
95
 
    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
96
 
    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
97
 
    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
98
 
    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
99
 
    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
100
 
    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
101
 
    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
102
 
    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
103
 
    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
104
 
    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
105
 
    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
106
 
    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
107
 
    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
108
 
    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
109
 
    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
110
 
 
111
 
    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
112
 
    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
113
 
    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
114
 
    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
115
 
    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
116
 
    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
117
 
    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
118
 
    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
119
 
    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
120
 
    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
121
 
    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
122
 
    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
123
 
    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
124
 
    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
125
 
    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
126
 
    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
127
 
 
128
 
    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
129
 
    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
130
 
    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
131
 
    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
132
 
    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
133
 
    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
134
 
    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
135
 
    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
136
 
    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
137
 
    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
138
 
    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
139
 
    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
140
 
    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
141
 
    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
142
 
    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
143
 
    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
144
 
 
145
 
    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
146
 
    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
147
 
    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
148
 
    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
149
 
    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
150
 
    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
151
 
    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
152
 
    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
153
 
    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
154
 
    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
155
 
    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
156
 
    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
157
 
    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
158
 
    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
159
 
    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
160
 
    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
161
 
 
162
 
    buf[0] += a;
163
 
    buf[1] += b;
164
 
    buf[2] += c;
165
 
    buf[3] += d;
166
 
  }
167
 
#undef F1
168
 
#undef F2
169
 
#undef F3
170
 
#undef F4
171
 
#undef MD5STEP
172
 
 
173
 
  QByteArray QObexMD5( const QByteArray& data ) {
174
 
    myDebug(( "QObexMD5( ... )" ));
175
 
    QByteArray md5sum(16);
176
 
    unsigned long finalsize = data.size()+1; /* in bytes */
177
 
    unsigned int i = 0, j = 0;
178
 
    unsigned char w = '\0';
179
 
    Q_UINT32 buffer[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476};
180
 
    Q_UINT32 in[16];
181
 
    
182
 
    while((finalsize & 63) != 56) finalsize++;
183
 
    finalsize += 8;
184
 
    
185
 
    for( i=0, j=0; i<finalsize; i++ )
186
 
      {
187
 
        if(i < data.size()) {
188
 
          w = data[i];
189
 
        } else if(i == data.size()) {
190
 
          w = 0x80;
191
 
        } else if((finalsize-i > 8) || (finalsize-i <= 4)) {
192
 
          w = 0;
193
 
        } else {
194
 
          /* well, the length thing encoded in here will only
195
 
             work until 2^32 bits (though md5 would support 2^64
196
 
             bits) */
197
 
          w = ((data.size()*8) >> ((i+8-finalsize)*8)) & 0xff;
198
 
        }
199
 
        switch(i & 3) {
200
 
        case 0: in[j]  = w;
201
 
          break;
202
 
        case 1: in[j] |= w << 8;
203
 
          break;
204
 
        case 2: in[j] |= w << 16;
205
 
          break;
206
 
        case 3: in[j] |= w << 24;
207
 
          j++;
208
 
          if(j == 16) {
209
 
            MD5Transform(buffer,in);
210
 
            j = 0;
211
 
          }
212
 
          break;
213
 
        }
214
 
      }
215
 
    
216
 
    for( i=0, j=0;j<4;j++)
217
 
      {
218
 
        md5sum[i++] = buffer[j] & 0xff;
219
 
        md5sum[i++] = (buffer[j] >> 8) & 0xff;
220
 
        md5sum[i++] = (buffer[j] >> 16) & 0xff;
221
 
        md5sum[i++] = (buffer[j] >> 24) & 0xff;
222
 
      }
223
 
    
224
 
    return md5sum;
225
 
  }
226
 
}
227
 
 
228
 
QObexAuthDigestBase::text_encoding QObexAuthDigestBase::encoding_list[] = {
229
 
  { "ISO-8859-1", QObexAuthDigestBase::Realm_ISO_8859_1 },
230
 
  { "ISO-8859-2", QObexAuthDigestBase::Realm_ISO_8859_2 },
231
 
  { "ISO-8859-3", QObexAuthDigestBase::Realm_ISO_8859_3 },
232
 
  { "ISO-8859-4", QObexAuthDigestBase::Realm_ISO_8859_4 },
233
 
  { "ISO-8859-5", QObexAuthDigestBase::Realm_ISO_8859_5 },
234
 
  { "ISO-8859-6", QObexAuthDigestBase::Realm_ISO_8859_6 },
235
 
  { "ISO-8859-7", QObexAuthDigestBase::Realm_ISO_8859_7 },
236
 
  { "ISO-8859-8", QObexAuthDigestBase::Realm_ISO_8859_8 },
237
 
  { "ISO-8859-9", QObexAuthDigestBase::Realm_ISO_8859_9 },
238
 
  { "utf-16", QObexAuthDigestBase::Realm_UNICODE },
239
 
  // Use latin 1 for ascii. Since latin1 is a superset this should be
240
 
  // ok for conversion to QString.
241
 
  // For conversion to binary arrays we have to check for real latin-1
242
 
  // first and sign that encoding. This way outgoing engodings will
243
 
  // never be ascii, but that does't matter ...
244
 
  { "ISO-8859-1", QObexAuthDigestBase::Realm_ASCII },
245
 
  { 0, 0 }
246
 
};
247
 
 
248
 
void QObexAuthDigestBase::appendStringValue( Q_UINT8 tag, const QString& s ) {
249
 
  QTextCodec* codec = 0;
250
 
  int idx;
251
 
  Q_UINT8 realm = 0;
252
 
  for ( idx = 0; encoding_list[idx].name; ++idx ) {
253
 
    codec = QTextCodec::codecForName( encoding_list[idx].name );
254
 
    if ( codec && codec->canEncode( s ) ) {
255
 
      realm = encoding_list[idx].tag;
256
 
      break;
257
 
    }
258
 
    codec = 0;
259
 
  }
260
 
 
261
 
  if ( !codec ) {
262
 
    // if not found take unicode. This one will fit best ...
263
 
    codec = QTextCodec::codecForName ( "utf-16" );
264
 
    realm = Realm_UNICODE;
265
 
  }
266
 
 
267
 
  if ( !codec )
268
 
    return;
269
 
 
270
 
  QCString encoded = codec->fromUnicode( s );
271
 
  encoded = " " + encoded;
272
 
  encoded.at( 0 ) = realm;
273
 
  appendTag( tag, encoded );
274
 
}
275
 
 
276
 
QString QObexAuthDigestBase::getStringTag( Q_UINT8 tag ) const {
277
 
  QByteArray data = getTag( tag );
278
 
  if ( 1 < data.size() ) {
279
 
    Q_UINT8 realm = data.at( 0 );
280
 
    QTextCodec* codec = 0;
281
 
    int idx;
282
 
    for ( idx = 0; encoding_list[idx].name; ++idx ) {
283
 
      if ( encoding_list[idx].tag == realm ) {
284
 
        codec = QTextCodec::codecForName ( encoding_list[idx].name );
285
 
        break;
286
 
      }
287
 
    }
288
 
 
289
 
    if ( !codec )
290
 
      codec = QTextCodec::codecForContent ( data.data() + 1, data.size() - 1);
291
 
 
292
 
    if ( codec )
293
 
      return codec->toUnicode( data.data() + 1, data.size() - 1 );
294
 
  }
295
 
  return QString::null;
296
 
}
297
 
 
298
 
QByteArray QObexAuthDigestBase::computeDigest( const QByteArray& d1, const QByteArray& d2 ) {
299
 
  QByteArray message( 1 + d1.size() + d2.size() );
300
 
  ::memcpy( message.data(), d1.data(), d1.size() );
301
 
  message[ d1.size() ] = ':';
302
 
  ::memcpy( message.data()+d1.size()+1, d2.data(), d2.size() );
303
 
  return QObexMD5( message );
304
 
}
305
 
 
306
 
QByteArray QObexAuthDigestBase::randomNonce() {
307
 
  myDebug(( "QObexAuthDigestChallenge::randomNonce()" ));
308
 
  QObexArray rnd( 16 );
309
 
  rnd.uint32( 0, ::rand() );
310
 
  rnd.uint32( 4, ::rand() );
311
 
  rnd.uint32( 8, ::rand() );
312
 
  rnd.uint32( 12, ::rand() );
313
 
  return QObexMD5( rnd );
314
 
}
315
 
 
316
 
QString QObexAuthDigestBase::toString( const QByteArray& data ) {
317
 
  QString str;
318
 
  QTextStream stream( &str, IO_WriteOnly );
319
 
 
320
 
  for ( Q_ULONG i = 0; i < data.size(); ++i )
321
 
    stream << QString().sprintf("%02X", (unsigned char)data[i] );
322
 
 
323
 
  return str;
324
 
}
325
 
 
326
 
// Constructor to create data for a new AuthChallenge header.
327
 
QObexAuthDigestChallenge::QObexAuthDigestChallenge( const AuthInfo& ai ) {
328
 
  myDebug(( "QObexAuthDigestChallenge::QObexAuthDigestChallenge( ... )" ));
329
 
 
330
 
  appendTag( NonceTag, randomNonce() );
331
 
 
332
 
  if ( !ai.realm.isNull() )
333
 
    appendStringValue( RealmTag, ai.realm );
334
 
 
335
 
  if ( 0 < ai.options ) {
336
 
    QByteArray data( 1 );
337
 
    data.at( 0 ) = ai.options;
338
 
    appendTag( OptionsTag, data );
339
 
  }
340
 
}
341
 
 
342
 
// Constructor used to parse the data given here.
343
 
QObexAuthDigestChallenge::QObexAuthDigestChallenge( const QByteArray& data )
344
 
  : QObexAuthDigestBase( data ) {
345
 
  myDebug(( "QObexAuthDigestChallenge::QObexAuthDigestChallenge( ... )" ));
346
 
}
347
 
 
348
 
// Needed for list handling
349
 
QObexAuthDigestChallenge::QObexAuthDigestChallenge() {
350
 
  myDebug(( "QObexAuthDigestChallenge::QObexAuthDigestChallenge()" ));
351
 
}
352
 
 
353
 
// Read access to the fields of the header data.
354
 
QByteArray QObexAuthDigestChallenge::nonce() const {
355
 
  myDebug(( "QObexAuthDigestChallenge::nonce()" ));
356
 
  return getTag( NonceTag );
357
 
}
358
 
 
359
 
QString QObexAuthDigestChallenge::realm() const {
360
 
  myDebug(( "QObexAuthDigestChallenge::realm()" ));
361
 
  return getStringTag( RealmTag );
362
 
}
363
 
 
364
 
bool QObexAuthDigestChallenge::hasRealm() const {
365
 
  myDebug(( "QObexAuthDigestChallenge::hasRealm()" ));
366
 
  return hasTag( RealmTag );
367
 
}
368
 
 
369
 
int QObexAuthDigestChallenge::options() const {
370
 
  myDebug(( "QObexAuthDigestChallenge::options()" ));
371
 
  if ( hasTag( OptionsTag ) ) {
372
 
    QObexArray data = getTag( OptionsTag );
373
 
    if ( data.size() == 1 )
374
 
      return data.uint8( 0 );
375
 
    else
376
 
      return 0;
377
 
  } else
378
 
    return 0;
379
 
}
380
 
 
381
 
bool QObexAuthDigestChallenge::readOnly() const {
382
 
  myDebug(( "QObexAuthDigestChallenge::readOnly()" ));
383
 
  return options() & AccessReadOnly;
384
 
}
385
 
 
386
 
bool QObexAuthDigestChallenge::userIdRequired() const {
387
 
  myDebug(( "QObexAuthDigestChallenge::userIdRequired()" ));
388
 
  return options() & SendUserId;
389
 
}
390
 
 
391
 
bool QObexAuthDigestChallenge::hasOptions() const {
392
 
  myDebug(( "QObexAuthDigestChallenge::hasOptions()" ));
393
 
  return hasTag( OptionsTag );
394
 
}
395
 
 
396
 
QString QObexAuthDigestChallenge::toString( int indent ) const {
397
 
  QString indentStr;
398
 
  indentStr.fill( QChar( ' ' ), indent );
399
 
  QString str;
400
 
  QTextStream stream( &str, IO_WriteOnly );
401
 
 
402
 
  stream << indentStr << "Nonce:          "
403
 
         << QObexAuthDigestBase::toString( nonce() ) << "\n";
404
 
  if ( hasRealm() )
405
 
    stream << indentStr << "Realm:          "
406
 
           << realm() << "\n";
407
 
  if ( hasOptions() )
408
 
    stream << indentStr << "Options:        "
409
 
           << QString().sprintf("0x%02X", (unsigned char)options() ) << " "
410
 
           << ((options() & SendUserId) ? "(Send Userid) " : "" )
411
 
           << ((options() & AccessReadOnly) ? "(ReadOnly) " : "" )
412
 
           << "\n";
413
 
  else
414
 
    stream << indentStr << "Options:        Not set, defaults to 0x00\n";
415
 
 
416
 
  return str;
417
 
}
418
 
 
419
 
// Constructor to create data for a new AuthResponse header.
420
 
QObexAuthDigestResponse::QObexAuthDigestResponse( const QByteArray& nonce, const AuthInfo& ai ) {
421
 
  myDebug(( "QObexAuthDigestResponse::QObexAuthDigestResponse()" ));
422
 
 
423
 
  Q_ASSERT( !nonce.isEmpty() );
424
 
  appendTag( RequestDigestTag, computeDigest( nonce, ai.secret ) );
425
 
  appendTag( NonceTag, nonce );
426
 
 
427
 
  if ( !ai.userId.isNull() )
428
 
    appendStringValue( UserIdTag, ai.userId );
429
 
}
430
 
 
431
 
// Constructor used to parse the data given here.
432
 
QObexAuthDigestResponse::QObexAuthDigestResponse( const QByteArray& data )
433
 
  : QObexAuthDigestBase( data ) {
434
 
  myDebug(( "QObexAuthDigestResponse::QObexAuthDigestResponse()" ));
435
 
}
436
 
  
437
 
// Needed for list handling
438
 
QObexAuthDigestResponse::QObexAuthDigestResponse() {
439
 
  myDebug(( "QObexAuthDigestResponse::QObexAuthDigestResponse()" ));
440
 
}
441
 
 
442
 
// Read access to the fields of the header data.
443
 
QByteArray QObexAuthDigestResponse::requestDigest() const {
444
 
  myDebug(( "QObexAuthDigestResponse::requestDigest()" ));
445
 
  return getTag( RequestDigestTag );
446
 
}
447
 
 
448
 
QByteArray QObexAuthDigestResponse::nonce() const {
449
 
  myDebug(( "QObexAuthDigestResponse::nonce()" ));
450
 
  return getTag( NonceTag );
451
 
}
452
 
 
453
 
bool QObexAuthDigestResponse::hasNonce() const {
454
 
  myDebug(( "QObexAuthDigestResponse::hasNonce()" ));
455
 
  return hasTag( NonceTag );
456
 
}
457
 
 
458
 
QString QObexAuthDigestResponse::userId() const {
459
 
  myDebug(( "QObexAuthDigestResponse::userId()" ));
460
 
  return getStringTag( UserIdTag );
461
 
}
462
 
 
463
 
bool QObexAuthDigestResponse::hasUserId() const {
464
 
  myDebug(( "QObexAuthDigestResponse::hasUserId()" ));
465
 
  return hasTag( UserIdTag );
466
 
}
467
 
 
468
 
bool QObexAuthDigestResponse::authenticate( const QByteArray& secret, const QByteArray& nonce ) const {
469
 
  myDebug(( "QObexAuthDigestResponse::authenticate( ... )" ));
470
 
  return getTag( RequestDigestTag ) == computeDigest( nonce, secret );
471
 
}
472
 
 
473
 
QString QObexAuthDigestResponse::toString( int indent ) const {
474
 
  QString indentStr;
475
 
  indentStr.fill( QChar( ' ' ), indent );
476
 
  QString str;
477
 
  QTextStream stream( &str, IO_WriteOnly );
478
 
 
479
 
  stream << indentStr << "Request Digest: "
480
 
         << QObexAuthDigestBase::toString( requestDigest() ) << "\n";
481
 
  if ( hasNonce() )
482
 
    stream << indentStr << "Nonce:          "
483
 
           << QObexAuthDigestBase::toString( nonce() ) << "\n";
484
 
  if ( hasUserId() )
485
 
    stream << indentStr << "UserId:         " << userId() << "\n";
486
 
 
487
 
  return str;
488
 
}