kio
authinfo.cpp
Go to the documentation of this file.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 fclose (fstream);
00330 close (fd);
00331 return true;
00332 }