2 * This file is part of the KDE libraries
3 * Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
25 #include <sys/stat.h> // don't move it down the include order, it breaks compilation on MSVC
29 #include <sys/types.h>
31 #include <QtCore/QByteArray>
32 #include <QtCore/QDir>
33 #include <QtCore/QFile>
37 #include <kstandarddirs.h>
38 #include <ksavefile.h>
40 #define NETRC_READ_BUF_SIZE 4096
49 QString customTitle
; // reserved for future use
50 AuthInfo::FieldFlags flags
;
53 ExtraField() : flags(AuthInfo::ExtraFieldNoFlags
) {}
56 QDataStream
& operator<< (QDataStream
& s
, const ExtraField
& extraField
)
58 s
<< extraField
.customTitle
;
59 s
<< (int)extraField
.flags
;
60 s
<< extraField
.value
;
64 QDataStream
& operator>> (QDataStream
& s
, ExtraField
& extraField
)
66 s
>> extraField
.customTitle
;
69 extraField
.flags
= (AuthInfo::FieldFlags
)i
;
70 s
>> extraField
.value
;
75 class KIO::AuthInfoPrivate
81 QMap
<QString
, ExtraField
> extraFields
;
87 AuthInfo::AuthInfo() : d(new AuthInfoPrivate())
95 AuthInfo::AuthInfo( const AuthInfo
& info
) : d(new AuthInfoPrivate())
100 AuthInfo::~AuthInfo()
105 AuthInfo
& AuthInfo::operator= ( const AuthInfo
& info
)
108 username
= info
.username
;
109 password
= info
.password
;
110 prompt
= info
.prompt
;
111 caption
= info
.caption
;
112 comment
= info
.comment
;
113 commentLabel
= info
.commentLabel
;
114 realmValue
= info
.realmValue
;
115 digestInfo
= info
.digestInfo
;
116 verifyPath
= info
.verifyPath
;
117 readOnly
= info
.readOnly
;
118 keepPassword
= info
.keepPassword
;
119 modified
= info
.modified
;
120 d
->extraFields
= info
.d
->extraFields
;
124 bool AuthInfo::isModified() const
129 void AuthInfo::setModified( bool flag
)
136 void AuthInfo::setExtraField(const QString
&fieldName
, const QVariant
& value
)
138 d
->extraFields
[fieldName
].value
= value
;
141 void AuthInfo::setExtraFieldFlags(const QString
&fieldName
, const FieldFlags flags
)
143 d
->extraFields
[fieldName
].flags
= flags
;
146 QVariant
AuthInfo::getExtraField(const QString
&fieldName
) const
148 if (!d
->extraFields
.contains(fieldName
)) return QVariant();
149 return d
->extraFields
[fieldName
].value
;
152 AuthInfo::FieldFlags
AuthInfo::getExtraFieldFlags(const QString
&fieldName
) const
154 if (!d
->extraFields
.contains(fieldName
)) return AuthInfo::ExtraFieldNoFlags
;
155 return d
->extraFields
[fieldName
].flags
;
160 QDataStream
& KIO::operator<< (QDataStream
& s
, const AuthInfo
& a
)
163 << a
.url
<< a
.username
<< a
.password
<< a
.prompt
<< a
.caption
164 << a
.comment
<< a
.commentLabel
<< a
.realmValue
<< a
.digestInfo
165 << a
.verifyPath
<< a
.readOnly
<< a
.keepPassword
<< a
.modified
170 QDataStream
& KIO::operator>> (QDataStream
& s
, AuthInfo
& a
)
174 >> a
.url
>> a
.username
>> a
.password
>> a
.prompt
>> a
.caption
175 >> a
.comment
>> a
.commentLabel
>> a
.realmValue
>> a
.digestInfo
176 >> a
.verifyPath
>> a
.readOnly
>> a
.keepPassword
>> a
.modified
182 typedef QList
<NetRC::AutoLogin
> LoginList
;
183 typedef QMap
<QString
, LoginList
> LoginMap
;
185 class NetRC::NetRCPrivate
195 NetRC
* NetRC::instance
= 0L;
198 : d( new NetRCPrivate
)
212 instance
= new NetRC
;
216 bool NetRC::lookup( const KUrl
& url
, AutoLogin
& login
, bool userealnetrc
,
217 const QString
&_type
, LookUpMode mode
)
219 // kDebug() << "AutoLogin lookup for: " << url.host();
220 if ( !url
.isValid() )
223 QString type
= _type
;
224 if ( type
.isEmpty() )
225 type
= url
.protocol();
227 if ( d
->loginMap
.isEmpty() || d
->isDirty
)
231 QString filename
= KStandardDirs::locateLocal("config", QLatin1String("kionetrc"));
232 bool status
= parse (openf (filename
));
236 filename
= QDir::homePath() + QDir::separator() + QLatin1String(".netrc");
237 status
|= parse (openf(filename
));
244 if ( !d
->loginMap
.contains( type
) )
247 const LoginList
& l
= d
->loginMap
[type
];
251 for (LoginList::ConstIterator it
= l
.begin(); it
!= l
.end(); ++it
)
253 const AutoLogin
&log
= *it
;
255 if ( (mode
& defaultOnly
) == defaultOnly
&&
256 log
.machine
== QLatin1String("default") &&
257 (login
.login
.isEmpty() || login
.login
== log
.login
) )
259 login
.type
= log
.type
;
260 login
.machine
= log
.machine
;
261 login
.login
= log
.login
;
262 login
.password
= log
.password
;
263 login
.macdef
= log
.macdef
;
266 if ( (mode
& presetOnly
) == presetOnly
&&
267 log
.machine
== QLatin1String("preset") &&
268 (login
.login
.isEmpty() || login
.login
== log
.login
) )
270 login
.type
= log
.type
;
271 login
.machine
= log
.machine
;
272 login
.login
= log
.login
;
273 login
.password
= log
.password
;
274 login
.macdef
= log
.macdef
;
277 if ( (mode
& exactOnly
) == exactOnly
&&
278 log
.machine
== url
.host() &&
279 (login
.login
.isEmpty() || login
.login
== log
.login
) )
281 login
.type
= log
.type
;
282 login
.machine
= log
.machine
;
283 login
.login
= log
.login
;
284 login
.password
= log
.password
;
285 login
.macdef
= log
.macdef
;
298 int NetRC::openf( const QString
& f
)
300 KDE_struct_stat sbuff
;
301 if ( KDE::stat(f
, &sbuff
) != 0 )
305 if ( sbuff
.st_mode
!= (S_IFREG
|S_IRUSR
|S_IWUSR
) ||
306 sbuff
.st_uid
!= geteuid() )
309 return KDE::open( f
, O_RDONLY
);
312 QString
NetRC::extract( const char* buf
, const char* key
, int& pos
)
315 int m_len
= strlen(key
);
316 int b_len
= strlen(buf
);
320 while( buf
[idx
] == ' ' || buf
[idx
] == '\t' )
323 if ( strncasecmp( buf
+idx
, key
, m_len
) != 0 )
328 while( buf
[idx
] == ' ' || buf
[idx
] == '\t' )
332 while( buf
[idx
] != ' ' && buf
[idx
] != '\t' &&
333 buf
[idx
] != '\n' && buf
[idx
] != '\r' )
339 return QString::fromLatin1( buf
+start
, idx
-start
);
347 bool NetRC::parse( int fd
)
356 bool isMacro
= false;
357 char* buf
= new char[NETRC_READ_BUF_SIZE
];
358 FILE* fstream
= KDE_fdopen( fd
,"rb" );
360 while ( fgets (buf
, NETRC_READ_BUF_SIZE
, fstream
) != 0L )
364 while ( buf
[pos
] == ' ' || buf
[pos
] == '\t' )
367 if ( buf
[pos
] == '#' || buf
[pos
] == '\n' ||
368 buf
[pos
] == '\r' || buf
[pos
] == '\0' )
370 if ( buf
[pos
] != '#' && isMacro
)
378 int tail
= strlen(buf
);
379 while( buf
[tail
-1] == '\n' || buf
[tail
-1] =='\r' )
382 QString mac
= QString::fromLatin1(buf
, tail
).trimmed();
383 if ( !mac
.isEmpty() )
384 d
->loginMap
[type
][index
].macdef
[macro
].append( mac
);
390 l
.machine
= extract( buf
, "machine", pos
);
391 if ( l
.machine
.isEmpty() )
393 if (strncasecmp(buf
+pos
, "default", 7) == 0 )
396 l
.machine
= QLatin1String("default");
398 else if (strncasecmp(buf
+pos
, "preset", 6) == 0 )
401 l
.machine
= QLatin1String("preset");
404 // kDebug() << "Machine: " << l.machine;
406 l
.login
= extract( buf
, "login", pos
);
407 // kDebug() << "Login: " << l.login;
409 l
.password
= extract( buf
, "password", pos
);
410 if ( l
.password
.isEmpty() )
411 l
.password
= extract( buf
, "account", pos
);
412 // kDebug() << "Password: " << l.password;
414 type
= l
.type
= extract( buf
, "type", pos
);
415 if ( l
.type
.isEmpty() && !l
.machine
.isEmpty() )
416 type
= l
.type
= QLatin1String("ftp");
417 // kDebug() << "Type: " << l.type;
419 macro
= extract( buf
, "macdef", pos
);
420 isMacro
= !macro
.isEmpty();
421 // kDebug() << "Macro: " << macro;
423 d
->loginMap
[l
.type
].append(l
);
424 index
= d
->loginMap
[l
.type
].count()-1;