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