kio Library API Documentation

authinfo.cpp

00001 /*
00002  *  This file is part of the KDE libraries
00003  *  Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org>
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Library General Public
00007  *  License as published by the Free Software Foundation; either
00008  *  version 2 of the License, or (at your option) any later version.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Library General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Library General Public License
00016  *  along with this library; see the file COPYING.LIB.  If not, write to
00017  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018  *  Boston, MA 02111-1307, USA.
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     // kdDebug() << "AutoLogin lookup for: " << url.host() << endl;
00125     if ( !url.isValid() )
00126         return false;
00127 
00128     if ( type.isEmpty() )
00129         type = url.protocol();
00130 
00131     if ( loginMap.isEmpty() || isDirty )
00132     {
00133         int fd;
00134         loginMap.clear();
00135         QString filename = locateLocal("config", "kionetrc");
00136         bool status=((fd=openf(filename)) != -1);
00137         if ( status )
00138             parse( fd );
00139 
00140         if ( userealnetrc )
00141         {
00142             filename =  QDir::homeDirPath()+ QDir::separator() + ".netrc";
00143             bool hasnetrc = ((fd=openf(filename)) != -1);
00144             if ( hasnetrc )
00145                 parse( fd );
00146             status |= hasnetrc;
00147         }
00148         close( fd );
00149         if ( !status )
00150           return false;
00151     }
00152 
00153     if ( !loginMap.contains( type ) )
00154         return false;
00155 
00156     LoginList l = loginMap[type];
00157     if ( l.isEmpty() )
00158         return false;
00159 
00160     LoginList::Iterator it = l.begin();
00161     for ( ; it != l.end(); ++it )
00162     {
00163         AutoLogin &log = *it;
00164 
00165         if ( (mode & defaultOnly) == defaultOnly &&
00166              log.machine == QString::fromLatin1("default") &&
00167              (login.login.isEmpty() || login.login == log.login) )
00168         {
00169             login.type = log.type;
00170             login.machine = log.machine;
00171             login.login = log.login;
00172             login.password = log.password;
00173             login.macdef = log.macdef;
00174         }
00175 
00176         if ( (mode & presetOnly) == presetOnly &&
00177              log.machine == QString::fromLatin1("preset") &&
00178              (login.login.isEmpty() || login.login == log.login) )
00179         {
00180             login.type = log.type;
00181             login.machine = log.machine;
00182             login.login = log.login;
00183             login.password = log.password;
00184             login.macdef = log.macdef;
00185         }
00186 
00187         if ( (mode & exactOnly) == exactOnly &&
00188              log.machine == url.host() &&
00189              (login.login.isEmpty() || login.login == log.login) )
00190         {
00191             login.type = log.type;
00192             login.machine = log.machine;
00193             login.login = log.login;
00194             login.password = log.password;
00195             login.macdef = log.macdef;
00196             break;
00197         }
00198     }
00199     return true;
00200 }
00201 /*
00202 bool NetRC::flush() const
00203 {
00204     if ( loginMap.isEmpty() )
00205         return false;
00206 
00207     KSaveFile saveFile ( locateLocal("config", "kionetrc"), 0600 );
00208     if (saveFile.status() != 0)
00209         return false;
00210 
00211     FILE* f = saveFile.fstream();
00212     fprintf(f, "#\n# kionetrc - non-protocol specific password storage"
00213                "\n# file.  The format used is exactly the same as the"
00214                "\n# \".netrc\" file with some minor distinctions.  kionetrc"
00215                "\n# does not support the \"macdef\" keyword and also adds"
00216                "\n# one extra keyword, type, which is used to determine the"
00217                "\n# protocol or type for whom the login information is stored!"
00218                "\n#\n");
00219     LoginMap::ConstIterator it = loginMap.begin();
00220     for ( ; it != loginMap.end() ; ++it )
00221     {
00222         LoginList lst = it.data();
00223         LoginList::ConstIterator itr = lst.begin();  
00224         for ( ; itr != lst.end(); ++itr )
00225         {
00226             AutoLogin al = itr.data();
00227             fprintf( f, "%-5s %-10s %-5s %10s %-5s %-10s %-5s %-10s",
00228                      "machine", al.machine.local8Bit().data(), "login",
00229                      al.login.local8Bit().data(), "password",
00230                      al.password.local8Bit().data(), "type",
00231                      it.key().local8Bit().data() );
00232         }
00233     }
00234     return saveFile.close();
00235 }
00236 */
00237 int NetRC::openf( const QString& f )
00238 {
00239     struct stat sbuff;
00240     QCString ef = QFile::encodeName(f);
00241     if ( stat(ef, &sbuff) != 0 )
00242         return -1;
00243 
00244     // Security check!!
00245     if ( sbuff.st_mode != (S_IFREG|S_IRUSR|S_IWUSR) ||
00246          sbuff.st_uid != geteuid() )
00247         return -1;
00248 
00249     return open( ef, O_RDONLY );
00250 }
00251 
00252 QString NetRC::extract( const char* buf, const char* key, int& pos )
00253 {
00254     int idx = pos;
00255     int m_len = strlen(key);
00256     int b_len = strlen(buf);
00257 
00258     while( idx < b_len )
00259     {
00260         while( buf[idx] == ' ' || buf[idx] == '\t' ) idx++;
00261         if ( strncasecmp( buf+idx, key, m_len ) == 0 )
00262         {
00263             idx += m_len;
00264             while( buf[idx] == ' ' || buf[idx] == '\t' ) idx++;
00265             int start = idx;
00266             while( buf[idx] != ' ' && buf[idx] != '\t' &&
00267                    buf[idx] != '\n' && buf[idx] != '\r' ) idx++;
00268             if ( idx > start )
00269             {
00270                 pos = idx;
00271                 return QString::fromLatin1( buf+start, idx-start);
00272             }
00273         }
00274         else
00275             idx++;
00276     }
00277     return QString::null;
00278 }
00279 
00280 void NetRC::parse( int fd )
00281 {
00282     // kdDebug() << "Parsing config files..." << endl;
00283     uint index = 0;
00284     QString macro, type;
00285     bool isMacro = false;
00286     char* buf = new char[NETRC_READ_BUF_SIZE];
00287     FILE* fstream = fdopen( fd,"rb" );
00288 
00289     while ( fgets( buf, NETRC_READ_BUF_SIZE, fstream ) != 0L )
00290     {
00291         int pos = 0;
00292         while ( buf[pos] == ' ' || buf[pos] == '\t' ) pos++;
00293         if ( buf[pos] == '#' || buf[pos] == '\n' ||
00294              buf[pos] == '\r' || buf[pos] == '\0' )
00295         {
00296             if ( buf[pos] != '#' && isMacro )
00297                 isMacro = false;
00298             continue;
00299         }
00300 
00301         if ( isMacro )
00302         {
00303             int tail = strlen(buf);
00304             while( buf[tail-1] == '\n' || buf[tail-1] =='\r' ) tail--;
00305             QString mac = QString::fromLatin1(buf, tail).stripWhiteSpace();
00306 
00307             if ( !mac.isEmpty() )
00308             {
00309                 loginMap[type][index].macdef[macro].append( mac );
00310                 // kdDebug() << mac << endl;
00311             }
00312             continue;
00313         }
00314 
00315         AutoLogin l;
00316         l.machine = extract( buf, "machine", pos );
00317         if ( l.machine.isEmpty() )
00318         {
00319             if (strncasecmp(buf+pos, "default", 7) == 0 )
00320             {
00321                 pos += 7;
00322                 l.machine = QString::fromLatin1("default");
00323             }
00324             else if (strncasecmp(buf+pos, "preset", 6) == 0 )
00325             {
00326                 pos += 6;
00327                 l.machine = QString::fromLatin1("preset");
00328             }
00329         }
00330         // kdDebug() << "Machine: " << l.machine << endl;
00331 
00332         l.login = extract( buf, "login", pos );
00333         // kdDebug() << "Login: " << l.login << endl;
00334 
00335         l.password = extract( buf, "password", pos );
00336         if ( l.password.isEmpty() )
00337             l.password = extract( buf, "account", pos );
00338         // kdDebug() << "Password: " << l.password << endl;
00339 
00340         type = l.type = extract( buf, "type", pos );
00341         if ( l.type.isEmpty() && !l.machine.isEmpty() )
00342             type = l.type = QString::fromLatin1("ftp");
00343         // kdDebug() << "Type: " << l.type << endl;
00344 
00345         macro = extract( buf, "macdef", pos );
00346         isMacro = !macro.isEmpty();
00347         // kdDebug() << "Macro: " << macro << endl;
00348 
00349         loginMap[l.type].append(l);
00350         index = loginMap[l.type].count()-1;
00351     }
00352     delete [] buf;
00353 }
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Jan 28 13:12:42 2004 by doxygen 1.3.4 written by Dimitri van Heesch, © 1997-2001