00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <config.h>
00022
00023
#include <stdio.h>
00024
#include <fcntl.h>
00025
#include <unistd.h>
00026
#include <sys/stat.h>
00027
#include <sys/types.h>
00028
00029
#include <qdir.h>
00030
#include <qfile.h>
00031
00032
#include <kdebug.h>
00033
#include <kstandarddirs.h>
00034
#include <ksavefile.h>
00035
#include <kstaticdeleter.h>
00036
00037
#include "kio/authinfo.h"
00038
00039
#define NETRC_READ_BUF_SIZE 4096
00040
00041
using namespace KIO;
00042
00043 AuthInfo::AuthInfo()
00044 {
00045 modified =
false;
00046
readOnly =
false;
00047
verifyPath =
false;
00048
keepPassword =
false;
00049 }
00050
00051 AuthInfo::AuthInfo(
const AuthInfo& info )
00052 {
00053 (*this) = info;
00054 }
00055
00056 AuthInfo& AuthInfo::operator= (
const AuthInfo& info )
00057 {
00058
url = info.
url;
00059
username = info.
username;
00060
password = info.
password;
00061
prompt = info.
prompt;
00062
caption = info.
caption;
00063
comment = info.
comment;
00064
commentLabel = info.
commentLabel;
00065
realmValue = info.
realmValue;
00066
digestInfo = info.
digestInfo;
00067
verifyPath = info.
verifyPath;
00068
readOnly = info.
readOnly;
00069
keepPassword = info.
keepPassword;
00070 modified = info.
modified;
00071
return *
this;
00072 }
00073
00074
QDataStream& KIO::operator<< (
QDataStream& s,
const AuthInfo& a)
00075 {
00076 s << a.
url << a.
username << a.
password << a.
prompt << a.
caption
00077 << a.
comment << a.
commentLabel << a.
realmValue << a.
digestInfo
00078 << Q_UINT8(a.
verifyPath ? 1:0) << Q_UINT8(a.
readOnly ? 1:0)
00079 << Q_UINT8(a.
keepPassword ? 1:0) << Q_UINT8(a.
modified ? 1:0);
00080
return s;
00081 }
00082
00083
QDataStream& KIO::operator>> (
QDataStream& s,
AuthInfo& a)
00084 {
00085 Q_UINT8 verify = 0;
00086 Q_UINT8 ro = 0;
00087 Q_UINT8 keep = 0;
00088 Q_UINT8 mod = 0;
00089
00090 s >> a.
url >> a.
username >> a.
password >> a.
prompt >> a.
caption
00091 >> a.
comment >> a.
commentLabel >> a.
realmValue >> a.
digestInfo
00092 >> verify >> ro >> keep >> mod;
00093 a.
verifyPath = (verify != 0);
00094 a.
readOnly = (ro != 0);
00095 a.
keepPassword = (keep != 0);
00096 a.
modified = (mod != 0);
00097
return s;
00098 }
00099
00100
00101
NetRC* NetRC::instance = 0L;
00102
00103 NetRC::NetRC()
00104 {
00105 isDirty =
false;
00106 }
00107
00108 NetRC::~NetRC()
00109 {
00110
delete instance;
00111 instance = 0L;
00112 }
00113
00114 NetRC*
NetRC::self()
00115 {
00116
if ( !instance )
00117 instance =
new NetRC();
00118
return instance;
00119 }
00120
00121 bool NetRC::lookup(
const KURL& url,
AutoLogin& login,
bool userealnetrc,
00122
QString type,
int mode )
00123 {
00124
00125
if ( !url.
isValid() )
00126
return false;
00127
00128
if ( type.
isEmpty() )
00129 type = url.
protocol();
00130
00131
if ( loginMap.
isEmpty() || isDirty )
00132 {
00133 loginMap.
clear();
00134
00135
QString filename =
locateLocal(
"config",
"kionetrc");
00136
bool status = parse (openf (filename));
00137
00138
if ( userealnetrc )
00139 {
00140 filename =
QDir::homeDirPath()+
QDir::separator() +
".netrc";
00141 status |= parse (openf(filename));
00142 }
00143
00144
if ( !status )
00145
return false;
00146 }
00147
00148
if ( !loginMap.
contains( type ) )
00149
return false;
00150
00151
LoginList l = loginMap[type];
00152
if ( l.
isEmpty() )
00153
return false;
00154
00155
for (LoginList::Iterator it = l.
begin(); it != l.
end(); ++it)
00156 {
00157
AutoLogin &log = *it;
00158
00159
if ( (mode & defaultOnly) == defaultOnly &&
00160 log.
machine == QString::fromLatin1(
"default") &&
00161 (login.
login.
isEmpty() || login.
login == log.
login) )
00162 {
00163 login.
type = log.
type;
00164 login.
machine = log.
machine;
00165 login.
login = log.
login;
00166 login.
password = log.
password;
00167 login.
macdef = log.
macdef;
00168 }
00169
00170
if ( (mode & presetOnly) == presetOnly &&
00171 log.
machine == QString::fromLatin1(
"preset") &&
00172 (login.
login.
isEmpty() || login.
login == log.
login) )
00173 {
00174 login.
type = log.
type;
00175 login.
machine = log.
machine;
00176 login.
login = log.
login;
00177 login.
password = log.
password;
00178 login.
macdef = log.
macdef;
00179 }
00180
00181
if ( (mode & exactOnly) == exactOnly &&
00182 log.
machine == url.
host() &&
00183 (login.
login.
isEmpty() || login.
login == log.
login) )
00184 {
00185 login.
type = log.
type;
00186 login.
machine = log.
machine;
00187 login.
login = log.
login;
00188 login.
password = log.
password;
00189 login.
macdef = log.
macdef;
00190
break;
00191 }
00192 }
00193
00194
return true;
00195 }
00196
00197
int NetRC::openf(
const QString& f )
00198 {
00199
struct stat sbuff;
00200
QCString ef = QFile::encodeName(f);
00201
if (
stat(ef, &sbuff) != 0 )
00202
return -1;
00203
00204
00205
if ( sbuff.st_mode != (S_IFREG|S_IRUSR|S_IWUSR) ||
00206 sbuff.st_uid != geteuid() )
00207
return -1;
00208
00209
return open( ef, O_RDONLY );
00210 }
00211
00212
QString NetRC::extract(
const char* buf,
const char* key,
int& pos )
00213 {
00214
int idx = pos;
00215
int m_len = strlen(key);
00216
int b_len = strlen(buf);
00217
00218
while( idx < b_len )
00219 {
00220
while( buf[idx] ==
' ' || buf[idx] ==
'\t' )
00221 idx++;
00222
00223
if ( strncasecmp( buf+idx, key, m_len ) != 0 )
00224 idx++;
00225
else
00226 {
00227 idx += m_len;
00228
while( buf[idx] ==
' ' || buf[idx] ==
'\t' )
00229 idx++;
00230
00231
int start = idx;
00232
while( buf[idx] !=
' ' && buf[idx] !=
'\t' &&
00233 buf[idx] !=
'\n' && buf[idx] !=
'\r' )
00234 idx++;
00235
00236
if ( idx > start )
00237 {
00238 pos = idx;
00239
return QString::fromLatin1( buf+start, idx-start);
00240 }
00241 }
00242 }
00243
00244
return QString::null;
00245 }
00246
00247
bool NetRC::parse(
int fd )
00248 {
00249
if (fd == -1)
00250
return false;
00251
00252
QString type;
00253
QString macro;
00254
00255 uint index = 0;
00256
bool isMacro =
false;
00257
char* buf =
new char[NETRC_READ_BUF_SIZE];
00258 FILE* fstream = fdopen( fd,
"rb" );
00259
00260
while ( fgets (buf, NETRC_READ_BUF_SIZE, fstream) != 0L )
00261 {
00262
int pos = 0;
00263
00264
while ( buf[pos] ==
' ' || buf[pos] ==
'\t' )
00265 pos++;
00266
00267
if ( buf[pos] ==
'#' || buf[pos] ==
'\n' ||
00268 buf[pos] ==
'\r' || buf[pos] ==
'\0' )
00269 {
00270
if ( buf[pos] !=
'#' && isMacro )
00271 isMacro =
false;
00272
00273
continue;
00274 }
00275
00276
if ( isMacro )
00277 {
00278
int tail = strlen(buf);
00279
while( buf[tail-1] ==
'\n' || buf[tail-1] ==
'\r' )
00280 tail--;
00281
00282
QString mac =
QString::fromLatin1(buf, tail).stripWhiteSpace();
00283
if ( !mac.
isEmpty() )
00284 loginMap[type][index].macdef[macro].append( mac );
00285
00286
continue;
00287 }
00288
00289 AutoLogin l;
00290 l.machine = extract( buf,
"machine", pos );
00291
if ( l.machine.isEmpty() )
00292 {
00293
if (strncasecmp(buf+pos,
"default", 7) == 0 )
00294 {
00295 pos += 7;
00296 l.machine =
QString::fromLatin1(
"default");
00297 }
00298
else if (strncasecmp(buf+pos,
"preset", 6) == 0 )
00299 {
00300 pos += 6;
00301 l.machine =
QString::fromLatin1(
"preset");
00302 }
00303 }
00304
00305
00306 l.login = extract( buf,
"login", pos );
00307
00308
00309 l.password = extract( buf,
"password", pos );
00310
if ( l.password.isEmpty() )
00311 l.password = extract( buf,
"account", pos );
00312
00313
00314 type = l.type = extract( buf,
"type", pos );
00315
if ( l.type.isEmpty() && !l.machine.isEmpty() )
00316 type = l.type =
QString::fromLatin1(
"ftp");
00317
00318
00319 macro = extract( buf,
"macdef", pos );
00320 isMacro = !macro.
isEmpty();
00321
00322
00323 loginMap[l.type].append(l);
00324 index = loginMap[l.type].
count()-1;
00325 }
00326
00327
delete [] buf;
00328
close (fd);
00329
return true;
00330 }