From 5159cd2beb2e87806a5b54e9991b7895285c9d3e Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 27 Jan 2013 01:04:16 -0600 Subject: Rename a number of libraries and executables to avoid conflicts with KDE4 --- tdeio/misc/CMakeLists.txt | 100 ++ tdeio/misc/Makefile.am | 60 + tdeio/misc/fileshareset | 430 ++++++ tdeio/misc/kpac/CMakeLists.txt | 66 + tdeio/misc/kpac/Makefile.am | 30 + tdeio/misc/kpac/README | 9 + tdeio/misc/kpac/README.wpad | 73 + tdeio/misc/kpac/TODO | 1 + tdeio/misc/kpac/configure.in.in | 26 + tdeio/misc/kpac/dhcp.h | 78 ++ tdeio/misc/kpac/discovery.cpp | 147 ++ tdeio/misc/kpac/discovery.h | 55 + tdeio/misc/kpac/downloader.cpp | 89 ++ tdeio/misc/kpac/downloader.h | 64 + tdeio/misc/kpac/eventsrc | 530 ++++++++ tdeio/misc/kpac/kpac_dhcp_helper.c | 229 ++++ tdeio/misc/kpac/kpactest.pac | 169 +++ tdeio/misc/kpac/proxyscout.cpp | 196 +++ tdeio/misc/kpac/proxyscout.desktop | 131 ++ tdeio/misc/kpac/proxyscout.h | 82 ++ tdeio/misc/kpac/script.cpp | 465 +++++++ tdeio/misc/kpac/script.h | 56 + tdeio/misc/kssld/CMakeLists.txt | 47 + tdeio/misc/kssld/Makefile.am | 33 + tdeio/misc/kssld/kssld.cpp | 1027 ++++++++++++++ tdeio/misc/kssld/kssld.desktop | 156 +++ tdeio/misc/kssld/kssld.h | 154 +++ tdeio/misc/mms.protocol | 73 + tdeio/misc/mmst.protocol | 15 + tdeio/misc/mmsu.protocol | 15 + tdeio/misc/pnm.protocol | 15 + tdeio/misc/rlogin.protocol | 13 + tdeio/misc/rtsp.protocol | 15 + tdeio/misc/rtspt.protocol | 15 + tdeio/misc/rtspu.protocol | 15 + tdeio/misc/ssh.protocol | 13 + tdeio/misc/tdefile/CMakeLists.txt | 39 + tdeio/misc/tdefile/Makefile.am | 10 + tdeio/misc/tdefile/README | 4 + tdeio/misc/tdefile/fileprops.cpp | 480 +++++++ tdeio/misc/tdefile/fileprops.h | 74 + tdeio/misc/tdeio_uiserver.desktop | 100 ++ tdeio/misc/tdemailservice.cpp | 45 + tdeio/misc/tdemailservice.protocol | 15 + tdeio/misc/tdentlm/CMakeLists.txt | 43 + tdeio/misc/tdentlm/Makefile.am | 12 + tdeio/misc/tdentlm/des.cpp | 513 +++++++ tdeio/misc/tdentlm/des.h | 19 + tdeio/misc/tdentlm/kswap.h | 428 ++++++ tdeio/misc/tdentlm/tdentlm.cpp | 389 ++++++ tdeio/misc/tdentlm/tdentlm.h | 233 ++++ tdeio/misc/tdesasl/CMakeLists.txt | 42 + tdeio/misc/tdesasl/Makefile.am | 12 + tdeio/misc/tdesasl/tdesasl.cpp | 285 ++++ tdeio/misc/tdesasl/tdesasl.h | 169 +++ tdeio/misc/tdesendbugmail/CMakeLists.txt | 37 + tdeio/misc/tdesendbugmail/Makefile.am | 26 + tdeio/misc/tdesendbugmail/main.cpp | 142 ++ tdeio/misc/tdesendbugmail/main.h | 20 + tdeio/misc/tdesendbugmail/smtp.cpp | 336 +++++ tdeio/misc/tdesendbugmail/smtp.h | 144 ++ tdeio/misc/tdetelnetservice.cpp | 112 ++ tdeio/misc/tdewalletd/CMakeLists.txt | 49 + tdeio/misc/tdewalletd/Makefile.am | 35 + tdeio/misc/tdewalletd/kbetterthankdialogbase.ui | 154 +++ tdeio/misc/tdewalletd/kbetterthankdialogbase.ui.h | 50 + tdeio/misc/tdewalletd/ktimeout.cpp | 84 ++ tdeio/misc/tdewalletd/ktimeout.h | 52 + tdeio/misc/tdewalletd/tdewalletd.cpp | 1514 +++++++++++++++++++++ tdeio/misc/tdewalletd/tdewalletd.desktop | 151 ++ tdeio/misc/tdewalletd/tdewalletd.h | 199 +++ tdeio/misc/tdewalletd/tdewalletwizard.ui | 545 ++++++++ tdeio/misc/tdewalletd/tdewalletwizard.ui.h | 74 + tdeio/misc/telnet.protocol | 13 + tdeio/misc/uiserver.cpp | 1413 +++++++++++++++++++ tdeio/misc/uiserver.h | 430 ++++++ 76 files changed, 13184 insertions(+) create mode 100644 tdeio/misc/CMakeLists.txt create mode 100644 tdeio/misc/Makefile.am create mode 100755 tdeio/misc/fileshareset create mode 100644 tdeio/misc/kpac/CMakeLists.txt create mode 100644 tdeio/misc/kpac/Makefile.am create mode 100644 tdeio/misc/kpac/README create mode 100644 tdeio/misc/kpac/README.wpad create mode 100644 tdeio/misc/kpac/TODO create mode 100644 tdeio/misc/kpac/configure.in.in create mode 100644 tdeio/misc/kpac/dhcp.h create mode 100644 tdeio/misc/kpac/discovery.cpp create mode 100644 tdeio/misc/kpac/discovery.h create mode 100644 tdeio/misc/kpac/downloader.cpp create mode 100644 tdeio/misc/kpac/downloader.h create mode 100644 tdeio/misc/kpac/eventsrc create mode 100644 tdeio/misc/kpac/kpac_dhcp_helper.c create mode 100644 tdeio/misc/kpac/kpactest.pac create mode 100644 tdeio/misc/kpac/proxyscout.cpp create mode 100644 tdeio/misc/kpac/proxyscout.desktop create mode 100644 tdeio/misc/kpac/proxyscout.h create mode 100644 tdeio/misc/kpac/script.cpp create mode 100644 tdeio/misc/kpac/script.h create mode 100644 tdeio/misc/kssld/CMakeLists.txt create mode 100644 tdeio/misc/kssld/Makefile.am create mode 100644 tdeio/misc/kssld/kssld.cpp create mode 100644 tdeio/misc/kssld/kssld.desktop create mode 100644 tdeio/misc/kssld/kssld.h create mode 100644 tdeio/misc/mms.protocol create mode 100644 tdeio/misc/mmst.protocol create mode 100644 tdeio/misc/mmsu.protocol create mode 100644 tdeio/misc/pnm.protocol create mode 100644 tdeio/misc/rlogin.protocol create mode 100644 tdeio/misc/rtsp.protocol create mode 100644 tdeio/misc/rtspt.protocol create mode 100644 tdeio/misc/rtspu.protocol create mode 100644 tdeio/misc/ssh.protocol create mode 100644 tdeio/misc/tdefile/CMakeLists.txt create mode 100644 tdeio/misc/tdefile/Makefile.am create mode 100644 tdeio/misc/tdefile/README create mode 100644 tdeio/misc/tdefile/fileprops.cpp create mode 100644 tdeio/misc/tdefile/fileprops.h create mode 100644 tdeio/misc/tdeio_uiserver.desktop create mode 100644 tdeio/misc/tdemailservice.cpp create mode 100644 tdeio/misc/tdemailservice.protocol create mode 100644 tdeio/misc/tdentlm/CMakeLists.txt create mode 100644 tdeio/misc/tdentlm/Makefile.am create mode 100644 tdeio/misc/tdentlm/des.cpp create mode 100644 tdeio/misc/tdentlm/des.h create mode 100644 tdeio/misc/tdentlm/kswap.h create mode 100644 tdeio/misc/tdentlm/tdentlm.cpp create mode 100644 tdeio/misc/tdentlm/tdentlm.h create mode 100644 tdeio/misc/tdesasl/CMakeLists.txt create mode 100644 tdeio/misc/tdesasl/Makefile.am create mode 100644 tdeio/misc/tdesasl/tdesasl.cpp create mode 100644 tdeio/misc/tdesasl/tdesasl.h create mode 100644 tdeio/misc/tdesendbugmail/CMakeLists.txt create mode 100644 tdeio/misc/tdesendbugmail/Makefile.am create mode 100644 tdeio/misc/tdesendbugmail/main.cpp create mode 100644 tdeio/misc/tdesendbugmail/main.h create mode 100644 tdeio/misc/tdesendbugmail/smtp.cpp create mode 100644 tdeio/misc/tdesendbugmail/smtp.h create mode 100644 tdeio/misc/tdetelnetservice.cpp create mode 100644 tdeio/misc/tdewalletd/CMakeLists.txt create mode 100644 tdeio/misc/tdewalletd/Makefile.am create mode 100644 tdeio/misc/tdewalletd/kbetterthankdialogbase.ui create mode 100644 tdeio/misc/tdewalletd/kbetterthankdialogbase.ui.h create mode 100644 tdeio/misc/tdewalletd/ktimeout.cpp create mode 100644 tdeio/misc/tdewalletd/ktimeout.h create mode 100644 tdeio/misc/tdewalletd/tdewalletd.cpp create mode 100644 tdeio/misc/tdewalletd/tdewalletd.desktop create mode 100644 tdeio/misc/tdewalletd/tdewalletd.h create mode 100644 tdeio/misc/tdewalletd/tdewalletwizard.ui create mode 100644 tdeio/misc/tdewalletd/tdewalletwizard.ui.h create mode 100644 tdeio/misc/telnet.protocol create mode 100644 tdeio/misc/uiserver.cpp create mode 100644 tdeio/misc/uiserver.h (limited to 'tdeio/misc') diff --git a/tdeio/misc/CMakeLists.txt b/tdeio/misc/CMakeLists.txt new file mode 100644 index 000000000..3bfdb0980 --- /dev/null +++ b/tdeio/misc/CMakeLists.txt @@ -0,0 +1,100 @@ +################################################# +# +# (C) 2010 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +add_subdirectory( tdesendbugmail ) +add_subdirectory( kpac ) +add_subdirectory( tdesasl ) +add_subdirectory( kssld ) +add_subdirectory( tdefile ) +add_subdirectory( tdewalletd ) +add_subdirectory( tdentlm ) + +add_definitions( + -D_LARGEFILE64_SOURCE +) + +include_directories( + ${TQT_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdecore + ${CMAKE_BINARY_DIR}/tdeio + ${CMAKE_BINARY_DIR}/tdeio/tdeio + ${CMAKE_BINARY_DIR}/tdeio/kssl + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/dcop + ${CMAKE_SOURCE_DIR}/tdefx + ${CMAKE_SOURCE_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdeui + ${CMAKE_SOURCE_DIR}/tdeio + ${CMAKE_SOURCE_DIR}/tdeio/tdeio + ${CMAKE_SOURCE_DIR}/tdeio/kssl +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### headers ################################### + +install( FILES uiserver.h DESTINATION ${INCLUDE_INSTALL_DIR}/tdeio ) + + +##### other data ################################ + +install(FILES + tdeio_uiserver.desktop tdemailservice.protocol + telnet.protocol rlogin.protocol rtsp.protocol + ssh.protocol mms.protocol mmst.protocol mmsu.protocol + pnm.protocol rtspt.protocol rtspu.protocol + DESTINATION ${SERVICES_INSTALL_DIR} ) + +install( FILES fileshareset DESTINATION ${BIN_INSTALL_DIR} + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE SETUID ) + + +#### tdeio_uiserver ############################### + +set( target tdeio_uiserver ) + +set( ${target}_SRCS + uiserver.cpp uiserver.skel +) + +tde_add_tdeinit_executable( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK tdeio-shared + DEPENDENCIES dcopidl +) + + +##### tdemailservice ############################## + +set( target tdemailservice ) + +tde_add_executable( ${target} + SOURCES ${target}.cpp + LINK tdecore-shared + DESTINATION ${BIN_INSTALL_DIR} +) + + +##### tdetelnetservice ############################ + +set( target tdetelnetservice ) + +tde_add_executable( ${target} + SOURCES ${target}.cpp + LINK tdeui-shared + DESTINATION ${BIN_INSTALL_DIR} +) + +tde_install_symlink( ${target} ${BIN_INSTALL_DIR}/filesharelist ) diff --git a/tdeio/misc/Makefile.am b/tdeio/misc/Makefile.am new file mode 100644 index 000000000..6a250cf8a --- /dev/null +++ b/tdeio/misc/Makefile.am @@ -0,0 +1,60 @@ +# This file is part of the KDE libraries +# Copyright (C) 1997 Torben Weis (weis@kde.org) + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. + +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public License +# along with this library; see the file COPYING.LIB. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +AM_CPPFLAGS = -D_LARGEFILE64_SOURCE + +INCLUDES= -I$(srcdir)/.. -I$(top_srcdir) -I$(srcdir)/../kssl -I../kssl $(all_includes) $(SSL_INCLUDES) + +SUBDIRS = . tdesendbugmail kpac tdesasl kssld tdefile tdewalletd tdentlm + +lib_LTLIBRARIES = +tdeinit_LTLIBRARIES = tdeio_uiserver.la +bin_PROGRAMS = tdemailservice tdetelnetservice + +observer_DIR = $(top_srcdir)/tdeio/tdeio + +tdeio_uiserver_la_SOURCES = uiserver.cpp uiserver.skel observer.stub +tdeio_uiserver_la_LIBADD = $(LIB_KIO) $(LIB_TDEUI) $(LIB_QT) $(top_builddir)/dcop/libDCOP.la $(LIB_TDECORE) +tdeio_uiserver_la_LDFLAGS = $(all_libraries) -module -avoid-version + +METASOURCES = AUTO + +kde_services_DATA = tdeio_uiserver.desktop + +tdemailservice_SOURCES = tdemailservice.cpp +tdemailservice_LDADD = $(LIB_TDECORE) +tdemailservice_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor + +tdetelnetservice_SOURCES = tdetelnetservice.cpp +tdetelnetservice_LDADD = $(LIB_TDEUI) +tdetelnetservice_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor + +protocol_DATA = tdemailservice.protocol telnet.protocol rlogin.protocol rtsp.protocol ssh.protocol \ + mms.protocol mmst.protocol mmsu.protocol pnm.protocol rtspt.protocol rtspu.protocol +protocoldir = $(kde_servicesdir) + +kiomiscdir = $(includedir)/tdeio +kiomisc_HEADERS = uiserver.h + + +bin_SCRIPTS = fileshareset +install-exec-local: + @-rm -f $(DESTDIR)$(bindir)/filesharelist + @$(LN_S) fileshareset $(DESTDIR)$(bindir)/filesharelist + @(chown root $(DESTDIR)$(bindir)/fileshareset && chmod 4755 $(DESTDIR)$(bindir)/fileshareset) || echo "Was not able to make fileshareset setuid root" + diff --git a/tdeio/misc/fileshareset b/tdeio/misc/fileshareset new file mode 100755 index 000000000..4c921ba38 --- /dev/null +++ b/tdeio/misc/fileshareset @@ -0,0 +1,430 @@ +#!/usr/bin/perl -T +use strict; + +######################################## +# config files +$nfs_exports::default_options = '*(ro,all_squash)'; +$nfs_exports::conf_file = '/etc/exports'; +$smb_exports::conf_file = '/etc/samba/smb.conf'; +my $authorisation_file = '/etc/security/fileshare.conf'; +my $authorisation_group = 'fileshare'; + + +######################################## +# Copyright (C) 2001-2002 MandrakeSoft (pixel@mandrakesoft.com) +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +######################################## +my $uid = $<; +my $username = getpwuid($uid); + +######################################## +# errors +my $usage = +"usage: fileshareset --add + fileshareset --remove "; +my $not_enabled = +qq(File sharing is not enabled. +To enable file sharing put +"FILESHARING=yes" in $authorisation_file); + +my $not_simple_enabled = +qq(Simple file sharing is not enabled. +To enable simple file sharing put +"SHARINGMODE=simple" in $authorisation_file); + +my $non_authorised = +qq(You are not authorised to use file sharing +To grant you the rights: +- put "RESTRICT=no" in $authorisation_file +- or put user "$username" in group "$authorisation_group"); + +my $no_export_method = "can't export anything: no nfs, no smb"; + +my %exit_codes = reverse ( + 1 => $non_authorised, + 2 => $usage, + +# when adding + 3 => "already exported", + 4 => "invalid mount point", + +# when removing + 5 => "not exported", + + 6 => $no_export_method, + + 7 => $not_enabled, + + 8 => $not_simple_enabled, + + 255 => "various", +); + +################################################################################ +# correct PATH needed to call /etc/init.d/... ? seems not, but... +%ENV = ();#(PATH => '/bin:/sbin:/usr/bin:/usr/sbin'); + +my $modify = $0 =~ /fileshareset/; + +authorisation::check($modify); + +my @exports = ( + -e $nfs_exports::conf_file ? nfs_exports::read() : (), + -e $smb_exports::conf_file ? smb_exports::read() : (), + ); +@exports or error($no_export_method); + +if ($modify) { + my ($cmd, $dir) = @ARGV; + $< = $>; + @ARGV == 2 && ($cmd eq '--add' || $cmd eq '--remove') or error($usage); + + verify_mntpoint($dir); + + if ($cmd eq '--add') { + my @errs = map { eval { $_->add($dir) }; $@ } @exports; + grep { !$_ } @errs or error("already exported"); + } else { + my @errs = map { eval { $_->remove($dir) }; $@ } @exports; + grep { !$_ } @errs or error("not exported"); + } + foreach my $export (@exports) { + $export->write; + $export->update_server; + } +} +my @mntpoints = grep {$_} uniq(map { map { $_->{mntpoint} } @$_ } @exports); +print "$_\n" foreach grep { own($_) } @mntpoints; + + +sub own { $uid == 0 || (stat($_[0]))[4] == $uid } + +sub verify_mntpoint { + local ($_) = @_; + my $ok = 1; + $ok &&= m|^/|; + $ok &&= !m|/\.\./|; + $ok &&= !m|[\0\n\r]|; + $ok &&= -d $_; + $ok &&= own($_); + $ok or error("invalid mount point"); +} + +sub error { + my ($string) = @_; + print STDERR "$string\n"; + exit($exit_codes{$string} || 255); +} +sub member { my $e = shift; foreach (@_) { $e eq $_ and return 1 } 0 } +sub uniq { my %l; $l{$_} = 1 foreach @_; grep { delete $l{$_} } @_ } + + +################################################################################ +package authorisation; + +sub read_conf { + my ($exclusive_lock) = @_; + open F_lock, $authorisation_file; # don't care if it's missing + flock(F_lock, $exclusive_lock ? 2 : 1) or die "can't lock"; + my %conf; + foreach () { + s/#.*//; # remove comments + s/^\s+//; + s/\s+$//; + /^$/ and next; + my ($cmd, $value) = split('=', $_, 2); + $conf{$cmd} = $value || warn qq(suspicious line "$_" in $authorisation_file\n); + } + # no close F_lock, keep it locked + \%conf +} + +sub check { + my ($exclusive_lock) = @_; + my $conf = read_conf($exclusive_lock); + if (lc($conf->{FILESHARING}) eq 'no') { + ::error($not_enabled); + } + + if (lc($conf->{SHARINGMODE}) eq 'advanced') { + ::error($not_simple_enabled); + } + + if (lc($conf->{FILESHAREGROUP} ne '')) { + $authorisation_group = lc($conf->{FILESHAREGROUP}); + } + + if (lc($conf->{RESTRICT}) eq 'no') { + # ok, access granted for everybody + } else { + my @l; + while (@l = getgrent) { + last if $l[0] eq $authorisation_group; + } + ::member($username, split(' ', $l[3])) or ::error($non_authorised); + } +} + +################################################################################ +package exports; + +sub find { + my ($exports, $mntpoint) = @_; + foreach (@$exports) { + $_->{mntpoint} eq $mntpoint and return $_; + } + undef; +} + +sub add { + my ($exports, $mntpoint) = @_; + foreach (@$exports) { + $_->{mntpoint} eq $mntpoint and die 'add'; + } + push @$exports, my $e = { mntpoint => $mntpoint }; + $e; +} + +sub remove { + my ($exports, $mntpoint) = @_; + my @l = grep { $_->{mntpoint} ne $mntpoint } @$exports; + @l < @$exports or die 'remove'; + @$exports = @l; +} + + +################################################################################ +package nfs_exports; + +use vars qw(@ISA $conf_file $default_options); +BEGIN { @ISA = 'exports' } + +sub read { + my $file = $conf_file; + local *F; + open F, $file or return []; + + my ($prev_raw, $prev_line, %e, @l); + my $line_nb = 0; + foreach my $raw () { + $line_nb++; + local $_ = $raw; + $raw .= "\n" if !/\n/; + + s/#.*//; # remove comments + + s/^\s+//; + s/\s+$//; # remove unuseful spaces to help regexps + + if (/^$/) { + # blank lines ignored + $prev_raw .= $raw; + next; + } + + if (/\\$/) { + # line continue across lines + chop; # remove the backslash + $prev_line .= "$_ "; + $prev_raw .= $raw; + next; + } + my $line = $prev_line . $_; + my $raw_line = $prev_raw . $raw; + ($prev_line, $prev_raw) = ('', ''); + + my ($mntpoint, $options) = $line =~ /("[^"]*"|\S+)\s+(.*)/ or die "$file:$line_nb: bad line $line\n"; + + # You can also specify spaces or any other unusual characters in the + # export path name using a backslash followed by the character code as + # 3 octal digits. + $mntpoint =~ s/\\(\d{3})/chr(oct $1)/ge; + + # not accepting weird characters that would break the output + $mntpoint =~ m/[\0\n\r]/ and die "i won't handle this"; + push @l, { mntpoint => $mntpoint, option => $options, raw => $raw_line }; + } + bless \@l, 'nfs_exports'; +} + +sub write { + my ($nfs_exports) = @_; + foreach (@$nfs_exports) { + if (!exists $_->{options}) { + $_->{options} = $default_options; + } + if (!exists $_->{raw}) { + my $mntpoint = $_->{mntpoint} =~ /\s/ ? qq("$_->{mntpoint}") : $_->{mntpoint}; + $_->{raw} = sprintf("%s %s\n", $mntpoint, $_->{options}); + } + } + local *F; + open F, ">$conf_file" or die "can't write $conf_file"; + print F $_->{raw} foreach @$nfs_exports; +} + +sub update_server { + if (fork) { + system('/usr/sbin/exportfs', '-r'); + if (system('PATH=/bin:/sbin pidof rpc.mountd >/dev/null') != 0 || + system('PATH=/bin:/sbin pidof nfsd >/dev/null') != 0) { + # trying to start the server... + system('/etc/init.d/portmap start') if system('/etc/init.d/portmap status') != 0; + if ( -f '/etc/init.d/nfs' ) { + system('/etc/init.d/nfs', $_) foreach 'stop', 'start'; + } + elsif ( -f '/etc/init.d/nfs-kernel-server' ) { + system('/etc/init.d/nfs-kernel-server', $_) foreach 'stop', 'start'; + } + } + exit 0; + } +} + +################################################################################ +package smb_exports; + +use vars qw(@ISA $conf_file); +BEGIN { @ISA = 'exports' } + +sub read { + my ($s, @l); + local *F; + open F, $conf_file; + local $_; + while () { + if (/^\s*\[.*\]/ || eof F) { + #- first line in the category + my ($label) = $s =~ /^\s*\[(.*)\]/; + my ($mntpoint) = $s =~ /^\s*path\s*=\s*(.*)/m; + push @l, { mntpoint => $mntpoint, raw => $s, label => $label }; + $s = ''; + } + $s .= $_; + } + bless \@l, 'smb_exports'; +} + +sub write { + my ($smb_exports) = @_; + foreach (@$smb_exports) { + if (!exists $_->{raw}) { + $_->{raw} = <{label}] + path = $_->{mntpoint} + comment = $_->{mntpoint} + public = yes + guest ok = yes + writable = no + wide links = no +EOF + } + } + local *F; + open F, ">$conf_file" or die "can't write $conf_file"; + print F $_->{raw} foreach @$smb_exports; +} + +sub add { + my ($exports, $mntpoint) = @_; + my $e = $exports->exports::add($mntpoint); + $e->{label} = name_mangle($mntpoint, map { $_->{label} } @$exports); +} + +sub name_mangle { + my ($input, @others) = @_; + + local $_ = $input; + + # 1. first only keep legal characters. "/" is also kept for the moment + tr|a-z|A-Z|; + s|[^A-Z0-9#\-_!/]|_|g; # "$" is allowed except at the end, remove it in any case + + # 2. removing non-interesting parts + s|^/||; + s|^home/||; + s|_*/_*|/|g; + s|_+|_|g; + + # 3. if size is too small (!), make it bigger + $_ .= "_" while length($_) < 3; + + # 4. if size is too big, shorten it + while (length > 12) { + my ($s) = m|.*?/(.*)|; + if (length($s) > 8 && !grep { /\Q$s/ } @others) { + # dropping leading directories when the resulting is still long and meaningful + $_ = $s; + next; + } + s|(.*)[0-9#\-_!/]|$1| and next; + + # inspired by "Christian Brolin" "Long names are doom" on comp.lang.functional + s|(.+)[AEIOU]|$1| and next; # allButFirstVowels + s|(.*)(.)\2|$1$2| and next; # adjacentDuplicates + + s|(.*).|$1|; # booh, :'-( + } + + # 5. remove "/"s still there + s|/|_|g; + + # 6. resolving conflicts + my $l = join("|", map { quotemeta } @others); + my $conflicts = qr|^($l)$|; + if (/$conflicts/) { + A: while (1) { + for (my $nb = 1; length("$_$nb") <= 12; $nb++) { + if ("$_$nb" !~ /$conflicts/) { + $_ = "$_$nb"; + last A; + } + } + $_ or die "can't find a unique name"; + # can't find a unique name, dropping the last letter + s|(.*).|$1|; + } + } + + # 7. done + $_; +} + +sub update_server { + if (fork) { + system('/usr/bin/killall -HUP smbd 2>/dev/null'); + if (system('PATH=/bin:/sbin pidof smbd >/dev/null') != 0 || + system('PATH=/bin:/sbin pidof nmbd >/dev/null') != 0) { +# trying to start the server... + if ( -f '/etc/init.d/smb' ) { + system('/etc/init.d/smb', $_) foreach 'stop', 'start'; + } + elsif ( -f '/etc/init.d/samba' ) { + system('/etc/init.d/samba', $_) foreach 'stop', 'start'; + } + elsif ( -f '/etc/rc.d/rc.samba' ) { + system('/etc/rc.d/rc.samba', $_) foreach 'stop', 'start'; + } + else { + print STDERR "Error: Can't find the samba init script \n"; + } + } + exit 0; + } +} diff --git a/tdeio/misc/kpac/CMakeLists.txt b/tdeio/misc/kpac/CMakeLists.txt new file mode 100644 index 000000000..14af52de1 --- /dev/null +++ b/tdeio/misc/kpac/CMakeLists.txt @@ -0,0 +1,66 @@ +################################################# +# +# (C) 2010 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${TQT_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdecore + ${CMAKE_BINARY_DIR}/kjs + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/dcop + ${CMAKE_SOURCE_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdecore/network + ${CMAKE_SOURCE_DIR}/tdeio + ${CMAKE_SOURCE_DIR}/tdeio/tdeio + ${CMAKE_SOURCE_DIR}/kded +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + +##### other data ################################ + +install(FILES proxyscout.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded ) +install(FILES eventsrc DESTINATION ${DATA_INSTALL_DIR}/proxyscout ) + + +##### kded_proxyscout ########################### + +set( target kded_proxyscout ) + +set( ${target}_SRCS + proxyscout.cpp proxyscout.skel script.cpp + downloader.cpp discovery.cpp +) + +set( ${target}_SKELS + proxyscout.h +) + +tde_add_kpart( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK tdeinit_kded-shared kjs-shared ${RESOLV_LIBRARIES} + DEPENDENCIES dcopidl + DESTINATION ${PLUGIN_INSTALL_DIR} +) + + +##### kpac_dhcp_helper ########################## + +set( target kpac_dhcp_helper ) + +# FIXME on Gentoo this binary is not suided +tde_add_executable( ${target} SETUID + SOURCES kpac_dhcp_helper.c + DESTINATION ${BIN_INSTALL_DIR} +) diff --git a/tdeio/misc/kpac/Makefile.am b/tdeio/misc/kpac/Makefile.am new file mode 100644 index 000000000..beb6a4b86 --- /dev/null +++ b/tdeio/misc/kpac/Makefile.am @@ -0,0 +1,30 @@ + +kde_module_LTLIBRARIES = kded_proxyscout.la +bin_PROGRAMS = kpac_dhcp_helper + +INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/libltdl -I$(top_srcdir)/kded -I$(top_builddir)/kjs \ + -I$(top_srcdir)/tdecore/network $(all_includes) +METASOURCES = AUTO +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + +kded_proxyscout_la_SOURCES = proxyscout.skel proxyscout.cpp script.cpp \ + downloader.cpp discovery.cpp +kded_proxyscout_la_LDFLAGS = $(all_libraries) -module -avoid-version +kded_proxyscout_la_LIBADD = $(LIB_KIO) $(top_builddir)/kjs/libkjs.la $(LIB_KDED) $(LIB_QT) \ + $(top_builddir)/dcop/libDCOP.la $(LIB_TDECORE) $(LIBRESOLV) + +kpac_dhcp_helper_SOURCES = kpac_dhcp_helper.c +kpac_dhcp_helper_CFLAGS = $(KDE_USE_FPIE) +kpac_dhcp_helper_LDFLAGS = $(KDE_USE_PIE) +kpac_dhcp_helper_LDADD = $(LIBSOCKET) + +noinst_HEADERS = proxyscout.h script.h downloader.h discovery.h + +servicesdir = $(kde_servicesdir)/kded +services_DATA = proxyscout.desktop + +proxyscoutdatadir = $(kde_datadir)/proxyscout +proxyscoutdata_DATA = eventsrc + +install-exec-local: + @(chown root $(DESTDIR)$(bindir)/kpac_dhcp_helper && chmod 4755 $(DESTDIR)$(bindir)/kpac_dhcp_helper) || echo "Please make kpac_dhcp_helper setuid root" diff --git a/tdeio/misc/kpac/README b/tdeio/misc/kpac/README new file mode 100644 index 000000000..d211ae07b --- /dev/null +++ b/tdeio/misc/kpac/README @@ -0,0 +1,9 @@ +Proxy Auto Configuration is a means to use a JavaScript function to +determine the proxy to use based on the requested URL. +It is described in detail here: +http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/proxy-live.html + +Also implemented by this library are parts of the now expired Internet Draft +at http://www.wrec.org/Drafts/draft-cooper-webi-wpad-00.txt about WPAD +(Web Proxy Automatic Discovery). The discovery implemented discovery methods +are DHCP and DNS "Well known Aliases". diff --git a/tdeio/misc/kpac/README.wpad b/tdeio/misc/kpac/README.wpad new file mode 100644 index 000000000..f63d25764 --- /dev/null +++ b/tdeio/misc/kpac/README.wpad @@ -0,0 +1,73 @@ +Web Proxy Auto Discovery (WPAD) +=============================== + +This README is intended for network administrators who want to enable the +users on their network to fully automatically find the proxy settings. + +Automatic proxy discovery works in two steps: +1) Find a configuration script +2) Determine a proxy to use by running that script + +The configuration script is a "PAC" (JavaScript) file just as in plain Proxy +Auto Configuration as described here: +http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/proxy-live.html + +The WPAD part of the process (#1 above) described here is about how to find +this script without having the users enter its URL into the proxy settings. +(All they have to do in a WPAD-enabled network is to select "Automatically +detected script file" in KDE's proxy setup. + +There are two alternative ways to discover the PAC script's URL implemented +in KDE: + +1. DHCP based autodiscovery + + If you are running a DHCP server on your network anyway, you might + want to use this approach; all you have to do is to add the WPAD + option (numeric 252 or hex fc) as a string containing the URL to the + PAC script. + + To do so with older versions of ISC dhcpd, add this to + /etc/dhcpd.conf, either globally or just for the subnets you want to + enable WPAD for: + + option option-252 "http://example.com/path/to/proxyconfig.pac"; + + Or, for newer ISC dhcpd versions, add this globally: + + option wpad code 252 = text; + + and this either globally or for the WPAD subnets: + + option wpad "http://example.com/path/to/proxyconfig.pac"; + + For other DHCP servers, please consult the reference manual on how + to add an option by number if WPAD support is not built-in. + +2. DNS based autodiscovery + + If you don't run a DHCP server or prefer DNS based discovery, you + need to configure one of your hosts to have the name + wpad.example.com and make sure the PAC script is available as + http://wpad.example.com/wpad.dat If your network consists of several + subdomains, like a.example.com and b.example.com you can either + provide both http://a.example.com/wpad.dat and + http://b.example.com/wpad.dat or just http://example.com/wpad.dat + When a client searches for that script, it will search for a host + named "wpad" in its own domain, then in the next higher level domain + until success or if only the TLD is left (i.e. wpad.com will never + be tried) + +Note that DHCP is the preferred approach since it's more flexible than DNS +as it doesn't require a well known host name nor a fixed location +(/wpad.dat) for the PAC script. It is also the first method tried before +resorting to DNS, so if you use DNS there will be a noticeable delay of 5 +seconds while waiting for a DHCP reply. + +However, DHCP requires a helper program, kpac_dhcp_helper to be installed +suid root. If you consider this a security problem, just delete that program +or remove its suid permissions and use DNS instead. If the helper cannot +execute as root, the 5 seconds delay will also go away. + +If you have further questions or comments, please contact me: Malte +Starostik diff --git a/tdeio/misc/kpac/TODO b/tdeio/misc/kpac/TODO new file mode 100644 index 000000000..ce5cd6a11 --- /dev/null +++ b/tdeio/misc/kpac/TODO @@ -0,0 +1 @@ +* Make use of badProxy() in KProtocolManager to enable fallbacks diff --git a/tdeio/misc/kpac/configure.in.in b/tdeio/misc/kpac/configure.in.in new file mode 100644 index 000000000..a65b9a1c8 --- /dev/null +++ b/tdeio/misc/kpac/configure.in.in @@ -0,0 +1,26 @@ +dnl some setgroups() implementations seem to have short* instead of gid_t* +dnl and use some flags in the fiels that follows the gids +AC_MSG_CHECKING([for setgroups with short argument]) +AC_CACHE_VAL([kde_cv_shortsetgroups],[ + AC_TRY_RUN([ + int main() + { + short x[4]; + x[0] = x[1] = 1; + if (getgroups(1, x) == 0) if (setgroups(1, x) == -1) exit(1); + + if (getgroups(1, x) == -1) exit(1); + if (x[1] != 1) exit(1); + x[1] = 2; + if (getgroups(1, x) == -1) exit(1); + if (x[1] != 2) exit(1); + exit(0); + } + ],[kde_cv_shortsetgroups="yes"],[kde_cv_shortsetgroups="no"]) +]) +AC_MSG_RESULT($kde_cv_shortsetgroups) +if test "$kde_cv_shortsetgroups" = "yes"; then + AC_DEFINE(HAVE_SHORTSETGROUPS,1,[if setgroups() takes short *as second arg]) +fi + +AC_CHECK_HEADERS(arpa/nameser8_compat.h sys/param.h) diff --git a/tdeio/misc/kpac/dhcp.h b/tdeio/misc/kpac/dhcp.h new file mode 100644 index 000000000..41643ae3a --- /dev/null +++ b/tdeio/misc/kpac/dhcp.h @@ -0,0 +1,78 @@ +/* This file is part of the KDE Libraries + Copyright (c) 2001 Malte Starostik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + + +/* See RFC 2131 for details */ + +#ifndef __dhcp_h__ +#define __dhcp_h__ + +#ifdef HAVE_STDINT_H +# include +#endif + +#define DHCP_OPT_LEN 312 + +struct dhcp_msg +{ +#define DHCP_BOOTREQUEST 1 +#define DHCP_BOOTREPLY 2 + uint8_t op; /* operation */ + uint8_t htype; /* hwaddr type */ + uint8_t hlen; /* hwaddr len */ + uint8_t hops; + uint32_t xid; /* transaction id */ + uint16_t secs; /* seconds since protocol start */ +#define DHCP_BROADCAST 1 + uint16_t flags; + uint32_t ciaddr; /* client IP */ + uint32_t yiaddr; /* "your" IP */ + uint32_t siaddr; /* server IP */ + uint32_t giaddr; /* gateway IP */ + uint8_t chaddr[16]; /* client hwaddr */ + uint8_t sname[64]; /* server name */ + uint8_t file[128]; /* bootstrap file */ + uint8_t options[DHCP_OPT_LEN]; +}; + +/* first four bytes in options */ +#define DHCP_MAGIC1 0x63 +#define DHCP_MAGIC2 0x82 +#define DHCP_MAGIC3 0x53 +#define DHCP_MAGIC4 0x63 + +/* DHCP message types */ +#define DHCP_DISCOVER 1 +#define DHCP_OFFER 2 +#define DHCP_REQUEST 3 +#define DHCP_DECLINE 4 +#define DHCP_ACK 5 +#define DHCP_NAK 6 +#define DHCP_RELEASE 7 +#define DHCP_INFORM 8 + +/* option types */ +#define DHCP_OPT_MSGTYPE 0x35 +#define DHCP_OPT_PARAMREQ 0x37 +#define DHCP_OPT_WPAD 0xfc +#define DHCP_OPT_END 0xff + +#endif + +/* vim: ts=4 sw=4 noet + */ diff --git a/tdeio/misc/kpac/discovery.cpp b/tdeio/misc/kpac/discovery.cpp new file mode 100644 index 000000000..4f33d1389 --- /dev/null +++ b/tdeio/misc/kpac/discovery.cpp @@ -0,0 +1,147 @@ +/* + Copyright (c) 2003 Malte Starostik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#include "config.h" + +#include + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#include +#ifdef HAVE_ARPA_NAMESER8_COMPAT_H +#include +#endif +#ifdef HAVE_SYS_PARAM_H +// Basically, the BSDs need this before resolv.h +#include +#endif +#include +#include + +#include + +#include +#include +#include + +#include "discovery.moc" + +namespace KPAC +{ + Discovery::Discovery( TQObject* parent ) + : Downloader( parent ), + m_helper( new KProcIO ) + { + connect( m_helper, TQT_SIGNAL( readReady( KProcIO* ) ), TQT_SLOT( helperOutput() ) ); + connect( m_helper, TQT_SIGNAL( processExited( TDEProcess* ) ), TQT_SLOT( failed() ) ); + *m_helper << "kpac_dhcp_helper"; + + if ( !m_helper->start() ) + TQTimer::singleShot( 0, this, TQT_SLOT( failed() ) ); + } + + bool Discovery::initHostName() + { + struct utsname uts; + + if (uname (&uts) > -1) + { + struct hostent *hent = gethostbyname (uts.nodename); + if (hent != 0) + m_hostname = TQString::fromLocal8Bit( hent->h_name ); + } + + // If no hostname, try gethostname as a last resort. + if (m_hostname.isEmpty()) + { + char buf [256]; + if (gethostname (buf, sizeof(buf)) == 0) + { + buf[255] = '\0'; + m_hostname = TQString::fromLocal8Bit( buf ); + } + } + return !m_hostname.isEmpty(); + } + + bool Discovery::checkDomain() const + { + // If a domain has a SOA record, don't traverse any higher. + // Returns true if no SOA can be found (domain is "ok" to use) + // Stick to old resolver interface for portability reasons. + union + { + HEADER header; + unsigned char buf[ PACKETSZ ]; + } response; + int len = res_query( m_hostname.local8Bit(), C_IN, T_SOA, + response.buf, sizeof( response.buf ) ); + if ( len <= int( sizeof( response.header ) ) || + ntohs( response.header.ancount ) != 1 ) return true; + unsigned char* pos = response.buf + sizeof( response.header ); + unsigned char* end = response.buf + len; + // skip query section + pos += dn_skipname( pos, end ) + QFIXEDSZ; + if ( pos >= end ) return true; + // skip answer domain + pos += dn_skipname( pos, end ); + short type; + GETSHORT( type, pos ); + return type != T_SOA; + } + + void Discovery::failed() + { + setError( i18n( "Could not find a usable proxy configuration script" ) ); + + // If this is the first DNS query, initialize our host name or abort + // on failure. Otherwise abort if the current domain (which was already + // queried for a host called "wpad" contains a SOA record) + bool firstQuery = m_hostname.isEmpty(); + if ( ( firstQuery && !initHostName() ) || + ( !firstQuery && !checkDomain() ) ) + { + emit result( false ); + return; + } + + int dot = m_hostname.find( '.' ); + if ( dot >= 0 ) + { + m_hostname.remove( 0, dot + 1 ); // remove one domain level + download( KURL( "http://wpad." + m_hostname + "./wpad.dat" ) ); + } + else emit result( false ); + } + + void Discovery::helperOutput() + { + m_helper->disconnect( this ); + TQString line; + m_helper->readln( line ); + download( KURL( line.stripWhiteSpace() ) ); + } +} + +// vim: ts=4 sw=4 et diff --git a/tdeio/misc/kpac/discovery.h b/tdeio/misc/kpac/discovery.h new file mode 100644 index 000000000..a1443ad8c --- /dev/null +++ b/tdeio/misc/kpac/discovery.h @@ -0,0 +1,55 @@ +/* + Copyright (c) 2003 Malte Starostik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#ifndef KPAC_DISCOVERY_H +#define KPAC_DISCOVERY_H + +#include + +#include "downloader.h" + +class KProcIO; + +namespace KPAC +{ + class Discovery : public Downloader + { + Q_OBJECT + public: + Discovery( TQObject* ); + + protected slots: + virtual void failed(); + + private slots: + void helperOutput(); + + private: + bool initHostName(); + bool checkDomain() const; + + KProcIO* m_helper; + TQString m_hostname; + }; +} + +#endif // KPAC_DISCOVERY_H + +// vim: ts=4 sw=4 et diff --git a/tdeio/misc/kpac/downloader.cpp b/tdeio/misc/kpac/downloader.cpp new file mode 100644 index 000000000..c94cc9b72 --- /dev/null +++ b/tdeio/misc/kpac/downloader.cpp @@ -0,0 +1,89 @@ +/* + Copyright (c) 2003 Malte Starostik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#include +#include + +#include + +#include +#include +#include +#include + +#include "downloader.moc" + +namespace KPAC +{ + Downloader::Downloader( TQObject* parent ) + : TQObject( parent ) + { + } + + void Downloader::download( const KURL& url ) + { + m_data.resize( 0 ); + m_script = TQString::null; + m_scriptURL = url; + + TDEIO::TransferJob* job = TDEIO::get( url, false, false ); + connect( job, TQT_SIGNAL( data( TDEIO::Job*, const TQByteArray& ) ), + TQT_SLOT( data( TDEIO::Job*, const TQByteArray& ) ) ); + connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ), TQT_SLOT( result( TDEIO::Job* ) ) ); + } + + void Downloader::failed() + { + emit result( false ); + } + + void Downloader::setError( const TQString& error ) + { + m_error = error; + } + + void Downloader::data( TDEIO::Job*, const TQByteArray& data ) + { + unsigned offset = m_data.size(); + m_data.resize( offset + data.size() ); + std::memcpy( m_data.data() + offset, data.data(), data.size() ); + } + + void Downloader::result( TDEIO::Job* job ) + { + if ( !job->error() && !static_cast< TDEIO::TransferJob* >( job )->isErrorPage() ) + { + bool dummy; + m_script = TDEGlobal::charsets()->codecForName( + job->queryMetaData( "charset" ), dummy )->toUnicode( m_data ); + emit result( true ); + } + else + { + if ( job->error() ) + setError( i18n( "Could not download the proxy configuration script:\n%1" ) + .arg( job->errorString() ) ); + else setError( i18n( "Could not download the proxy configuration script" ) ); // error page + failed(); + } + } +} + +// vim: ts=4 sw=4 et diff --git a/tdeio/misc/kpac/downloader.h b/tdeio/misc/kpac/downloader.h new file mode 100644 index 000000000..808e09378 --- /dev/null +++ b/tdeio/misc/kpac/downloader.h @@ -0,0 +1,64 @@ +/* + Copyright (c) 2003 Malte Starostik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#ifndef KPAC_DOWNLOADER_H +#define KPAC_DOWNLOADER_H + +#include + +#include + +namespace TDEIO { class Job; } + +namespace KPAC +{ + class Downloader : public TQObject + { + Q_OBJECT + public: + Downloader( TQObject* ); + + void download( const KURL& ); + const KURL& scriptURL() { return m_scriptURL; } + const TQString& script() { return m_script; } + const TQString& error() { return m_error; } + + signals: + void result( bool ); + + protected: + virtual void failed(); + void setError( const TQString& ); + + private slots: + void data( TDEIO::Job*, const TQByteArray& ); + void result( TDEIO::Job* ); + + private: + TQByteArray m_data; + KURL m_scriptURL; + TQString m_script; + TQString m_error; + }; +} + +#endif // KPAC_DOWNLOADER_H + +// vim: ts=4 sw=4 et diff --git a/tdeio/misc/kpac/eventsrc b/tdeio/misc/kpac/eventsrc new file mode 100644 index 000000000..c44443a03 --- /dev/null +++ b/tdeio/misc/kpac/eventsrc @@ -0,0 +1,530 @@ +[!Global!] +IconName=proxy +Comment=Automatic Proxy Configuration +Comment[af]=Outomatiese Proksie Opstelling +Comment[ar]=تهيئة آلية للخادم الوكيل +Comment[az]=Avtomatik Vəkil Quraşdırılması +Comment[bg]=Автоматично настройване на прокси сървъра +Comment[bn]=স্বয়ংক্রিয় প্রক্সি কনফিগারেশন +Comment[br]=Kefluniadur emgefreekh ar proksi +Comment[bs]=Automatsko podešavanje proxy-ja +Comment[ca]=Configuració automàtica del servidor d'intercanvi +Comment[cs]=Automatické nastavení proxy +Comment[csb]=Aùtokònfigùracëjô pòstrzédnika +Comment[cy]=Ffurweddiad Awtomatig o'r Dirprwy +Comment[da]=Automatisk proxy-indstilling +Comment[de]=Autom. Proxy-Einrichtung +Comment[el]=Αυτόματη ρύθμιση διαμεσολαβητή +Comment[eo]=Aŭtomata Prokuragordo +Comment[es]=Configuración automática del Proxy +Comment[et]=Automaatne proxy konfigureerimine +Comment[eu]=Proxy-aren konfigurazio automatikoa +Comment[fa]=پیکربندی خودکار پیشکار +Comment[fi]=Automaattiset proxy-asetukset +Comment[fr]=Configuration automatique du serveur mandataire +Comment[fy]=Automatyske proxy ynstelling +Comment[ga]=Uathchumraíocht an tSeachfhreastalaí +Comment[gl]=Configuración Automática do Proxy +Comment[he]=הגדרות פרוקסי אוטומטיות +Comment[hi]=स्वचलित प्रॉक्सी कॉन्फ़िगरेटर +Comment[hr]=Automatsko podešavanje proxyja +Comment[hu]=Automatikus proxybeállítás +Comment[id]=Konfigurasi Proxi Otomatis +Comment[is]=Sjálfvirkar stillingar milliþjóns +Comment[it]=Configurazione automatica proxy +Comment[ja]=自動プロキシ設定 +Comment[ka]=პროქსის თვითგამართვა +Comment[kk]=Автоматты түрде проксиді баптау +Comment[km]=ការ​កំណត់​រចនាសម្ព័ន្ធ​ប្រូកស៊ី​ដោយ​ស្វ័យ​ប្រវត្តិ +Comment[ko]=스스로 프록시 설정 +Comment[lb]=Automatesch Proxy-Configuratioun +Comment[lt]=Automatinis proxy derinimas +Comment[mk]=Автоматска конфигурација на прокси +Comment[mn]=Автомат итгэмжилэгчийн тохиргоо +Comment[ms]=Penyelarasan Proksi Automatik +Comment[nb]=Automatisk mellomtjenerinnstilling +Comment[nds]=Proxy automaatsch instellen +Comment[ne]=स्वचालित प्रोक्सी कन्फिगरेसन +Comment[nl]=Automatische proxyconfiguratie +Comment[nn]=Automatisk mellomtenaroppsett +Comment[pa]=ਸਵੈ-ਚਾਲਤ ਪਰਾਕਸੀ ਸੰਰਚਨਾ +Comment[pl]=Autokonfiguracja pośrednika +Comment[pt]=Configuração Automática do 'Proxy' +Comment[pt_BR]=Configuração Automática do Proxy +Comment[ro]=Configurare automată "proxy" +Comment[ru]=Автонастройка прокси +Comment[rw]=Iboneza rya Nyabubasha Ryikoresha +Comment[se]=Automáhtalaš gaskabálváheiveheapmi +Comment[sk]=Automatická konfigurácia proxy +Comment[sl]=Samodejne nastavitve posrednika +Comment[sq]=Kofigurimi Automatik i Proxy-t +Comment[sr]=Аутоматско подешавање проксија +Comment[sr@Latn]=Automatsko podešavanje proksija +Comment[sv]=Automatisk proxyinställning +Comment[ta]=தானியக்க பதிலாள் வடிவமைப்பு +Comment[te]=స్వయంచాలిత ప్రాక్సీ రూపకరణం +Comment[tg]=Шакли Автоматӣ Вакил Кардашуда +Comment[th]=ปรับแต่งพร็อกซีอัตโนมัติ +Comment[tr]=Otomatik Vekil Sunucu Yapılandırması +Comment[tt]=Proxy'nı Aqıllı Caylaw +Comment[uk]=Автоматичне визначення проксі сервера +Comment[uz]=Proksini avtomatik ravishda moslash +Comment[uz@cyrillic]=Проксини автоматик равишда мослаш +Comment[vi]=Cấu hình ủy nhiệm tự động. +Comment[wa]=Apontiaedje otomatike do procsi +Comment[zh_CN]=自动代理配置 +Comment[zh_HK]=自動代理組態 +Comment[zh_TW]=自動代理組態 + +[script-error] +Name=Invalid proxy script +Name[af]=Ongeldige proksie skrip +Name[ar]=نص برمجي غير صالح +Name[az]=Hökmsüz vəkil skripti +Name[bg]=Невалиден скрипт за прокси сървъра +Name[bn]=অবৈধ প্রক্সি স্ক্রিপ্ট +Name[br]=N'eo ket mat an urzhiaoug proksi +Name[bs]=Neispravna proxy skripta +Name[ca]=Script del servidor intermedi no vàlid +Name[cs]=Neplatný proxy skript +Name[csb]=Falszëwi skript pòstrzédnika +Name[cy]=Sgript dirprwy annilys +Name[da]=Ugyldigt proxy-script +Name[de]=Ungültiges Proxy-Skript +Name[el]=Μη έγκυρο σενάριο διαμεσολαβητή +Name[eo]=Nevalida prokurila skripto +Name[es]=Procedimiento inválido del proxy +Name[et]=Vigane proxy skript +Name[eu]=Proxy-aren script baliogabea +Name[fa]=دست‌نوشتۀ پیشکار نامعتبر +Name[fi]=Virheellinen proxy-skripti +Name[fr]=Script de serveur mandataire non valable +Name[fy]=Unjildich proxy skript +Name[ga]=Script neamhbhailí seachfhreastalaí +Name[gl]=Guión de proxy inválido +Name[he]=תסריט Proxy לא תקין +Name[hi]=अवैध प्रॉक्सी स्क्रिप्ट +Name[hr]=Neispravna proxy skripta +Name[hu]=Érvénytelen proxy-szkript +Name[id]=Skrip proxi tidak sah +Name[is]=Ógild milliþjónsskrifta +Name[it]=Script proxy non valido +Name[ja]=無効なプロキシスクリプト +Name[ka]=პროქსის მცდარი სკრიპტი +Name[kk]=Жарамсыз прокси скрипті +Name[km]=ស្គ្រីប​ប្រូកស៊ី​មិន​ត្រឹមត្រូវ +Name[ko]=올바르지 않은 프록시 스크립트 +Name[lb]=Ongültegt Proxy-Skript +Name[lt]=Blogas proxy scenarijas +Name[mk]=Невалидна прокси скрипта +Name[mn]=Хүчингүй итгэмжилэгч скрипт +Name[ms]=Skrip proksi tidak sah +Name[nb]=Ugyldig mellomtjenerskript +Name[nds]=Proxyskript gellt nich +Name[ne]=अवैद्य प्रोक्सी स्क्रिप्ट +Name[nl]=Ongeldig proxyscript +Name[nn]=Ugyldig mellomtenarskript +Name[pa]=ਗਲਤ ਪਰਾਕਸੀ ਸਕ੍ਰਿਪਟ +Name[pl]=Niepoprawny skrypt pośrednika +Name[pt]=Configuração de 'proxy' inválida +Name[pt_BR]=Script de proxy inválido +Name[ro]=Script "proxy" eronat +Name[ru]=Неверный скрипт прокси +Name[rw]=Inyandikoporogaramu ya Nyabubasha ntiyemewe +Name[se]=Gustohis gaskabálváskripta +Name[sk]=Zlý proxy skript +Name[sl]=Neveljaven posredniški skript +Name[sq]=Proxy Skripta është e gabuar +Name[sr]=Неисправна прокси скрипта +Name[sr@Latn]=Neispravna proksi skripta +Name[sv]=Ogiltigt proxyskript +Name[ta]=செல்லாத பதிலாள் எழுத்தாக்கம் +Name[te]=చెల్లని ప్రాక్సీ స్క్రిప్ట్ +Name[tg]=Дастнависи вакил кардашуда ношоям +Name[th]=สคริปต์ของพร็อกซี ไม่ถูกต้อง +Name[tr]=Geçersiz vekil sunucu betiği +Name[tt]=Proxy ämerlege bozıq +Name[uk]=Неправильний скрипт для проксі +Name[uz]=Proksi skripti haqiqiy emas +Name[uz@cyrillic]=Прокси скрипти ҳақиқий эмас +Name[vi]=Tập lệnh ủy nhiệm không hợp lệ +Name[zh_CN]=无效的代理脚本 +Name[zh_HK]=不合法的代理伺服器 script +Name[zh_TW]=不合法 proxy 命令稿檔案 +Comment=The downloaded proxy configuration script is invalid +Comment[af]=Die proksie skipt wat afgelaai was is ongeldig +Comment[ar]=النص البرمجي الذي تم تنزيله غير صالح +Comment[az]=Endirilən vəkil quraşdırma skripti kökmsüzdür +Comment[bg]=Изтегленият скрипт за настройване на прокси сървъра е невалиден +Comment[bn]=ডাউনলোড করা প্রক্সি কনফিগারেশন স্ক্রিপ্টটি অবৈধ +Comment[br]=N'eo ket mat urzhiaoug kefluniadur ar proksi +Comment[bs]=Downloadovana skripta za podešavanje proxy-ja je neispravna +Comment[ca]=L'script de configuració del servidor intermedi descarregat no és vàlid +Comment[cs]=Stažený konfigurační skript pro proxy je neplatný +Comment[csb]=Zladowóny skript kònfigùracëji pòstrzédnika je falszëwi +Comment[cy]=Mae'r sgript ffurfweddu'r dirprwy a chafodd ei lawrlwytho yn annilys +Comment[da]=Det hentede proxy-indstillingsscript er ugyldigt +Comment[de]=Das heruntergeladene Proxy-Einrichtungsskript ist nicht verwendbar +Comment[el]=Το σενάριο ρύθμισης διαμεσολαβητή που λήφθηκε δεν είναι έγκυρο +Comment[eo]=La ŝarĝita prokuragordoskript estas nevalida +Comment[es]=El procedimiento descargado para la configuración del proxy es inválido +Comment[et]=Allalaaditud proxy seadistuse skript on vigane +Comment[eu]=Deskargatutako proxy-aren konfigurazioko script-a baliogabea da +Comment[fa]=دست‌نوشتۀ پیکربندی پیشکار بارگیری‌شده، نامعتبر است +Comment[fi]=Ladattu proxy-asetusskripti on virheellinen +Comment[fr]=Le script téléchargé de configuration du serveur mandataire n'est pas valable +Comment[fy]=It ynladen proxy ynstellings skript is ûnjildich +Comment[ga]=Is neamhbhailí í script chumraíocht an tseachfhreastalaí a íosluchtaíodh +Comment[gl]=O guión de configuración descarregado do proxy non é válido +Comment[he]=תסריט הגדרת הפרוקסי שהורד לא תקין +Comment[hi]=ङाउनलोडेड प्रॉक्सी कॉन्फ़िगरेटर स्क्रिप्ट अवैध है। +Comment[hr]=Preuzeta skripta konfiguriranja proxyja je neispravna +Comment[hu]=A letöltött proxybeállító szkript érvénytelen +Comment[id]=Skrip konfigurasi proxy yang diunduh tidak valid +Comment[is]=Sótt milliþjónsskrifta er ógild +Comment[it]=Lo script di configurazione proxy scaricato non è valido +Comment[ja]=ダウンロードされたプロキシ設定スクリプトは無効です。 +Comment[ka]=პროქსის გამართვის ჩამოტვირთული სკრიპტი მცდარია +Comment[kk]=Жүктеп алынған прокси баптау скрипті жарамсыз +Comment[km]=ស្គ្រីប​កំណត់​រចនាសម្ព័ន្ធប្រូកស៊ី​ដែល​បាន​ទាញយក មិន​ត្រឹមត្រូវ​ឡើយ +Comment[ko]=내려받은 프록시 설정 스크립트가 올바르지 않습니다. +Comment[lb]=D'Proxy-Configuratiounsskript, dat erofgelude gouf, ass ongülteg +Comment[lt]=Atsisiųstas proxy derinimo scenarijus yra blogas +Comment[mk]=Симнатата скрипта за конфигурација на прокси е навалидна +Comment[mn]=Татагдсан итгэмжилэгч тохируулгын скрипт хүчингүй +Comment[ms]=Skrip penyelarasan proksi yang dimuat turun tidak sah +Comment[nb]=Det nedlastede skriptet for mellomtjener-innstillinger er ugyldig +Comment[nds]=Dat Skript för't Instellen vun den Proxy gellt nich +Comment[ne]=डाउनलोड गरिएको प्रोक्सी कन्फिगरेसन स्क्रिप्ट अवैद्य छ +Comment[nl]=Het opgehaalde proxyconfiguratiescript is ongeldig +Comment[nn]=Det nedlasta skriptet for mellomtenaroppsett er ugyldig +Comment[pa]=ਡਾਊਨਲੋਡ ਪਰਾਕਸੀ ਸੰਰਚਨਾ ਸਕ੍ਰਿਪਟ ਜਾਇਜ਼ ਨਹੀਂ ਹੈ +Comment[pl]=Pobrany skrypt konfiguracji pośrednika jest nieprawidłowy +Comment[pt]=A configuração do 'proxy' transferida é inválida +Comment[pt_BR]=O script de configuração do proxy baixado é inválido +Comment[ro]=Scriptul de configurare "proxy" este eronat +Comment[ru]=Загруженный скрипт настройки прокси содержит ошибки +Comment[rw]=inyandikoporogaramu y'iboneza rya Nyabubasha yakuruwe ntiyemewe +Comment[se]=Viežžojuvvon gaskabálváskripta lea gustomeahttun +Comment[sk]=Stiahnutý konfiguračný skript proxy nie je správny +Comment[sl]=Naložen nastavitveni skript posrednika je neveljaven +Comment[sq]=Skripta për Konfigurimin e Proxy-t ishte e gabuar +Comment[sr]=Преузета скрипта за подешавање проксија је неисправна +Comment[sr@Latn]=Preuzeta skripta za podešavanje proksija je neispravna +Comment[sv]=Det nerladdade proxyinställningsskriptet är ogiltigt +Comment[ta]=இறக்கப்பட்ட பதிலாள் வடிவமைப்பு எழுத்தாக்கம் செல்லாது +Comment[te]=డౌన్ లోడ్ చేయబడిన్ ప్రాక్సీ రూపకరణపు స్క్రిప్ట్ చెల్లదు +Comment[tg]=Шакли дастнависи вакил кардашуда ношоям фаровир +Comment[th]=สคริปต์สำหรับการปรับแต่งพร็อกซีที่ดาวน์โหลดมาไม่ถูกต้อง +Comment[tr]=Vekil sunucu yapılandırma dosyası geçersiz +Comment[tt]=Proxy caylaw öçen iñderelgän ämerlek bozıq bulğan +Comment[uk]=Звантажений скрипт для визначення проксі сервера неправильний +Comment[uz]=Proksini moslash uchun yozib olingan skript haqiqiy emas +Comment[uz@cyrillic]=Проксини мослаш учун ёзиб олинган скрипт ҳақиқий эмас +Comment[vi]=Tập lệnh cấu hình ủy nhiệm đã được tải xuống không phải là hợp lệ. +Comment[zh_CN]=下载的代理配置脚本是无效的 +Comment[zh_HK]=剛下載的代理伺服器組態 script 語法有誤 +Comment[zh_TW]=代理組態的 script 檔案語法有誤 +default_presentation=16 + +[download-error] +Name=Script download error +Name[af]=Skrip aflaai fout +Name[ar]=خطأ أثناء تنزيل النص البرمجي +Name[az]=Skript endirmə xətası +Name[be]=Памылка сцягвання сцэнара +Name[bg]=Грешка при изтегляне на скрипта +Name[bn]=স্ক্রিপ্ট ডাউনলোডে সমস্যা +Name[br]=Fazi en ur enkargañ an urzhiaoug +Name[bs]=Greška pri downloadu skripte +Name[ca]=Error descàrrega de l'script +Name[cs]=Chyba ve stažení skriptu +Name[csb]=Fela zladënkù skriptu +Name[cy]=Gwall wrth lawrlwytho'r sgript +Name[da]=Script download-fejl +Name[de]=Fehler beim Herunterladen des Skripts +Name[el]=Σφάλμα λήψης σεναρίου +Name[eo]=Skripta ŝarĝeraro +Name[es]=Error de descarga del procedimiento +Name[et]=Viga skripti allalaadimisel +Name[eu]=Errorea script-a deskargatzean +Name[fa]=خطای بارگیری دست‌نوشته +Name[fi]=Skriptin latausvirhe +Name[fr]=Erreur de téléchargement du script +Name[fy]=Skript ynlaad flater +Name[ga]=Earráid íoslódála scripte +Name[gl]=Erro de descarga do guión +Name[he]=שגיאה בהורדת התסריט +Name[hi]=स्क्रिप्ट डाउनलोड त्रुटि +Name[hr]=Pogreška pri preuzimanju skripte +Name[hu]=Szkriptletöltési hiba +Name[id]=Kesalahan mengambil skrip +Name[is]=Villa við hleðslu skriftu +Name[it]=Errore di scaricamento script +Name[ja]=スクリプトのダウンロードエラー +Name[ka]=სკრიპტის ჩამოტვირთვის შეცდოამ +Name[kk]=Скриптті жүктеп алу қатесі +Name[km]=កំហុស​ទាញយក​ស្គ្រីប +Name[ko]=스크립트 내려받기 오류 +Name[lb]=Feeler beim Erofluede vum Skript +Name[lt]=scenarijaus atsisiuntimo klaida +Name[lv]=Skripta lejuplādes kļūda +Name[mk]=Грешка при симнување на скрипта +Name[mn]=Скрипт татахад алдаа +Name[ms]=Ralat muat turun skrip +Name[nb]=Skript nedlastingsfeil +Name[nds]=Skript-Daallaadfehler +Name[ne]=स्क्रिप्ट डाउनलोड त्रुटि +Name[nl]=Fout bij downloaden van script +Name[nn]=Feil ved skriptnedlasting +Name[pa]=ਸਕ੍ਰਿਪਟ ਡਾਊਨਲੋਡ ਗਲਤੀ +Name[pl]=Błąd pobierania skryptu +Name[pt]=Erro de transferência da configuração +Name[pt_BR]=Erro de download de script +Name[ro]=Eroare de transfer a scriptului +Name[ru]=Ошибка загрузки скрипта +Name[rw]=Ikosa ry'ikurura inyandikoporogaramu +Name[se]=Meattáhus skripta vieččadettiin +Name[sk]=Chyba počas sťahovania skriptu +Name[sl]=Napaka nalaganju skripta +Name[sq]=Skripta nuk pat sukses të Ngarkohet +Name[sr]=Грешка приликом преузимања скрипте +Name[sr@Latn]=Greška prilikom preuzimanja skripte +Name[sv]=Nerladdningsfel för skript +Name[ta]=எழுத்தாக்கத்தை இறக்கும்போது பிழை +Name[te]=స్క్రిప్ట్ డౌన్ లోడ్ దోషం +Name[tg]=Хатои дастнавис фаровир +Name[th]=ข้อผิดพลาดในการดาวน์โหลดสคริปต์ +Name[tr]=Betik indirme hatası +Name[tt]=Ämerlek iñderü xatarı +Name[uk]=Помилка звантаження скрипту +Name[uz]=Skriptni yozib olishda xato roʻy berdi +Name[uz@cyrillic]=Скриптни ёзиб олишда хато рўй берди +Name[vi]=Lỗi tải xuống tập lệnh +Name[zh_CN]=脚本下载错误 +Name[zh_HK]=Script 下載錯誤 +Name[zh_TW]=Script 下載錯誤 +Comment=The proxy configuration script could not be downloaded +Comment[af]=Die proksie opstelling skrip kon nie afgelaai word nie +Comment[ar]=تعذر تنزيل النص البرمجي لإعداد الخادم الوكيل +Comment[az]=VƏkil qurğuları skripti endirilə bilmədi +Comment[bg]=Скриптът за настройване на прокси сървъра не може да бъде изтеглен +Comment[bn]=প্রক্সি কনফিগারেশন স্ক্রিপ্ট ডাউনলোড করা যায়নি +Comment[br]=Ne m'eus ket enkargañ urzhiaoug kefluniadur ar proksi +Comment[bs]=Nisam mogao downloadovati skriptu za podešavanje proxy-ja +Comment[ca]=L'script de configuració del servidor intermedi no es pot descarregar +Comment[cs]=Nelze stáhnout konfigurační skript pro proxy +Comment[csb]=Nie je mòżno zladowac skriptu kònfiguracëji pòstrzédnika +Comment[cy]=Y sgript ffurfweddu'r dirprwy +Comment[da]=Proxy-indstillingsscriptet kunne ikke hentes +Comment[de]=Das Proxy-Einrichtungsskript lässt sich nicht herunterladen +Comment[el]=Το σενάριο ρύθμισης διαμεσολαβητή ήταν αδύνατο να ανακτηθεί +Comment[eo]=Ne eblas ŝarĝi la prokuragordoskripton +Comment[es]=El procedimiento de configuración del proxy no se pudo descargar +Comment[et]=Proxy seadistuse skripti ei õnnestu alla laadida +Comment[eu]=Proxy-aren konfigurazioko script-a ezin izan da deskargatu +Comment[fa]=دست‌نوشتۀ پیکربندی پیشکار بارگیری نشد +Comment[fi]=Proxyn asetusskriptiä ei voitu ladata +Comment[fr]=Le script de configuration du serveur mandataire n'a pas pu être téléchargé +Comment[fy]=It ynladen fan de proxy ynstellings skript is net slagge +Comment[ga]=Níorbh fhéidir script chumraíochta an tseachfhreastalaí a íoslódáil +Comment[gl]=Non se pudo descarregar o guión de configuración do proxy +Comment[he]=לא יכול להוריד את תסריט הגדרות הפרוקסי +Comment[hi]=प्रॉक्सी कॉन्फ़िगरेशन स्क्रिप्ट डाउनलोड नही की जा सकी। +Comment[hr]=Skripta konfiguriranja proxyja nije mogla biti preuzetom s Interneta +Comment[hu]=A proxybeállító szkript letöltése nem sikerült +Comment[id]= Skrip konfigurasi proxy tidak dapat diunduh +Comment[is]=Gat ekki sótt stillingaskriftu milliþjóns +Comment[it]=Impossibile scaricare lo script di configurazione proxy +Comment[ja]=プロキシ設定スクリプトをダウンロードできませんでした +Comment[ka]=პროქსის გამართვის სკრიპტის ჩამოტვირთვა ვერ ხერხდება +Comment[kk]=Бұл прокси скрипт жүктеп алынбайды +Comment[km]=មិន​អាច​ទាញយក​ស្គ្រីប​កំណត់​រចនាសម្ព័ន្ធ​ប្រូកស៊ី +Comment[ko]=프록시 설정 스크립트를 내려받지 못합니다 +Comment[lb]=D'Proxy-Konfiguratiounsskript konnt net erofgeluede ginn +Comment[lt]=Proxy derinimo scenarijus negali būti atsisiųstas +Comment[mk]=Скриптата за конфигурација на прокси не можеше да се симне +Comment[mn]=Итгэмжилэгч тохиргооны скрипт татагдахгүй байна +Comment[ms]=Skrip penyelarasan proksi tidak boleh dimuat turun +Comment[nb]=Klarte ikke å laste ned skiptet for mellomtjener-innstillinger +Comment[nds]=Dat Skript för't Instellen vun den Proxy lett sik nich daalladen +Comment[ne]=प्रोक्सी कन्फिगरेसन स्क्रिप्ट डाउनलोड हुन सक्ने छैन +Comment[nl]=Het proxyconfiguratiescript kon niet worden opgehaald +Comment[nn]=Klarte ikkje lasta ned skript for mellomtenaroppsett +Comment[pa]=ਪਰਾਕਸੀ ਸੰਰਚਨਾ ਸਕ੍ਰਿਪਟ ਨੂੰ ਲੋਡ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ +Comment[pl]=Nie można pobrać skryptu konfiguracji pośrednika +Comment[pt]=A configuração do 'proxy' não pôde ser transferida +Comment[pt_BR]=O script de configuração do proxy não pode ser carregado +Comment[ro]=Nu am putut transfera scriptul de configurare "proxy" +Comment[ru]=Не удаётся загрузить скрипт настройки прокси +Comment[rw]=Inyandikoporogaramu y'iboneza rya Nyabubasha ntiyashoboye gukururwa +Comment[se]=Ii sáhttán gaskbálváheivehanskripta viežžat +Comment[sk]=Nebolo možné stiahnúť konfiguračný skript pre proxy +Comment[sl]=Nastavitveni skript posrednika ni mogel biti naložen +Comment[sq]=Skripta për Konfigurimin e Proxy-t nuk pat sukses të ngarkohet +Comment[sr]=Скрипта за подешавање проксија не може бити преузета +Comment[sr@Latn]=Skripta za podešavanje proksija ne može biti preuzeta +Comment[sv]=Proxyinställningsskriptet kunde inte laddas ner +Comment[ta]=பதிலாள் வடிவமைப்பு எழுத்தாக்கத்தை இறக்க முடியவில்லை +Comment[te]=ప్రాక్సీ రూపకరణపు స్క్రిప్ట్ ని డౌన్ లోడ్ చేయలేకపోయాం +Comment[tg]=Шакли дастнависи вакил кардашуда фаровир наметавонад +Comment[th]=ไม่สามารถดาวน์โหลดสคริปต์สำหรับปรับแต่งพร็อกซีได้ +Comment[tr]=Vekil sunucu yapılandırma dosyası indirilemedi +Comment[tt]=Bu proxy caylaw ämerlegen iñderep bulmadı +Comment[uk]=Не вдається звантажити скрипт для визначення проксі сервера +Comment[uz]=Proksini moslash uchun skriptni yozib olib boʻlmadi +Comment[uz@cyrillic]=Проксини мослаш учун скриптни ёзиб олиб бўлмади +Comment[vi]=Không thể tải xuống tập lệnh cấu hình ủy nhiệm. +Comment[zh_CN]=代理配置脚本无法下载 +Comment[zh_HK]=無法取得代理伺服器組態 script 檔案 +Comment[zh_TW]=無法取得代理組態 script 檔案 +default_presentation=16 + +[evaluation-error] +Name=Script evaluation error +Name[af]=Skrip evaluasie fout +Name[ar]=خطأ في تقييم النص البرمجي +Name[az]=Skript icra xətası +Name[bg]=Грешка при обработка на скрипта +Name[bn]=স্ক্রিপ্ট চালানোয় সমস্যা +Name[bs]=Greška pri procjeni skripte +Name[ca]=Error en l'avaluació de l'script +Name[cs]=Chyba v analýze skriptu +Name[csb]=Fela zrëszëniô skriptu +Name[cy]=Gwall wrth werthuso'r sgript +Name[da]=Script evalueringsfejl +Name[de]=Skript-Überprüfungsfehler +Name[el]=Σφάλμα επικύρωσης σεναρίου +Name[eo]=Skripta ruleraro +Name[es]=Error de evaluación del procedimiento +Name[et]=Viga skripti käivitamisel +Name[eu]=Script-aren ebaluazioko errorea +Name[fa]=خطای ارزیابی دست‌نوشته +Name[fi]=Skriptin määritysvirhe +Name[fr]=Erreur d'évaluation du script +Name[fy]=Beoardiele skript flater +Name[ga]=Earráid agus an script á luacháil +Name[gl]=Erro de evaluación do guión +Name[he]=שגיאת הרצה בתסריט +Name[hi]=स्क्रिप्ट इवेल्यूएशन त्रुटि +Name[hr]=Pogreška pri procjenjivanju skripte +Name[hu]=Szkriptkiértékelési hiba +Name[id]=Kesalahan menjalankan skrip +Name[is]=Túlkunarvilla skriftu +Name[it]=Errore di valutazione script +Name[ja]=スクリプト評価エラー +Name[ka]=სკრიპტის დამუშავების შეცდომა +Name[kk]=Скрипт талдау қатесі +Name[km]=កំហុស​វាយតម្លៃរបស់ស្គ្រីប +Name[ko]=스크립트 평가 오류 +Name[lb]=Feeler beim Evaluéieren vum Skript +Name[lt]=Scenarijaus analizės klaida +Name[mk]=Грешка при евалуација на скрипта +Name[mn]=Скрипт үнэлэхэд алдаа +Name[ms]=Ralat penilaian skrip +Name[nb]=Skript evalueringsfeil +Name[nds]=Skript-Pröövfehler +Name[ne]=स्क्रिप्ट मूल्यांकन त्रुटि +Name[nl]=Fout bij evalueren van script +Name[nn]=Feil ved skriptevaluering +Name[pa]=ਸਕ੍ਰਿਪਟ ਏਵੂਲੇਸ਼ਨ ਗਲਤੀ +Name[pl]=Błąd wykonywania skryptu +Name[pt]=Erro de avaliação da configuração +Name[pt_BR]=Erro de avaliação de script +Name[ro]=Eroare de analiză a scriptului +Name[ru]=Ошибка разбора скрипта +Name[rw]=Ikosa ry'isuzuma ry'inyandikoporogaramu +Name[sk]=Chyba kontroly skriptu +Name[sl]=Napaka pri ocenjevanju skripta +Name[sq]=Gabim i vlerësimit të skriptës +Name[sr]=Грешка приликом израчунавања у скрипти +Name[sr@Latn]=Greška prilikom izračunavanja u skripti +Name[sv]=Utvärderingsfel för skript +Name[ta]=எழுத்தாக்க மதிப்பீட்டுப் பிழை +Name[te]=స్క్రిప్ట్ నిర్వహణ దోషం +Name[tg]=Фикри хатои дастнавис +Name[th]=ข้อผิดพลาดในการประเมินสคริปต์ +Name[tr]=Betik çalıştırma hatası +Name[tt]=Ämerlek eçtälegen uqığanda xata çıqtı +Name[uk]=Помилка виконання скрипту +Name[uz]=Skriptni tekshirishda xato roʻy berdi +Name[uz@cyrillic]=Скриптни текширишда хато рўй берди +Name[vi]=Lỗi định lượng tập lệnh +Name[zh_CN]=脚本求值错误 +Name[zh_HK]=Script 執行錯誤 +Name[zh_TW]=Script 執行錯誤 +Comment=There was an error executing the proxy configuration script +Comment[af]=Daar was 'n fout met die uitvoer van die proksie opstell skrip +Comment[ar]=لقد حصل خطأ كبير أدى الى خروج البرنامج +Comment[az]=Vəkil qurğuları skripti işə salınırkən xəta baş verdi +Comment[bg]=Грешка по време на изпълнение на скрипта за настройване на прокси сървъра +Comment[bn]=প্রক্সি কনফিগারেশন স্ক্রিপ্ট চালাতে সমস্যা দেখা দিয়েছে +Comment[br]=Degouezhet ez eus ur fazi en ur seveniñ urzhiaoug kefluniadur ar proksi +Comment[bs]=Došlo je do greške pri izvršavanju skripte za podešavanje proxy-ja +Comment[ca]=Hi ha hagut un error executant l'script de configuració del servidor intermedi +Comment[cs]=Nastala chyba při spouštění konfiguračního skriptu proxy +Comment[csb]=Pòkôza sã fela, òb czas zrëszëniô skriptu kònfigùracëji pòstrzédnika +Comment[cy]=Digwyddodd gwall wrth weithredu'r sgript ffurfweddu'r dirprwy +Comment[da]=Der opstod en fejl ved kørslen af proxy-indstillingsscriptet +Comment[de]=Fehler beim Ausführen des Proxy-Einrichtungsskripts +Comment[el]=Συνέβη ένα σφάλμα στην εκτέλεση του σεναρίου ρύθμισης διαμεσολαβητή +Comment[eo]=Okazis eraro dum rulo de la prokuragordoskripto +Comment[es]=Se produjo un error al ejecutarse el procedimiento de configuración del proxy +Comment[et]=Ilmnes tõsine viga proxy seadistuse skripti käivitamisel +Comment[eu]=Errorea gertatu da proxy-a konfiguratzeko script-ean +Comment[fa]=هنگام اجرای دست‌نوشتۀ پیکربندی پیشکار، خطایی وجود داشت +Comment[fi]=Proxy-skriptin suorittamisessa tapahtui virhe +Comment[fr]=Une erreur s'est produite lors de l'exécution du script de configuration du serveur mandataire +Comment[fy]=Der wie in flater by it útfoeren fan de proxy ynstellings skript +Comment[ga]=Tharla earráid agus script chumraíocht an tseachfhreastalaí á rith +Comment[gl]=Houbo un erro executando o guión de configuración do proxi +Comment[he]=אירעה שגיאה בעת הרצת תסריט הגדרות בפרוקסי +Comment[hi]=प्रॉक्सी कॉन्फ़िगरेशन स्क्रिप्ट चलाने में त्रुटि हुई +Comment[hr]=Došlo je do pogreške pri izvršavanju konfiguracijske skripte proxyja +Comment[hu]=Hiba történt a proxybeállító szkript végrehajtása közben +Comment[id]=Kesalahan sewaktu menjalankan skrip konfigurasi proxy +Comment[is]=Það kom upp villa við keyrslu stillingaskriftu milliþjóns +Comment[it]=Si è verificato un errore durante l'esecuzione dello script di configurazione proxy +Comment[ja]=プロキシ設定スクリプトの実行中にエラーが発生しました +Comment[ka]=პროქსის გამართვის სკრიპტის გამოყენების შეცდომა +Comment[kk]=Прокси баптау скриптті орындау кезінде қате пайда болды +Comment[km]=មាន​កំហុស​មួយ​ក្នុងការប្រតិបត្តិ​ស្គ្រីបកំណត់​រចនាសម្ព័ន្ធ​ប្រូកស៊ី +Comment[ko]=프록시 설정 스크리트를 실행하는데 문제가 있습니다 +Comment[lb]=Et gouf e Feeler beim Ausféiere vum Proxy-Konfiguratiounsskript +Comment[lt]=Paleidžiant proxy derinimo scenarijų įvyko klaida +Comment[mk]=Имаше грешка при извршувањето на скриптата за конфигурација на прокси +Comment[mn]=итгэмжилэгч тохируулгын скрипт ажиллуулж байхад алдаа +Comment[ms]=Terdapat ralat melaksanakan skrip penyelarasan proksi +Comment[nb]=Det oppsto en alvorlig feil under kjøringen av skriptet for mellomtjener-innstillinger +Comment[nds]=Bi't Utföhren vun dat Proxy-Instellenskript hett dat en Fehler geven +Comment[ne]=प्रोक्सी कन्फिगरेसन स्क्रिप्ट कार्यान्वयन गर्दा त्रुटि थियो +Comment[nl]=Er deed zich een fout voor tijdens het uitvoeren van het proxyconfiguratiescript +Comment[nn]=Feil ved køyring av skript for mellomtenaroppsett +Comment[pa]=ਪਰਾਕਸੀ ਸੰਰਚਨਾ ਸਕ੍ਰਿਪਟ ਚਲਾਉਣ ਵਿੱਚ ਗਲਤੀ ਆਈ ਹੈ +Comment[pl]=Wystąpił błąd w czasie wykonywania skryptu konfiguracji pośrednika +Comment[pt]=Ocorreu um erro ao efectuar a configuração do 'proxy' +Comment[pt_BR]=Ocorreu um erro ao executar o script de configuração do proxy. +Comment[ro]=A apărut o eroare la execuţia scriptului de configurare "proxy" +Comment[ru]=Ошибка при выполнении скрипта настройки прокси +Comment[rw]=Habaye ikosa mu gutangiza inyandikoporogaramu y'iboneza rya Nyabubasha +Comment[se]=Meattáhus vuojedettiin gaskabálváheivehanskripta +Comment[sk]=Vyskytla sa chyba počas spustenia konfiguračného skriptu proxy +Comment[sl]=Prišlo je do napake pri izvajanju nastavitvenega skripta posrednika +Comment[sq]=Është paraqitur një gabim gjatë ekzekutimit të skriptës për konfigurimin e proxy-t +Comment[sr]=Десила се грешка приликом извршавања скрипте за подешавање проксија +Comment[sr@Latn]=Desila se greška prilikom izvršavanja skripte za podešavanje proksija +Comment[sv]=Fel uppstod vid körning av proxyinställningsskriptet +Comment[ta]=பதிலாள் வடிவமைப்பு எழுத்தாக்கத்தை செயல்படுத்தும்போது ஒரு பிழை நேர்ந்தது +Comment[te]=ప్రాక్సీ రూపకరణపు స్క్రిప్ట్ నిర్వహణలొ దోషం వున్నది +Comment[tg]=Хато фаразани дар шакли дастнависи вакил кардашуда +Comment[th]=เกิดข้อผิดพลาดในการสั่งให้สคริปต์ปรับแต่งพร็อกซีทำงาน +Comment[tr]=Vekil sunucu yapılandırma dosyası çalıştırılamadı +Comment[tt]=Proxy caylaw ämerelegen eşlätkändä xata çıqtı +Comment[uk]=Виникла помилка при спробі виконати скрипт для визначення проксі сервера +Comment[uz]=Proksini moslash uchun skriptni ishga tushirishda xato roʻy berdi +Comment[uz@cyrillic]=Проксини мослаш учун скриптни ишга туширишда хато рўй берди +Comment[vi]=Gặp lỗi khi thực hiện tập lệnh cấu hình ủy nhiệm. +Comment[zh_CN]=执行代理配置脚本出现错误 +Comment[zh_HK]=代理伺服器組態檔案執行錯誤 +Comment[zh_TW]=proxy 代理組態檔案執行錯誤 +default_presentation=0 diff --git a/tdeio/misc/kpac/kpac_dhcp_helper.c b/tdeio/misc/kpac/kpac_dhcp_helper.c new file mode 100644 index 000000000..906e89dfa --- /dev/null +++ b/tdeio/misc/kpac/kpac_dhcp_helper.c @@ -0,0 +1,229 @@ +/* This file is part of the KDE Libraries + Copyright (c) 2001 Malte Starostik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dhcp.h" + +#ifndef INADDR_NONE /* some OSes don't define this */ +#define INADDR_NONE -1 +#endif + +int set_gid(gid_t); +int set_uid(uid_t); +int get_port(const char *); +int init_socket(void); +uint32_t send_request(int); +void get_reply(int, uint32_t); + +int set_gid(gid_t gid) +{ +#ifdef HAVE_SHORTSETGROUPS + short x[2]; + x[0] = gid; + x[1] = 73; /* catch errors */ + if (setgroups(1, x) == -1) + return -1; +#else + if (setgroups(1, &gid) == -1) + return -1; +#endif + return setgid(gid); /* _should_ be redundant, but on some systems it isn't */ +} + +int set_uid(uid_t uid) +{ + return setuid(uid); +} + +/* All functions below do an exit(1) on the slightest error */ + +/* Returns the UDP port number for the given service name */ +int get_port(const char *service) +{ + struct servent *serv = getservbyname(service, "udp"); + if (serv == NULL) + exit(1); + + return serv->s_port; +} + +/* Opens the UDP socket, binds to the bootpc port and drops root privileges */ +int init_socket() +{ + struct sockaddr_in addr; + struct protoent *proto; + int sock; + int bcast = 1; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = get_port("bootpc"); + + if ((proto = getprotobyname("udp")) == NULL || + (sock = socket(AF_INET, SOCK_DGRAM, proto->p_proto)) == -1) + exit(1); + + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast)) == -1 || + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &bcast, sizeof(bcast)) == -1 || + bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) + exit(1); + + if (set_gid(getgid()) != 0 || /* we don't need it anymore */ + set_uid(getuid()) != 0) + exit(1); + return sock; +} + +/* Fills the DHCPINFORM request packet, returns the transaction id */ +uint32_t send_request(int sock) +{ + char hostname[256]; + struct hostent *hent; + struct sockaddr_in addr; + struct dhcp_msg request; + uint8_t *offs = request.options; + + hostname[0] = '\0'; + hostname[255] = '\0'; + if (gethostname(hostname, 255) == -1 || + strlen(hostname) == 0 || + (hent = gethostbyname(hostname)) == NULL) + exit(1); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_NONE; + addr.sin_port = get_port("bootps"); + + memset(&request, 0, sizeof(request)); + request.op = DHCP_BOOTREQUEST; + srand(time(NULL)); + request.xid = rand(); + request.ciaddr = *(uint32_t*)*hent->h_addr_list; + + *offs++ = DHCP_MAGIC1; + *offs++ = DHCP_MAGIC2; + *offs++ = DHCP_MAGIC3; + *offs++ = DHCP_MAGIC4; + + *offs++ = DHCP_OPT_MSGTYPE; + *offs++ = 1; /* length */ + *offs++ = DHCP_INFORM; + + *offs++ = DHCP_OPT_PARAMREQ; + *offs++ = 1; /* length */ + *offs++ = DHCP_OPT_WPAD; + + *offs++ = DHCP_OPT_END; + + if (sendto(sock, &request, sizeof(request), 0, + (struct sockaddr *)&addr, sizeof(addr)) != sizeof(request)) + exit(1); + + return request.xid; +} + +/* Reads the reply from the socket, checks it and outputs the URL to STDOUT */ +void get_reply(int sock, uint32_t xid) +{ + struct dhcp_msg reply; + int len; + char wpad[DHCP_OPT_LEN + 1]; + uint8_t wpad_len; + uint8_t *offs = reply.options; + uint8_t *end; + + if ((len = recvfrom(sock, &reply, sizeof(reply), 0, NULL, NULL)) <= 0) + exit(1); + + end = (uint8_t *)&reply + len; + if (end < offs + 4 || + end > &reply.options[DHCP_OPT_LEN] || + reply.op != DHCP_BOOTREPLY || + reply.xid != xid || + *offs++ != DHCP_MAGIC1 || + *offs++ != DHCP_MAGIC2 || + *offs++ != DHCP_MAGIC3 || + *offs++ != DHCP_MAGIC4) + exit(1); + + for ( ; offs < end - 1; offs += *offs+1) + { + switch (*offs++) + { + case DHCP_OPT_END: + exit(1); + case DHCP_OPT_MSGTYPE: + if (*offs != 1 || (offs >= end - 1) || *(offs + 1) != DHCP_ACK) + exit(1); + break; + case DHCP_OPT_WPAD: + memset(wpad, 0, sizeof(wpad)); + wpad_len = *offs++; + if (offs >= end) + exit(1); + if (wpad_len > end - offs) + wpad_len = end - offs; + strncpy(wpad, (char *)offs, wpad_len); + wpad[wpad_len] = 0; + printf("%s\n", wpad); + close(sock); + exit(0); + } + } + exit(1); +} + +int main() +{ + fd_set rfds; + struct timeval tv; + int sock; + uint32_t xid; + + sock = init_socket(); + xid = send_request(sock); + + FD_ZERO(&rfds); + FD_SET(sock, &rfds); + tv.tv_sec = 5; + tv.tv_usec = 0; + if (select(sock + 1, &rfds, NULL, NULL, &tv) == 1 && FD_ISSET(sock, &rfds)) + get_reply(sock, xid); + + close(sock); + exit(1); +} + +/* vim: ts=4 sw=4 noet + */ diff --git a/tdeio/misc/kpac/kpactest.pac b/tdeio/misc/kpac/kpactest.pac new file mode 100644 index 000000000..69e5aaad7 --- /dev/null +++ b/tdeio/misc/kpac/kpactest.pac @@ -0,0 +1,169 @@ +// This is a script to test KPAC. +// To use it: set this script as proxy config file and run +// dcop kded proxyscout proxyForURL http://blah (URL doesn't matter) +// The answer must be http:/// +// If you see "failed" in the output, lookup the test name in the comments +// below and let me now at or try to fix it yourself + +function FindProxyForURL( url, host ) +{ + var result = "PROXY http://" + myIPAddress(); + + // plainhost1 + if ( !isPlainHostName( "foo" ) ) + result += "/plainhost1=failed" + // plainhost2 + if ( isPlainHostName( "foo.bar" ) ) + result += "/plainhost2=failed"; + + // dnsdomain1 + if ( !dnsDomainIs( "foo.bar", "bar" ) ) + result += "/dnsdomain1=failed"; + // dnsdomain2 + if ( dnsDomainIs( "foo.baz", "bar" ) ) + result += "/dnsdomain2=failed"; + + // localordomain1 + if ( !localHostOrDomainIs( "foo", "bar" ) ) + result += "/localordomain1=failed"; + // localordomain2 + if ( !localHostOrDomainIs( "foo.bar", "foo.bar" ) ) + result += "/localordomain2=failed"; + // localordomain3 + if ( !localHostOrDomainIs( "foo", "foo.baz" ) ) + result += "/localordomain3=failed"; + // localordomain4 + if ( localHostOrDomainIs( "foo.bar", "foo.baz" ) ) + result += "/localordomain4=failed"; + + // isresolvable1 + // on failure make sure you can resolve www.kde.org correctly :-) + if ( !isResolvable( "www.kde.org" ) ) result += "/isresolvable1=failed"; + // isresolvable2 + // on failure make sure dummy.invalid doesn't resolve :-) + if ( isResolvable( "dummy.invalid" ) ) result += "/isresolvable2=failed"; + + // isinnet1 + // on failure check if localhost resolves to 127.0.0.1 as it should + if ( isInNet( "localhost", "1.2.3.4", "255.0.0.0" ) ) + result += "/isinnet1=failed"; + // isinnet2 + if ( isInNet( "1.2.3.4", "1.2.3.5", "255.255.255.255" ) ) + result += "/isinnet2=failed"; + // isinnet3 + if ( !isInNet( "1.2.3.4", "1.2.3.5", "255.255.255.0" ) ) + result += "/isinnet3=failed"; + + // dnsresolve1 + // on failure check if localhost resolves to 127.0.0.1 as it should + if ( dnsResolve( "localhost" ) != "127.0.0.1" ) + result += "/dnsresolve1=failed"; + + // dnslevels1 + if ( dnsDomainLevels( "foo" ) != 0 ) + result += "/dnslevels1=failed"; + // dnslevels2 + if ( dnsDomainLevels( "foo.bar" ) != 1 ) + result += "/dnslevels2=failed"; + // dnslevels3 + if ( dnsDomainLevels( "foo.bar.baz" ) != 2 ) + result += "/dnslevels3=failed"; + + // shexp1 + if ( !shExpMatch( "foobar", "foobar" ) ) + result += "/shexp1=failed"; + // shexp2 + if ( shExpMatch( "FoObAr", "foobar" ) ) + result += "/shexp2=failed"; + // shexp3 + if ( !shExpMatch( "Foobar", "?oobar" ) ) + result += "/shexp3=failed"; + // shexp4 + if ( !shExpMatch( "FoObAr", "*b*" ) ) + result += "/shexp4=failed"; + // shexp5 + if ( shExpMatch( "FoObAr", "*x*" ) ) + result += "/shexp5=failed"; + // shexp6 + if ( shExpMatch( "www.kde.org", "*.kde" ) ) + result += "/shexp6=failed"; + + var now = new Date; + var days = new Array( "sun", "mon", "tue", "wed", "thu", "fri", "sat" ); + var months = new Array( "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec" ); + + // weekday1 + if ( !weekdayRange( "sun", "sat" ) ) + result += "/weekday1=failed"; + // weekday2 + if ( !weekdayRange( "sat", "sun" ) ) + result += "/weekday2=failed"; + // weekday3 + if ( !weekdayRange( days[ now.getDay() ] ) ) + result += "/weekday3=failed"; + // weekday4 + if ( weekdayRange( now.getDay() ? "sun" : "mon" ) ) + result += "/weekday4=failed"; + + // date1 + if ( !dateRange( now.getDate() ) ) + result += "/date1=failed"; + // date2 + if ( !dateRange( now.getDate(), 31 ) ) + result += "/date2=failed"; + // date3 + if ( !dateRange( 1, now.getDate() ) ) + result += "/date3=failed"; + // date4 + if ( dateRange( now.getDay() > 5 ? 1 : 6, now.getDay() > 5 ? 3 : 8 ) ) + result += "/date4=failed"; + // date5 + if ( !dateRange( months[ now.getMonth() ] ) ) + result += "/date5=failed"; + // date6 + if ( !dateRange( months[ now.getMonth() ], "dec" ) ) + result += "/date6=failed"; + // date7 + if ( !dateRange( "dec", months[ now.getMonth() ] ) ) + result += "/date7=failed"; + // date8 + if ( !dateRange( now.getFullYear() ) ) + result += "/date8=failed"; + // date9 + if ( dateRange( now.getFullYear() - 1 ) ) + result += "/date9=failed"; + // date10 + // if this fails, check your clock first :-) + if ( dateRange( 1, "jan", 1990, 31, "dec", 2000 ) ) + result += "/date10=failed"; + // date11 + // if this fails, check your clock first :-) + if ( !dateRange( 1, "jan", 2000, 31, "dec", 3000 ) ) + result += "/date11=failed"; + + // time1 + if ( !timeRange( now.getHours() ) ) + result += "/time1=failed"; + // time2 + if ( !timeRange( now.getHours(), now.getMinutes(), 0, 0 ) ) + result += "/time2=failed"; + // time3 + if ( !timeRange( now.getHours(), now.getMinutes(), now.getSeconds(), 0, 0, 0 ) ) + result += "/time3=failed"; + // time4 + if ( timeRange( now.getHours() > 5 ? 1 : 6, now.getHours() > 5 ? 3 : 8 ) ) + result += "/time4=failed"; + // time5 + if ( now.getHours() == now.getUTCHours() ) + result += "/time5=skipped"; + else if ( timeRange( now.getUTCHours() ) ) + result += "/time5=failed"; + // time6 + if ( now.getHours() == now.getUTCHours() ) + result += "/time6=skipped"; + else if ( !timeRange( now.getUTCHours(), "GMT" ) ) + result += "/time6=failed"; + + return result; +} + diff --git a/tdeio/misc/kpac/proxyscout.cpp b/tdeio/misc/kpac/proxyscout.cpp new file mode 100644 index 000000000..b651e2313 --- /dev/null +++ b/tdeio/misc/kpac/proxyscout.cpp @@ -0,0 +1,196 @@ +/* + Copyright (c) 2003 Malte Starostik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#include +#include + +#include +#include +#include +#include +#include + +#include "proxyscout.moc" +#include "discovery.h" +#include "script.h" + +namespace KPAC +{ + ProxyScout::QueuedRequest::QueuedRequest( const KURL& u ) + : transaction( kapp->dcopClient()->beginTransaction() ), + url( u ) + { + } + + ProxyScout::ProxyScout( const TQCString& name ) + : KDEDModule( name ), + m_instance( new TDEInstance( "proxyscout" ) ), + m_downloader( 0 ), + m_script( 0 ), + m_suspendTime( 0 ) + { + } + + ProxyScout::~ProxyScout() + { + delete m_script; + delete m_instance; + } + + TQString ProxyScout::proxyForURL( const KURL& url ) + { + if ( m_suspendTime ) + { + if ( std::time( 0 ) - m_suspendTime < 300 ) return "DIRECT"; + m_suspendTime = 0; + } + + // Never use a proxy for the script itself + if ( m_downloader && url.equals( m_downloader->scriptURL(), true ) ) return "DIRECT"; + + if ( m_script ) return handleRequest( url ); + + if ( m_downloader || startDownload() ) + { + m_requestQueue.append( url ); + return TQString::null; + } + else return "DIRECT"; + } + + ASYNC ProxyScout::blackListProxy( const TQString& proxy ) + { + m_blackList[ proxy ] = std::time( 0 ); + } + + ASYNC ProxyScout::reset() + { + delete m_script; + m_script = 0; + delete m_downloader; + m_downloader = 0; + m_blackList.clear(); + m_suspendTime = 0; + KProtocolManager::reparseConfiguration(); + } + + bool ProxyScout::startDownload() + { + switch ( KProtocolManager::proxyType() ) + { + case KProtocolManager::WPADProxy: + m_downloader = new Discovery( this ); + break; + case KProtocolManager::PACProxy: + m_downloader = new Downloader( this ); + m_downloader->download( KURL( KProtocolManager::proxyConfigScript() ) ); + break; + default: + return false; + } + connect( m_downloader, TQT_SIGNAL( result( bool ) ), + TQT_SLOT( downloadResult( bool ) ) ); + return true; + } + + void ProxyScout::downloadResult( bool success ) + { + KNotifyClient::Instance notifyInstance( m_instance ); + if ( success ) + try + { + m_script = new Script( m_downloader->script() ); + } + catch ( const Script::Error& e ) + { + KNotifyClient::event( "script-error", i18n( + "The proxy configuration script is invalid:\n%1" ) + .arg( e.message() ) ); + success = false; + } + else KNotifyClient::event( "download-error", m_downloader->error() ); + + for ( RequestQueue::ConstIterator it = m_requestQueue.begin(); + it != m_requestQueue.end(); ++it ) + { + TQCString type = TQSTRING_OBJECT_NAME_STRING; + TQByteArray data; + TQDataStream ds( data, IO_WriteOnly ); + if ( success ) ds << handleRequest( ( *it ).url ); + else ds << TQString( "DIRECT" ); + kapp->dcopClient()->endTransaction( ( *it ).transaction, type, data ); + } + m_requestQueue.clear(); + m_downloader->deleteLater(); + m_downloader = 0; + // Suppress further attempts for 5 minutes + if ( !success ) m_suspendTime = std::time( 0 ); + } + + TQString ProxyScout::handleRequest( const KURL& url ) + { + try + { + TQString result = m_script->evaluate( url ); + TQStringList proxies = TQStringList::split( ';', result ); + for ( TQStringList::ConstIterator it = proxies.begin(); + it != proxies.end(); ++it ) + { + TQString proxy = ( *it ).stripWhiteSpace(); + if ( proxy.left( 5 ) == "PROXY" ) + { + KURL proxyURL( proxy = proxy.mid( 5 ).stripWhiteSpace() ); + // If the URL is invalid or the URL is valid but in opaque + // format which indicates a port number being present in + // this particular case, simply calling setProtocol() on + // it trashes the whole URL. + int len = proxyURL.protocol().length(); + if ( !proxyURL.isValid() || proxy.find( ":/", len ) != len ) + proxy.prepend("http://"); + BlackList::Iterator it = m_blackList.find( proxy ); + if ( it == m_blackList.end() ) return proxy; + else if ( std::time( 0 ) - *it > 1800 ) // 30 minutes + { + // black listing expired + m_blackList.remove( it ); + return proxy; + } + } + else return "DIRECT"; + } + // FIXME: blacklist + } + catch ( const Script::Error& e ) + { + KNotifyClient::Instance notifyInstance( m_instance ); + KNotifyClient::event( "evaluation-error", i18n( + "The proxy configuration script returned an error:\n%1" ) + .arg( e.message() ) ); + } + return "DIRECT"; + } + + extern "C" KDE_EXPORT KDEDModule* create_proxyscout( const TQCString& name ) + { + return new ProxyScout( name ); + } +} + +// vim: ts=4 sw=4 et diff --git a/tdeio/misc/kpac/proxyscout.desktop b/tdeio/misc/kpac/proxyscout.desktop new file mode 100644 index 000000000..02e402b50 --- /dev/null +++ b/tdeio/misc/kpac/proxyscout.desktop @@ -0,0 +1,131 @@ +[Desktop Entry] +Type=Service +Name=Proxy Scout +Name[af]=Proksie Verkenner +Name[az]=Vəkil Skout +Name[bg]=Проучване на прокси сървъри +Name[bn]=প্রক্সি স্কাউট +Name[ca]=Explorador del servidor intermedi +Name[cs]=Proxy vyhledávač +Name[csb]=Pòstrzédnik (proxy) +Name[cy]=Arweinydd Dirprwy +Name[de]=Automatische Proxy-Einrichtung +Name[el]=Διαμεσολαβητής Scout +Name[eo]=Prokurilo +Name[es]=Explorador del proxy +Name[fa]=پیشکار Scout +Name[fi]=Proxy-tiedustelija +Name[fy]=Proxy ferkenner +Name[gl]=Proxy Explorador +Name[he]=מחפש שרתי Proxy +Name[hi]= प्रॉक्सी स्काउट +Name[hr]=Proxy izvidnik +Name[is]=Milliþjóns leitari +Name[it]=Esploratore proxy +Name[ja]=プロキシを探す +Name[ka]=პროქსის თვითგამართვა +Name[kk]=Проксиді автобапату +Name[ko]=프록시 찾기 +Name[lb]=Proxy-Scout +Name[lt]=Proxy paieška +Name[mk]=Прокси скаут +Name[mn]=Итгэмжилэгчийн зам хайгч +Name[ms]=Scout Proksi +Name[nb]=Mellomtjenerspeiding +Name[ne]=प्रोक्सी स्काउट +Name[nn]=Mellomtenarspeiding +Name[pa]=ਪਰਾਕਸੀ ਸਕਾਊਟ +Name[pl]=Pośrednik (proxy) +Name[pt]=Escuteiro do 'Proxy' +Name[pt_BR]=Saída do Proxy +Name[ru]=Автонастройка прокси +Name[rw]=Igifasha Nyabubasha +Name[se]=Gaskabálvaohci +Name[sk]=Prieskumník proxy +Name[sr]=Прокси извиђач +Name[sr@Latn]=Proksi izviđač +Name[sv]=Proxy-scout +Name[ta]=பதிலாள் தேடு +Name[te]=ప్రాక్సీ వేగు +Name[tg]=Разведкачӣ Вакил Кардашуда +Name[tr]=Vekil Sunucu +Name[tt]=Proxy Saqçısı +Name[uk]=Розвідник проксі сервера +Name[uz]=Proksi skaut +Name[uz@cyrillic]=Прокси скаут +Name[zh_CN]=代理搜索 +Comment=Automatic proxy configuration +Comment[af]=Outomatiese proksie opstelling +Comment[bg]=Автоматично настройване на прокси сървъра +Comment[bn]=স্বয়ংক্রিয় প্রক্সি কনফিগারেশন +Comment[br]=Kefluniadur emgefreekh ar proksi +Comment[bs]=Automatsko podešavanje proxy-ja +Comment[ca]=Configuració automàtica de l'intermediari +Comment[cs]=Automatické nastavení proxy +Comment[csb]=Aòtokònfigùracëjô pòstrzédnika +Comment[cy]=Ffurweddiad Awtomatig o'r Dirprwy +Comment[da]=Automatisk proxy-indstilling +Comment[de]=Sucht nach einem Proxy-Server und richtet ihn ein +Comment[el]=Αυτόματη ρύθμιση διαμεσολαβητή +Comment[eo]=Aŭtomata Prokuragordo +Comment[es]=Configuración automática del Proxy +Comment[et]=Automaatne proxy konfigureerimine +Comment[eu]=Proxy-aren konfigurazio automatikoa +Comment[fa]=پیکربندی خودکار پیشکار +Comment[fi]=Automaattiset proxy-asetukset +Comment[fr]=Configuration automatique du serveur mandataire +Comment[fy]=Automatyske proxy ynstelling +Comment[ga]=Uathchumraíocht an tseachfhreastalaí +Comment[gl]=Configuración Automática do Proxi +Comment[he]=הגדרות מתווך אוטומטיות +Comment[hi]=स्वचालित प्रॉक्सी कॉन्फ़िगरेशन +Comment[hr]=Automatsko konfiguriranje proxyja +Comment[hu]=Automatikus proxybeállítás +Comment[id]=Konfigurasi proxi otomatis +Comment[is]=Sjálfvirkar stillingar milliþjóns +Comment[it]=Configurazione automatica proxy +Comment[ja]=自動プロキシ設定 +Comment[ka]=პროქსის თვითგამართვა +Comment[kk]=Проксиді автоматты түрде бапату +Comment[km]=ការ​កំណត់​រចនាសម្ព័ន្ធ​ប្រូកស៊ី​ដោយ​ស្វ័យប្រវត្តិ +Comment[lb]=Automatesch Proxy-Configuratioun +Comment[lt]=Automatinis proxy derinimas +Comment[mk]=Автоматска конфигурација на прокси +Comment[ms]=Penyelarasan Proksi Automatik +Comment[nb]=Automatisk mellomtjeneroppsett +Comment[nds]=Proxy automaatsch instellen +Comment[ne]=स्वचालित प्रोक्सी कन्फिगरेसन +Comment[nl]=Automatische proxyconfiguratie +Comment[nn]=Automatisk mellomtenaroppsett +Comment[pa]=ਸਵੈ-ਚਾਲਿਤ ਪਰਾਕਸੀ ਸੰਰਚਨਾ +Comment[pl]=Autokonfiguracja pośrednika +Comment[pt]=Configuração automática de 'proxy' +Comment[pt_BR]=Configuração automática do proxy +Comment[ro]=Configurare automată pentru proxy +Comment[ru]=Автонастройка прокси-сервера +Comment[rw]=Iboneza rya Nyabubasha Yikoresha +Comment[se]=Automáhtalaš gaskabálváheiveheapmi +Comment[sk]=Automatická konfigurácia proxy +Comment[sl]=Samodejne nastavitve posrednika +Comment[sr]=Аутоматско подешавање проксија +Comment[sr@Latn]=Automatsko podešavanje proksija +Comment[sv]=Automatisk proxyinställning +Comment[ta]=தானியக்க பதிலாள் வடிவமைப்பு +Comment[te]=స్వయంచాలక ప్రాక్సీ రూపకరణం +Comment[tg]=Танзими прокси бо автоматикӣ +Comment[th]=การปรับแต่งพร็อกซีอัตโนมัติ +Comment[tr]=Otomatik vekil sunucu yapılandırması +Comment[tt]=Proxy'nıñ üzzihenle caylanu +Comment[uk]=Автоматичне визначення проксі сервера +Comment[uz]=Proksini avtomatik ravishda moslash +Comment[uz@cyrillic]=Проксини автоматик равишда мослаш +Comment[vi]=Cấu hình ủy nhiệm tự động. +Comment[zh_CN]=自动代理配置 +Comment[zh_HK]=自動代理伺服器組態 +Comment[zh_TW]=自動代理組態 +ServiceTypes=KDEDModule +X-TDE-ModuleType=Library +X-TDE-Library=proxyscout +X-TDE-FactoryName=proxyscout +X-TDE-Kded-autoload=false +X-TDE-Kded-load-on-demand=true diff --git a/tdeio/misc/kpac/proxyscout.h b/tdeio/misc/kpac/proxyscout.h new file mode 100644 index 000000000..78c8fc237 --- /dev/null +++ b/tdeio/misc/kpac/proxyscout.h @@ -0,0 +1,82 @@ +/* + Copyright (c) 2003 Malte Starostik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#ifndef KPAC_PROXYSCOUT_H +#define KPAC_PROXYSCOUT_H + +#include + +#include +#include + +#include + +class DCOPClientTransaction; +class TDEInstance; + +namespace KPAC +{ + class Downloader; + class Script; + + class ProxyScout : public KDEDModule + { + Q_OBJECT + K_DCOP + public: + ProxyScout( const TQCString& ); + virtual ~ProxyScout(); + + k_dcop: + TQString proxyForURL( const KURL& url ); + ASYNC blackListProxy( const TQString& proxy ); + ASYNC reset(); + + private slots: + void downloadResult( bool ); + + private: + bool startDownload(); + TQString handleRequest( const KURL& url ); + + TDEInstance* m_instance; + Downloader* m_downloader; + Script* m_script; + + struct QueuedRequest + { + QueuedRequest() : transaction( 0 ) {} + QueuedRequest( const KURL& ); + + DCOPClientTransaction* transaction; + KURL url; + }; + typedef TQValueList< QueuedRequest > RequestQueue; + RequestQueue m_requestQueue; + + typedef TQMap< TQString, time_t > BlackList; + BlackList m_blackList; + time_t m_suspendTime; + }; +} + +#endif // KPAC_PROXYSCOUT_H + +// vim: ts=4 sw=4 et diff --git a/tdeio/misc/kpac/script.cpp b/tdeio/misc/kpac/script.cpp new file mode 100644 index 000000000..55faef8a1 --- /dev/null +++ b/tdeio/misc/kpac/script.cpp @@ -0,0 +1,465 @@ +/* + Copyright (c) 2003 Malte Starostik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "script.h" + +using namespace KJS; + +TQString UString::qstring() const +{ + return TQString( reinterpret_cast< const TQChar* >( data() ), size() ); +} + +UString::UString( const TQString &s ) +{ + UChar* data = new UChar[ s.length() ]; + std::memcpy( data, s.unicode(), s.length() * sizeof( UChar ) ); + rep = Rep::create( data, s.length() ); +} + +namespace +{ + class Address + { + public: + struct Error {}; + static Address resolve( const UString& host ) + { return Address( host.qstring(), false ); } + static Address parse( const UString& ip ) + { return Address( ip.qstring(), true ); } + + operator in_addr_t() const { + const sockaddr_in* sin = m_address; + return sin->sin_addr.s_addr; + } + + operator String() const { return String( m_address.ipAddress().toString() ); } + + private: + Address( const TQString& host, bool numeric ) + { + int flags = 0; + + if ( numeric ) + flags = KNetwork::KResolver::NoResolve; + + KNetwork::KResolverResults addresses = + KNetwork::KResolver::resolve( host, TQString::null, flags, + KNetwork::KResolver::IPv4Family ); + + if ( addresses.isEmpty() ) + throw Error(); + + m_address = addresses.first().address().asInet(); + } + + KNetwork::KInetSocketAddress m_address; + }; + + struct Function : public ObjectImp + { + struct ResolveError {}; + + virtual bool implementsCall() const { return true; } + + static int findString( const UString& s, const char* const* values ) + { + int index = 0; + UString lower = s.toLower(); + for ( const char* const* p = values; *p; ++p, ++index ) + if ( lower == *p ) return index; + return -1; + } + + static const tm* getTime( ExecState* exec, const List& args ) + { + time_t now = std::time( 0 ); + if ( args[ args.size() - 1 ].toString( exec ).toLower() == "gmt" ) + return std::gmtime( &now ); + else return std::localtime( &now ); + } + + Boolean checkRange( int value, int min, int max ) + { + return ( min <= max && value >= min && value <= max ) || + ( min > max && ( value <= min || value >= max ) ); + } + }; + + // isPlainHostName( host ) + // @returns true if @p host doesn't contains a domain part + struct IsPlainHostName : public Function + { + virtual Value call( ExecState* exec, Object&, const List& args ) + { + if ( args.size() != 1 ) return Undefined(); + return Boolean( args[ 0 ].toString( exec ).find( "." ) == -1 ); + } + }; + + // dnsDomainIs( host, domain ) + // @returns true if the domain part of @p host matches @p domain + struct DNSDomainIs : public Function + { + virtual Value call( ExecState* exec, Object&, const List& args ) + { + if ( args.size() != 2 ) return Undefined(); + TQString host = args[ 0 ].toString( exec ).qstring().lower(); + TQString domain = args[ 1 ].toString( exec ).qstring().lower(); + return Boolean( host.endsWith( domain ) ); + } + }; + + // localHostOrDomainIs( host, fqdn ) + // @returns true if @p host is unqualified or equals @p fqdn + struct LocalHostOrDomainIs : public Function + { + virtual Value call( ExecState* exec, Object&, const List& args ) + { + if ( args.size() != 2 ) return Undefined(); + UString host = args[ 0 ].toString( exec ).toLower(); + if ( host.find( "." ) == -1 ) return Boolean( true ); + UString fqdn = args[ 1 ].toString( exec ).toLower(); + return Boolean( host == fqdn ); + } + }; + + // isResolvable( host ) + // @returns true if host can be resolved via DNS + struct IsResolvable : public Function + { + virtual Value call( ExecState* exec, Object&, const List& args ) + { + if ( args.size() != 1 ) return Undefined(); + try { ::Address::resolve( args[ 0 ].toString( exec ) ); } + catch ( const Address::Error& ) { return Boolean( false ); } + return Boolean( true ); + } + }; + + // isInNet( host, subnet, mask ) + // @returns true if @p host is within the IP subnet + // specified via @p subnet and @p mask + struct IsInNet : public Function + { + virtual Value call( ExecState* exec, Object&, const List& args ) + { + if ( args.size() != 3 ) return Undefined(); + try + { + in_addr_t host = Address::resolve( args[ 0 ].toString( exec ) ); + in_addr_t subnet = Address::parse( args[ 1 ].toString( exec ) ); + in_addr_t mask = Address::parse( args[ 2 ].toString( exec ) ); + return Boolean( ( host & mask ) == ( subnet & mask ) ); + } + catch ( const Address::Error& ) + { + return Undefined(); + } + } + }; + + // dnsResolve( host ) + // @returns the IP address of @p host in dotted quad notation + struct DNSResolve : public Function + { + virtual Value call( ExecState* exec, Object&, const List& args ) + { + if ( args.size() != 1 ) return Undefined(); + try { return String(Address::resolve( args[ 0 ].toString( exec ))); } + catch ( const Address::Error& ) { return Undefined(); } + } + }; + + // myIpAddress() + // @returns the local machine's IP address in dotted quad notation + struct MyIpAddress : public Function + { + virtual Value call( ExecState*, Object&, const List& args ) + { + if ( args.size() ) return Undefined(); + char hostname[ 256 ]; + gethostname( hostname, 255 ); + hostname[ 255 ] = 0; + try { return String(Address::resolve( hostname )); } + catch ( const Address::Error& ) { return Undefined(); } + } + }; + + // dnsDomainLevels( host ) + // @returns the number of dots ('.') in @p host + struct DNSDomainLevels : public Function + { + virtual Value call( ExecState* exec, Object&, const List& args ) + { + if ( args.size() != 1 ) return Undefined(); + UString host = args[ 0 ].toString( exec ); + if ( host.isNull() ) return Number( 0 ); + return Number( std::count( + host.data(), host.data() + host.size(), '.' ) ); + } + }; + + // shExpMatch( str, pattern ) + // @returns true if @p str matches the shell @p pattern + struct ShExpMatch : public Function + { + virtual Value call( ExecState* exec, Object&, const List& args ) + { + if ( args.size() != 2 ) return Undefined(); + TQRegExp pattern( args[ 1 ].toString( exec ).qstring(), true, true ); + return Boolean( pattern.exactMatch(args[ 0 ].toString( exec ).qstring()) ); + } + }; + + // weekdayRange( day [, "GMT" ] ) + // weekdayRange( day1, day2 [, "GMT" ] ) + // @returns true if the current day equals day or between day1 and day2 resp. + // If the last argument is "GMT", GMT timezone is used, otherwise local time + struct WeekdayRange : public Function + { + virtual Value call( ExecState* exec, Object&, const List& args ) + { + if ( args.size() < 1 || args.size() > 3 ) return Undefined(); + static const char* const days[] = + { "sun", "mon", "tue", "wed", "thu", "fri", "sat", 0 }; + int d1 = findString( args[ 0 ].toString( exec ), days ); + if ( d1 == -1 ) return Undefined(); + + int d2 = findString( args[ 1 ].toString( exec ), days ); + if ( d2 == -1 ) d2 = d1; + return checkRange( getTime( exec, args )->tm_wday, d1, d2 ); + } + }; + + // dateRange( day [, "GMT" ] ) + // dateRange( day1, day2 [, "GMT" ] ) + // dateRange( month [, "GMT" ] ) + // dateRange( month1, month2 [, "GMT" ] ) + // dateRange( year [, "GMT" ] ) + // dateRange( year1, year2 [, "GMT" ] ) + // dateRange( day1, month1, day2, month2 [, "GMT" ] ) + // dateRange( month1, year1, month2, year2 [, "GMT" ] ) + // dateRange( day1, month1, year1, day2, month2, year2 [, "GMT" ] ) + // @returns true if the current date (GMT or local time according to + // presence of "GMT" as last argument) is within the given range + struct DateRange : public Function + { + virtual Value call( ExecState* exec, Object&, const List& args ) + { + if ( args.size() < 1 || args.size() > 7 ) return Undefined(); + static const char* const months[] = + { "jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "nov", "dec", 0 }; + + std::vector< int > values; + for ( int i = 0; i < args.size(); ++i ) + { + int value = -1; + if ( args[ i ].isA( NumberType ) ) + value = args[ i ].toInteger( exec ); + else value = findString( args[ i ].toString( exec ), months ); + if ( value >= 0 ) values.push_back( value ); + else break; + } + + const tm* now = getTime( exec, args ); + + // day1, month1, year1, day2, month2, year2 + if ( values.size() == 6 ) + return checkRange( ( now->tm_year + 1900 ) * 372 + now->tm_mon * 31 + now->tm_mday, + values[ 2 ] * 372 + values[ 1 ] * 31 + values[ 0 ], + values[ 5 ] * 372 + values[ 4 ] * 31 + values[ 3 ] ); + + // day1, month1, day2, month2 + else if ( values.size() == 4 && + values[ 1 ] < 12 && + values[ 3 ] < 12 ) + return checkRange( now->tm_mon * 31 + now->tm_mday, + values[ 1 ] * 31 + values[ 0 ], + values[ 3 ] * 31 + values[ 2 ] ); + + // month1, year1, month2, year2 + else if ( values.size() == 4 ) + return checkRange( ( now->tm_year + 1900 ) * 12 + now->tm_mon, + values[ 1 ] * 12 + values[ 0 ], + values[ 3 ] * 12 + values[ 2 ] ); + + // year1, year2 + else if ( values.size() == 2 && + values[ 0 ] >= 1000 && + values[ 1 ] >= 1000 ) + return checkRange( now->tm_year + 1900, values[ 0 ], values[ 1 ] ); + + // day1, day2 + else if ( values.size() == 2 && + args[ 0 ].isA( NumberType ) && + args[ 1 ].isA( NumberType ) ) + return checkRange( now->tm_mday, values[ 0 ], values[ 1 ] ); + + // month1, month2 + else if ( values.size() == 2 ) + return checkRange( now->tm_mon, values[ 0 ], values[ 1 ] ); + + // year + else if ( values.size() == 1 && values[ 0 ] >= 1000 ) + return checkRange( now->tm_year + 1900, values[ 0 ], values[ 0 ] ); + + // day + else if ( values.size() == 1 && args[ 0 ].isA( NumberType ) ) + return checkRange( now->tm_mday, values[ 0 ], values[ 0 ] ); + + // month + else if ( values.size() == 1 ) + return checkRange( now->tm_mon, values[ 0 ], values[ 0 ] ); + + else return Undefined(); + } + }; + + // timeRange( hour [, "GMT" ] ) + // timeRange( hour1, hour2 [, "GMT" ] ) + // timeRange( hour1, min1, hour2, min2 [, "GMT" ] ) + // timeRange( hour1, min1, sec1, hour2, min2, sec2 [, "GMT" ] ) + // @returns true if the current time (GMT or local based on presence + // of "GMT" argument) is within the given range + struct TimeRange : public Function + { + virtual Value call( ExecState* exec, Object&, const List& args ) + { + if ( args.size() < 1 || args.size() > 7 ) return Undefined(); + + std::vector< int > values; + for ( int i = 0; i < args.size(); ++i ) + if ( args[ i ].isA( NumberType ) ) + values.push_back( args[ i ].toInteger( exec ) ); + else break; + + const tm* now = getTime( exec, args ); + + // hour1, min1, sec1, hour2, min2, sec2 + if ( values.size() == 6 ) + return checkRange( now->tm_hour * 3600 + now->tm_min * 60 + now->tm_sec, + values[ 0 ] * 3600 + values[ 1 ] * 60 + values[ 2 ], + values[ 3 ] * 3600 + values[ 4 ] * 60 + values[ 5 ] ); + + // hour1, min1, hour2, min2 + else if ( values.size() == 4 ) + return checkRange( now->tm_hour * 60 + now->tm_min, + values[ 0 ] * 60 + values[ 1 ], + values[ 2 ] * 60 + values[ 3 ] ); + + // hour1, hour2 + else if ( values.size() == 2 ) + return checkRange( now->tm_hour, values[ 0 ], values[ 1 ] ); + + // hour + else if ( values.size() == 1 ) + return checkRange( now->tm_hour, values[ 0 ], values[ 0 ] ); + + else return Undefined(); + } + }; + + void registerFunctions( ExecState* exec, Object& global ) + { + global.put( exec, "isPlainHostName", + Object( new IsPlainHostName ) ); + global.put( exec, "dnsDomainIs", + Object( new DNSDomainIs ) ); + global.put( exec, "localHostOrDomainIs", + Object( new LocalHostOrDomainIs ) ); + global.put( exec, "isResolvable", + Object( new IsResolvable ) ); + global.put( exec, "isInNet", + Object( new IsInNet ) ); + global.put( exec, "dnsResolve", + Object( new DNSResolve ) ); + global.put( exec, "myIpAddress", + Object( new MyIpAddress ) ); + global.put( exec, "dnsDomainLevels", + Object( new DNSDomainLevels ) ); + global.put( exec, "shExpMatch", + Object( new ShExpMatch ) ); + global.put( exec, "weekdayRange", + Object( new WeekdayRange ) ); + global.put( exec, "dateRange", + Object( new DateRange ) ); + global.put( exec, "timeRange", + Object( new TimeRange ) ); + } +} + +namespace KPAC +{ + Script::Script( const TQString& code ) + { + ExecState* exec = m_interpreter.globalExec(); + Object global = m_interpreter.globalObject(); + registerFunctions( exec, global ); + + Completion result = m_interpreter.evaluate( code ); + if ( result.complType() == Throw ) + throw Error( result.value().toString( exec ).qstring() ); + } + + TQString Script::evaluate( const KURL& url ) + { + ExecState *exec = m_interpreter.globalExec(); + Value findFunc = m_interpreter.globalObject().get( exec, "FindProxyForURL" ); + Object findObj = Object::dynamicCast( findFunc ); + if (!findObj.isValid() || !findObj.implementsCall()) + throw Error( "No such function FindProxyForURL" ); + + Object thisObj; + List args; + args.append(String(url.url())); + args.append(String(url.host())); + Value retval = findObj.call( exec, thisObj, args ); + + if ( exec->hadException() ) { + Value ex = exec->exception(); + exec->clearException(); + throw Error( ex.toString( exec ).qstring() ); + } + + return retval.toString( exec ).qstring(); + } +} + +// vim: ts=4 sw=4 et diff --git a/tdeio/misc/kpac/script.h b/tdeio/misc/kpac/script.h new file mode 100644 index 000000000..49ba0b6a3 --- /dev/null +++ b/tdeio/misc/kpac/script.h @@ -0,0 +1,56 @@ +/* + Copyright (c) 2003 Malte Starostik + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#ifndef KPAC_SCRIPT_H +#define KPAC_SCRIPT_H + +#include + +#include + +class KURL; + +namespace KPAC +{ + class Script + { + public: + class Error + { + public: + Error( const TQString& message ) + : m_message( message ) {} + const TQString& message() const { return m_message; } + + private: + TQString m_message; + }; + + Script( const TQString& code ); + TQString evaluate( const KURL& ); + + private: + KJS::Interpreter m_interpreter; + }; +} + +#endif // KPAC_SCRIPT_H + +// vim: ts=4 sw=4 et diff --git a/tdeio/misc/kssld/CMakeLists.txt b/tdeio/misc/kssld/CMakeLists.txt new file mode 100644 index 000000000..813ce44f0 --- /dev/null +++ b/tdeio/misc/kssld/CMakeLists.txt @@ -0,0 +1,47 @@ +################################################# +# +# (C) 2010 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${TQT_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdeio/kssl + ${CMAKE_BINARY_DIR}/tdecore + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/dcop + ${CMAKE_SOURCE_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdeio/kssl +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install(FILES kssld.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded ) + + +##### kded_kssld ########################### + +set( target kded_kssld ) + +set( ${target}_SRCS + kssld.cpp kssld.skel +) + +tde_add_kpart( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK tdeinit_kded-shared + DEPENDENCIES dcopidl + DESTINATION ${PLUGIN_INSTALL_DIR} +) diff --git a/tdeio/misc/kssld/Makefile.am b/tdeio/misc/kssld/Makefile.am new file mode 100644 index 000000000..09ddfe440 --- /dev/null +++ b/tdeio/misc/kssld/Makefile.am @@ -0,0 +1,33 @@ +# This file is part of the KDE libraries +# Copyright (C) 2001 George Staikos + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. + +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public License +# along with this library; see the file COPYING.LIB. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +INCLUDES= -I$(srcdir)/.. -I$(top_srcdir) $(SSL_INCLUDES) -I$(top_srcdir)/tdeio/kssl -I$(top_builddir)/tdeio/kssl $(all_includes) + +kde_module_LTLIBRARIES = kded_kssld.la + +kded_kssld_la_LDFLAGS = $(all_libraries) -module -avoid-version +kded_kssld_la_LIBADD = $(LIB_KIO) $(LIB_KDED) $(LIB_QT) $(top_builddir)/dcop/libDCOP.la $(LIB_TDECORE) +kded_kssld_la_SOURCES = kssld.cpp kssld.skel + +METASOURCES = AUTO + +noinst_HEADERS = kssld.h + +services_DATA = kssld.desktop +servicesdir = $(kde_servicesdir)/kded + diff --git a/tdeio/misc/kssld/kssld.cpp b/tdeio/misc/kssld/kssld.cpp new file mode 100644 index 000000000..aa561cc8b --- /dev/null +++ b/tdeio/misc/kssld/kssld.cpp @@ -0,0 +1,1027 @@ +/* + This file is part of the KDE libraries + + Copyright (c) 2001-2005 George Staikos + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include "kssld.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// See design notes at end + +extern "C" { + KDE_EXPORT KDEDModule *create_kssld(const TQCString &name) { + return new KSSLD(name); + } + + KDE_EXPORT void *__kde_do_unload; +} + + +static void updatePoliciesConfig(TDEConfig *cfg) { + TQStringList groups = cfg->groupList(); + + for (TQStringList::Iterator i = groups.begin(); i != groups.end(); ++i) { + if ((*i).isEmpty() || *i == "General") { + continue; + } + + cfg->setGroup(*i); + + // remove it if it has expired + if (!cfg->readBoolEntry("Permanent") && cfg->readDateTimeEntry("Expires") < TQDateTime::currentDateTime()) { + cfg->deleteGroup(*i); + continue; + } + + TQString encodedCertStr = cfg->readEntry("Certificate"); + TQCString encodedCert = encodedCertStr.local8Bit(); + KSSLCertificate *newCert = KSSLCertificate::fromString(encodedCert); + if (!newCert) { + cfg->deleteGroup(*i); + continue; + } + + KSSLCertificateCache::KSSLCertificatePolicy policy = (KSSLCertificateCache::KSSLCertificatePolicy) cfg->readNumEntry("Policy"); + bool permanent = cfg->readBoolEntry("Permanent"); + TQDateTime expires = cfg->readDateTimeEntry("Expires"); + TQStringList hosts = cfg->readListEntry("Hosts"); + TQStringList chain = cfg->readListEntry("Chain"); + cfg->deleteGroup(*i); + + cfg->setGroup(newCert->getMD5Digest()); + cfg->writeEntry("Certificate", encodedCertStr); + cfg->writeEntry("Policy", policy); + cfg->writeEntry("Permanent", permanent); + cfg->writeEntry("Expires", expires); + cfg->writeEntry("Hosts", hosts); + cfg->writeEntry("Chain", chain); + delete newCert; + } + + cfg->setGroup("General"); + cfg->writeEntry("policies version", 2); + + cfg->sync(); +} + + +KSSLD::KSSLD(const TQCString &name) : KDEDModule(name) +{ +// ----------------------- FOR THE CACHE ------------------------------------ + cfg = new KSimpleConfig("ksslpolicies", false); + cfg->setGroup("General"); + if (2 != cfg->readNumEntry("policies version", 0)) { + ::updatePoliciesConfig(cfg); + } + TDEGlobal::dirs()->addResourceType("kssl", KStandardDirs::kde_default("data") + "kssl"); + caVerifyUpdate(); + cacheLoadDefaultPolicies(); + certList.setAutoDelete(false); + kossl = KOSSL::self(); + +// ----------------------- FOR THE HOME ------------------------------------- +} + + +KSSLD::~KSSLD() +{ +// ----------------------- FOR THE CACHE ------------------------------------ + cacheClearList(); + delete cfg; + +// ----------------------- FOR THE HOME ------------------------------------- +} + + + + +// A node in the cache +class KSSLCNode { + public: + KSSLCertificate *cert; + KSSLCertificateCache::KSSLCertificatePolicy policy; + bool permanent; + TQDateTime expires; + TQStringList hosts; + KSSLCNode() { cert = 0L; + policy = KSSLCertificateCache::Unknown; + permanent = true; + } + ~KSSLCNode() { delete cert; } +}; + + + +void KSSLD::cacheSaveToDisk() { +KSSLCNode *node; + + cfg->setGroup("General"); + cfg->writeEntry("policies version", 2); + + for (node = certList.first(); node; node = certList.next()) { + if (node->permanent || + node->expires > TQDateTime::currentDateTime()) { + // First convert to a binary format and then write the + // tdeconfig entry write the (CN, policy, cert) to + // KSimpleConfig + cfg->setGroup(node->cert->getMD5Digest()); + cfg->writeEntry("Certificate", node->cert->toString()); + cfg->writeEntry("Policy", node->policy); + cfg->writeEntry("Expires", node->expires); + cfg->writeEntry("Permanent", node->permanent); + cfg->writeEntry("Hosts", node->hosts); + + // Also write the chain + TQStringList qsl; + TQPtrList cl = + node->cert->chain().getChain(); + for (KSSLCertificate *c = cl.first(); + c != 0; + c = cl.next()) { + //kdDebug() << "Certificate in chain: " + // << c->toString() << endl; + qsl << c->toString(); + } + + cl.setAutoDelete(true); + cfg->writeEntry("Chain", qsl); + } + } + + cfg->sync(); + + // insure proper permissions -- contains sensitive data + TQString cfgName(TDEGlobal::dirs()->findResource("config", "ksslpolicies")); + + if (!cfgName.isEmpty()) { + ::chmod(TQFile::encodeName(cfgName), 0600); + } +} + + +void KSSLD::cacheReload() { + cacheClearList(); + delete cfg; + cfg = new KSimpleConfig("ksslpolicies", false); + cacheLoadDefaultPolicies(); +} + + +void KSSLD::cacheClearList() { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + certList.remove(node); + delete node; + } + + skEmail.clear(); + skMD5Digest.clear(); +} + + +void KSSLD::cacheLoadDefaultPolicies() { +TQStringList groups = cfg->groupList(); + + for (TQStringList::Iterator i = groups.begin(); + i != groups.end(); + ++i) { + if ((*i).isEmpty() || *i == "General") { + continue; + } + + cfg->setGroup(*i); + + // remove it if it has expired + if (!cfg->readBoolEntry("Permanent") && + cfg->readDateTimeEntry("Expires") < + TQDateTime::currentDateTime()) { + cfg->deleteGroup(*i); + continue; + } + + TQCString encodedCert; + KSSLCertificate *newCert; + + encodedCert = cfg->readEntry("Certificate").local8Bit(); + newCert = KSSLCertificate::fromString(encodedCert); + + if (!newCert) { + continue; + } + + KSSLCNode *n = new KSSLCNode; + n->cert = newCert; + n->policy = (KSSLCertificateCache::KSSLCertificatePolicy) cfg->readNumEntry("Policy"); + n->permanent = cfg->readBoolEntry("Permanent"); + n->expires = cfg->readDateTimeEntry("Expires"); + n->hosts = cfg->readListEntry("Hosts"); + newCert->chain().setCertChain(cfg->readListEntry("Chain")); + certList.append(n); + searchAddCert(newCert); + } +} + + +void KSSLD::cacheAddCertificate(KSSLCertificate cert, + KSSLCertificateCache::KSSLCertificatePolicy policy, + bool permanent) { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + if (cert == *(node->cert)) { + node->policy = policy; + node->permanent = permanent; + + if (!permanent) { + node->expires = TQDateTime::currentDateTime(); + // FIXME: make this configurable + node->expires = TQT_TQDATETIME_OBJECT(node->expires.addSecs(3600)); + } + + cacheSaveToDisk(); + return; + } + } + + KSSLCNode *n = new KSSLCNode; + n->cert = cert.replicate(); + n->policy = policy; + n->permanent = permanent; + // remove the old one + cacheRemoveByCertificate(*(n->cert)); + certList.prepend(n); + + if (!permanent) { + n->expires = TQDateTime::currentDateTime(); + n->expires = TQT_TQDATETIME_OBJECT(n->expires.addSecs(3600)); + } + + searchAddCert(n->cert); + cacheSaveToDisk(); +} + + +KSSLCertificateCache::KSSLCertificatePolicy KSSLD::cacheGetPolicyByCN(TQString cn) { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) { + if (!node->permanent && + node->expires < TQDateTime::currentDateTime()) { + certList.remove(node); + cfg->deleteGroup(node->cert->getMD5Digest()); + delete node; + continue; + } + + certList.remove(node); + certList.prepend(node); + cacheSaveToDisk(); + return node->policy; + } + } + + cacheSaveToDisk(); + +return KSSLCertificateCache::Unknown; +} + + +KSSLCertificateCache::KSSLCertificatePolicy KSSLD::cacheGetPolicyByCertificate(KSSLCertificate cert) { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + if (cert == *(node->cert)) { + if (!node->permanent && + node->expires < TQDateTime::currentDateTime()) { + certList.remove(node); + cfg->deleteGroup(node->cert->getMD5Digest()); + delete node; + cacheSaveToDisk(); + return KSSLCertificateCache::Unknown; + } + + certList.remove(node); + certList.prepend(node); + return node->policy; + } + } + +return KSSLCertificateCache::Unknown; +} + + +bool KSSLD::cacheSeenCN(TQString cn) { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) { + if (!node->permanent && + node->expires < TQDateTime::currentDateTime()) { + certList.remove(node); + cfg->deleteGroup(node->cert->getMD5Digest()); + delete node; + cacheSaveToDisk(); + continue; + } + + certList.remove(node); + certList.prepend(node); + return true; + } + } + +return false; +} + + +bool KSSLD::cacheSeenCertificate(KSSLCertificate cert) { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + if (cert == *(node->cert)) { + if (!node->permanent && + node->expires < TQDateTime::currentDateTime()) { + certList.remove(node); + cfg->deleteGroup(node->cert->getMD5Digest()); + delete node; + cacheSaveToDisk(); + return false; + } + + certList.remove(node); + certList.prepend(node); + return true; + } + } + +return false; +} + + +bool KSSLD::cacheIsPermanent(KSSLCertificate cert) { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + if (cert == *(node->cert)) { + if (!node->permanent && node->expires < + TQDateTime::currentDateTime()) { + certList.remove(node); + cfg->deleteGroup(node->cert->getMD5Digest()); + delete node; + cacheSaveToDisk(); + return false; + } + + certList.remove(node); + certList.prepend(node); + return node->permanent; + } + } + +return false; +} + + +bool KSSLD::cacheRemoveBySubject(TQString subject) { +KSSLCNode *node; +bool gotOne = false; + + for (node = certList.first(); node; node = certList.next()) { + if (node->cert->getSubject() == subject) { + certList.remove(node); + cfg->deleteGroup(node->cert->getMD5Digest()); + searchRemoveCert(node->cert); + delete node; + gotOne = true; + } + } + + cacheSaveToDisk(); + +return gotOne; +} + + +bool KSSLD::cacheRemoveByCN(TQString cn) { +KSSLCNode *node; +bool gotOne = false; + + for (node = certList.first(); node; node = certList.next()) { + if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) { + certList.remove(node); + cfg->deleteGroup(node->cert->getMD5Digest()); + searchRemoveCert(node->cert); + delete node; + gotOne = true; + } + } + + cacheSaveToDisk(); + +return gotOne; +} + + +bool KSSLD::cacheRemoveByCertificate(KSSLCertificate cert) { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + if (cert == *(node->cert)) { + certList.remove(node); + cfg->deleteGroup(node->cert->getMD5Digest()); + searchRemoveCert(node->cert); + delete node; + cacheSaveToDisk(); + return true; + } + } + +return false; +} + + +bool KSSLD::cacheModifyByCN(TQString cn, + KSSLCertificateCache::KSSLCertificatePolicy policy, bool permanent, + TQDateTime expires) { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + if (KSSLX509Map(node->cert->getSubject()).getValue("CN") == cn) { + node->permanent = permanent; + node->expires = expires; + node->policy = policy; + certList.remove(node); + certList.prepend(node); + cacheSaveToDisk(); + return true; + } + } + +return false; +} + + +bool KSSLD::cacheModifyByCertificate(KSSLCertificate cert, + KSSLCertificateCache::KSSLCertificatePolicy policy, + bool permanent, + TQDateTime expires) { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + if (cert == *(node->cert)) { + node->permanent = permanent; + node->expires = expires; + node->policy = policy; + certList.remove(node); + certList.prepend(node); + cacheSaveToDisk(); + return true; + } + } + +return false; +} + + +TQStringList KSSLD::cacheGetHostList(KSSLCertificate cert) { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + if (cert == *(node->cert)) { + if (!node->permanent && node->expires < + TQDateTime::currentDateTime()) { + certList.remove(node); + cfg->deleteGroup(node->cert->getMD5Digest()); + searchRemoveCert(node->cert); + delete node; + cacheSaveToDisk(); + return TQStringList(); + } + + certList.remove(node); + certList.prepend(node); + return node->hosts; + } + } + +return TQStringList(); +} + + +bool KSSLD::cacheAddHost(KSSLCertificate cert, TQString host) { +KSSLCNode *node; + + if (host.isEmpty()) + return true; + + for (node = certList.first(); node; node = certList.next()) { + if (cert == *(node->cert)) { + if (!node->permanent && node->expires < + TQDateTime::currentDateTime()) { + certList.remove(node); + cfg->deleteGroup(node->cert->getMD5Digest()); + searchRemoveCert(node->cert); + delete node; + cacheSaveToDisk(); + return false; + } + + if (!node->hosts.contains(host)) { + node->hosts << host; + } + + certList.remove(node); + certList.prepend(node); + cacheSaveToDisk(); + return true; + } + } + +return false; +} + + +bool KSSLD::cacheRemoveHost(KSSLCertificate cert, TQString host) { +KSSLCNode *node; + + for (node = certList.first(); node; node = certList.next()) { + if (cert == *(node->cert)) { + if (!node->permanent && node->expires < + TQDateTime::currentDateTime()) { + certList.remove(node); + cfg->deleteGroup(node->cert->getMD5Digest()); + searchRemoveCert(node->cert); + delete node; + cacheSaveToDisk(); + return false; + } + node->hosts.remove(host); + certList.remove(node); + certList.prepend(node); + cacheSaveToDisk(); + return true; + } + } + +return false; +} + + + + +/////////////////////////////////////////////////////////////////////////// + +void KSSLD::caVerifyUpdate() { + TQString path = TDEGlobal::dirs()->saveLocation("kssl") + "/ca-bundle.crt"; + if (!TQFile::exists(path)) + return; + + cfg->setGroup(TQString::null); + TQ_UINT32 newStamp = TDEGlobal::dirs()->calcResourceHash("config", "ksslcalist", true); + TQ_UINT32 oldStamp = cfg->readUnsignedNumEntry("ksslcalistStamp"); + if (oldStamp != newStamp) + { + caRegenerate(); + cfg->writeEntry("ksslcalistStamp", newStamp); + cfg->sync(); + } +} + +bool KSSLD::caRegenerate() { +TQString path = TDEGlobal::dirs()->saveLocation("kssl") + "/ca-bundle.crt"; + +TQFile out(path); + + if (!out.open(IO_WriteOnly)) + return false; + +TDEConfig cfg("ksslcalist", true, false); + +TQStringList x = cfg.groupList(); + + for (TQStringList::Iterator i = x.begin(); + i != x.end(); + ++i) { + if ((*i).isEmpty() || *i == "") continue; + + cfg.setGroup(*i); + + if (!cfg.readBoolEntry("site", false)) continue; + + TQString cert = cfg.readEntry("x509", ""); + if (cert.length() <= 0) continue; + + unsigned int xx = cert.length() - 1; + for (unsigned int j = 0; j < xx/64; j++) { + cert.insert(64*(j+1)+j, '\n'); + } + out.writeBlock("-----BEGIN CERTIFICATE-----\n", 28); + out.writeBlock(cert.latin1(), cert.length()); + out.writeBlock("\n-----END CERTIFICATE-----\n\n", 28); + out.flush(); + } + +return true; +} + + + +bool KSSLD::caAdd(TQString certificate, bool ssl, bool email, bool code) { +KSSLCertificate *x = KSSLCertificate::fromString(certificate.local8Bit()); + + if (!x) return false; + +TDEConfig cfg("ksslcalist", false, false); + + cfg.setGroup(x->getSubject()); + cfg.writeEntry("x509", certificate); + cfg.writeEntry("site", ssl); + cfg.writeEntry("email", email); + cfg.writeEntry("code", code); + + cfg.sync(); + delete x; + +return true; +} + + +/** + * @internal + * Returns a list of certificates as QStrings read from the given file + */ +static TQStringList caReadCerticatesFromFile(TQString filename) { + + TQStringList certificates; + TQString certificate, temp; + TQFile file(filename); + + if (!file.open(IO_ReadOnly)) + return certificates; + + while (!file.atEnd()) { + file.readLine(temp, 999); + if (temp.startsWith("-----BEGIN CERTIFICATE-----")) { + certificate = TQString::null; + continue; + } + + if (temp.startsWith("-----END CERTIFICATE-----")) { + certificates.append(certificate); + certificate = TQString::null; + continue; + } + + certificate += temp.stripWhiteSpace(); + } + + file.close(); + + return certificates; +} + +bool KSSLD::caAddFromFile(TQString filename, bool ssl, bool email, bool code) { + + TQStringList certificates; + certificates = caReadCerticatesFromFile(filename); + if (certificates.isEmpty()) + return false; + + bool ok = true; + + for (TQStringList::Iterator it = certificates.begin(); + it != certificates.end(); ++it ) { + ok &= caAdd(*it, ssl, email, code); + } + + return ok; +} + +bool KSSLD::caRemoveFromFile(TQString filename) { + + TQStringList certificates; + certificates = caReadCerticatesFromFile(filename); + if (certificates.isEmpty()) + return false; + + bool ok = true; + + for (TQStringList::Iterator it = certificates.begin(); + it != certificates.end(); ++it ) { + TQString certificate = *it; + KSSLCertificate *x = KSSLCertificate::fromString(certificate.local8Bit()); + ok &= x && caRemove(x->getSubject()); + delete x; + } + + return ok; +} + + +TQStringList KSSLD::caList() { +TQStringList x; +TDEConfig cfg("ksslcalist", true, false); + + x = cfg.groupList(); + x.remove(""); + +return x; +} + + +bool KSSLD::caUseForSSL(TQString subject) { +TDEConfig cfg("ksslcalist", true, false); + + if (!cfg.hasGroup(subject)) + return false; + + cfg.setGroup(subject); +return cfg.readBoolEntry("site", false); +} + + + +bool KSSLD::caUseForEmail(TQString subject) { +TDEConfig cfg("ksslcalist", true, false); + + if (!cfg.hasGroup(subject)) + return false; + + cfg.setGroup(subject); +return cfg.readBoolEntry("email", false); +} + + + +bool KSSLD::caUseForCode(TQString subject) { +TDEConfig cfg("ksslcalist", true, false); + + if (!cfg.hasGroup(subject)) + return false; + + cfg.setGroup(subject); +return cfg.readBoolEntry("code", false); +} + + +bool KSSLD::caRemove(TQString subject) { +TDEConfig cfg("ksslcalist", false, false); + if (!cfg.hasGroup(subject)) + return false; + + cfg.deleteGroup(subject); + cfg.sync(); + +return true; +} + + +TQString KSSLD::caGetCert(TQString subject) { +TDEConfig cfg("ksslcalist", true, false); + if (!cfg.hasGroup(subject)) + return TQString::null; + + cfg.setGroup(subject); + +return cfg.readEntry("x509", TQString::null); +} + + +bool KSSLD::caSetUse(TQString subject, bool ssl, bool email, bool code) { +TDEConfig cfg("ksslcalist", false, false); + if (!cfg.hasGroup(subject)) + return false; + + cfg.setGroup(subject); + + cfg.writeEntry("site", ssl); + cfg.writeEntry("email", email); + cfg.writeEntry("code", code); + cfg.sync(); + +return true; +} + +/////////////////////////////////////////////////////////////////////////// + +void KSSLD::searchAddCert(KSSLCertificate *cert) { + skMD5Digest.insert(cert->getMD5Digest(), cert, true); + + TQStringList mails; + cert->getEmails(mails); + for(TQStringList::const_iterator iter = mails.begin(); iter != mails.end(); ++iter) { + TQString email = static_cast(*iter).lower(); + TQMap >::iterator it = skEmail.find(email); + + if (it == skEmail.end()) + it = skEmail.insert(email, TQPtrVector()); + + TQPtrVector &elem = *it; + + if (elem.findRef(cert) == -1) { + unsigned int n = 0; + for(; n < elem.size(); n++) { + if (!elem.at(n)) { + elem.insert(n, cert); + break; + } + } + if (n == elem.size()) { + elem.resize(n+1); + elem.insert(n, cert); + } + } + } +} + + +void KSSLD::searchRemoveCert(KSSLCertificate *cert) { + skMD5Digest.remove(cert->getMD5Digest()); + + TQStringList mails; + cert->getEmails(mails); + for(TQStringList::const_iterator iter = mails.begin(); iter != mails.end(); ++iter) { + TQMap >::iterator it = skEmail.find(static_cast(*iter).lower()); + + if (it == skEmail.end()) + break; + + TQPtrVector &elem = *it; + + int n = elem.findRef(cert); + if (n != -1) + elem.remove(n); + } +} + + +TQStringList KSSLD::getKDEKeyByEmail(const TQString &email) { + TQStringList rc; + TQMap >::iterator it = skEmail.find(email.lower()); + + kdDebug() << "GETKDEKey " << email.latin1() << endl; + + if (it == skEmail.end()) + return rc; + + TQPtrVector &elem = *it; + for (unsigned int n = 0; n < elem.size(); n++) { + KSSLCertificate *cert = elem.at(n); + if (cert) { + rc.append(cert->getKDEKey()); + } + } + + kdDebug() << "ergebnisse: " << rc.size() << " " << elem.size() << endl; + return rc; +} + + +KSSLCertificate KSSLD::getCertByMD5Digest(const TQString &key) { + TQMap::iterator iter = skMD5Digest.find(key); + + kdDebug() << "Searching cert for " << key.latin1() << endl; + + if (iter != skMD5Digest.end()) + return **iter; + + KSSLCertificate rc; // FIXME: Better way to return a not found condition? + kdDebug() << "Not found: " << rc.toString().latin1() << endl; + return rc; +} + + +/////////////////////////////////////////////////////////////////////////// + +// +// Certificate Home methods +// + +TQStringList KSSLD::getHomeCertificateList() { + return KSSLCertificateHome::getCertificateList(); +} + +bool KSSLD::addHomeCertificateFile(TQString filename, TQString password, bool storePass) { + return KSSLCertificateHome::addCertificate(filename, password, storePass); +} + +bool KSSLD::addHomeCertificatePKCS12(TQString base64cert, TQString passToStore) { + bool ok; + KSSLPKCS12 *pkcs12 = KSSLPKCS12::fromString(base64cert, passToStore); + ok = KSSLCertificateHome::addCertificate(pkcs12, passToStore); + delete pkcs12; + return ok; +} + +bool KSSLD::deleteHomeCertificateByFile(TQString filename, TQString password) { + return KSSLCertificateHome::deleteCertificate(filename, password); +} + +bool KSSLD::deleteHomeCertificateByPKCS12(TQString base64cert, TQString password) { + bool ok; + KSSLPKCS12 *pkcs12 = KSSLPKCS12::fromString(base64cert, password); + ok = KSSLCertificateHome::deleteCertificate(pkcs12); + delete pkcs12; + return ok; +} + +bool KSSLD::deleteHomeCertificateByName(TQString name) { + return KSSLCertificateHome::deleteCertificateByName(name); +} + + + +/////////////////////////////////////////////////////////////////////////// + +#include "kssld.moc" + + +/* + + DESIGN - KSSLCertificateCache + ------ + + This is the first implementation and I think this cache actually needs + experimentation to determine which implementation works best. My current + options are: + + (1) Store copies of the X509 certificates in a TQPtrList using a self + organizing heuristic as described by Munro and Suwanda. + (2) Store copies of the X509 certificates in a tree structure, perhaps + a redblack tree, avl tree, or even just a simple binary tree. + (3) Store the CN's in a tree or list and use them as a hash to retrieve + the X509 certificates. + (4) Create "nodes" containing the X509 certificate and place them in + two structures concurrently, one organized by CN, the other by + X509 serial number. + + This implementation uses (1). (4) is definitely attractive, but I don't + think it will be necessary to go so crazy with performance, and perhaps + end up performing poorly in situations where there are very few entries in + the cache (which is most likely the case most of the time). The style of + heuristic is move-to-front, not swap-forward. This seems to make more + sense because the typical user will hit a site at least a few times in a + row before moving to a new one. + + What I worry about most with respect to performance is that cryptographic + routines are expensive and if we have to perform them on each X509 + certificate until the right one is found, we will perform poorly. + + All in all, this code is actually quite crucial for performance on SSL + website, especially those with many image files loaded via SSL. If a + site loads 15 images, we will have to run through this code 15 times. + A heuristic for self organization will make each successive lookup faster. + Sounds good, doesn't it? + + DO NOT ATTEMPT TO GUESS WHICH CERTIFICATES ARE ACCEPTIBLE IN YOUR CODE!! + ALWAYS USE THE CACHE. IT MAY CHECK THINGS THAT YOU DON'T THINK OF, AND + ALSO IF THERE IS A BUG IN THE CHECKING CODE, IF IT IS ALL CONTAINED IN + THIS LIBRARY, A MINOR FIX WILL FIX ALL APPLICATIONS. + */ + diff --git a/tdeio/misc/kssld/kssld.desktop b/tdeio/misc/kssld/kssld.desktop new file mode 100644 index 000000000..7054f8bad --- /dev/null +++ b/tdeio/misc/kssld/kssld.desktop @@ -0,0 +1,156 @@ +[Desktop Entry] +Type=Service +ServiceTypes=KDEDModule +X-TDE-ModuleType=Library +X-TDE-Library=kssld +X-TDE-FactoryName=kssld +X-TDE-Kded-autoload=false +X-TDE-Kded-load-on-demand=true +Name=KSSL Daemon Module +Name[af]=Kssl Bediener Module +Name[ar]=وحدة مراقب KSSL +Name[az]=KSSL Demon Modulu +Name[be]=Модуль сервіса KSSL +Name[bg]=Демон KSSL +Name[bn]=KSSL ডিমন মডিউল +Name[br]=Mollad an diaoul KSSL +Name[ca]=Mòdul del dimoni KSSL +Name[cs]=Modul démona KSSL +Name[csb]=KSSL +Name[cy]=Modiwl Daemon KSSL +Name[da]=KSSL Dæmonmodul +Name[de]=SSL-Dienst +Name[el]=Άρθρωμα δαίμονα KSSL +Name[eo]=SSL-demono-modulo +Name[es]=Módulo de demonio KSSL +Name[et]=KSSL deemoni moodul +Name[eu]=KSSL daemon modulua +Name[fa]=پیمانۀ شبح KSSL +Name[fi]=KSSL-palvelinmoduuli +Name[fr]=Module démon KSSL +Name[ga]=Modúl Deamhain KSSL +Name[gl]=Módulo do Demo KSSL +Name[he]=מודול תהליך הרקע של SSL +Name[hi]=KSSL ङेमन घटक +Name[hr]=Modul KSSL demona +Name[hu]=KSSL szolgáltatásmodul +Name[id]=Modul Daemon KSSL +Name[is]=KSSL þjónseining +Name[it]=Modulo demone KSSL +Name[ja]=KSSL デーモンモジュール +Name[ka]=KSSL გუშაგის მოდული +Name[kk]=KSSL қызметтің модулі +Name[km]=ម៉ូឌុល Daemon KSSL +Name[ko]=KSSL 데몬 모듈 +Name[lb]=KSSL-Dämonmodul +Name[lt]=KSSL tarnybos modulis +Name[lv]=KSSL Dēmona Modulis +Name[mn]=KSSL Daemon Modul +Name[ms]=Modul Daemon KSSL +Name[mt]=Modulu daemon KSSL +Name[nb]=KSSL nisse-modul +Name[nds]=KSSL-Dämoon +Name[ne]=KSSL डेइमन मोड्युल +Name[nl]=KSSL daemon-module +Name[nn]=KSSL-nissemodul +Name[nso]=Seripa sa Daemon ya KSSL +Name[pa]=KSSL ਡਾਇਮੋਨ ਮੈਡੀਊਲ +Name[pl]=KSSL +Name[pt]=Módulo do Servidor de KSSL +Name[pt_BR]=Módulo do Serviço do KSSL +Name[ro]=Modul demon KSSL +Name[ru]=Служба KSSL +Name[rw]=Igice Dayimoni KSSL +Name[se]=KSSL-bálvámoduvla +Name[sk]=Modul démona KSSL +Name[sl]=Strežniški modul KSSL +Name[sq]=Demoni për Modulin KSSL +Name[sr]=KSSL демон модул +Name[sr@Latn]=KSSL demon modul +Name[sv]=KSSL-demonmodul +Name[ta]=KSSL டெமான் பகுதி +Name[te]=కెఎస్ ఎస్ ఎల్ సూత్రధారి మాడ్యూల్ +Name[tg]=Модули Демон KSSL +Name[th]=โมดูลเดมอน KSSL +Name[tr]=KSSL Program Modülü +Name[tt]=KSSL Xezmäteneñ Modulı +Name[uk]=Модуль демону KSSL +Name[uz]=KSSL xizmatining moduli +Name[uz@cyrillic]=KSSL хизматининг модули +Name[ven]=Modulu wa Daemon wa KSSL +Name[vi]=Mô-đun trình nền KSSL +Name[xh]=Isicatshulwa se KSSL Daemon +Name[zh_CN]=KSSL 守护进程模块 +Name[zh_HK]=KSSL 伺服程式模組 +Name[zh_TW]=KSSL 伺服程式模組 +Name[zu]=Ingxenye ye-daemon ye-KSSL +Comment=KSSL daemon module for KDED +Comment[af]=KSSL bediener module vir KDED +Comment[be]=Модуль сервіса KSSL для KDED +Comment[bg]=Модул демон за KSSL за KDED +Comment[bn]=KDED-র জন্য KSSL ডিমন মডিউল +Comment[br]=Mollad an diaoul KSSL evit KDED +Comment[bs]=KSSL Daemon Module za KDED +Comment[ca]=Mòdul del dimoni KSSL per a KDED +Comment[cs]=Modul démona KSSL pro KDED +Comment[csb]=Ùsłëżnota SSL w KDED +Comment[da]=KSSL Dæmonmodul for KDED +Comment[de]=Unterstützung für SSL-Verschlüsselung in KDED +Comment[el]=Άρθρωμα δαίμονα KSSL για το KDED +Comment[eo]=SSL-demono-modulo por KDED +Comment[es]=Módulo de demonio KSSL para KDED +Comment[et]=KDED KSSL deemoni moodul +Comment[eu]=KSSL daemon modulua KDEDrako +Comment[fa]=پیمانۀ شبح KSSL برای KDED +Comment[fi]=KSSL-palvelinmoduuli KDED:lle +Comment[fr]=Module démon KSSL pour KDED +Comment[fy]=KSSL daemon module foar KDED +Comment[ga]=Modúl deamhain KSSL le haghaidh KDED +Comment[gl]=Módulo do Demo KSSL para KDED +Comment[he]=מודול תהליך רקע של SSL עבור KDED +Comment[hi]=केडीईडी के लिए केएसएसएल डेमन मॉड्यूल +Comment[hr]=KSSL demon modul za KDED +Comment[hu]=KSSL szolgáltatásmodul a KDED-hez +Comment[id]=Modul daemon KSSL untuk KDED +Comment[is]=KSSL þjónseining fyrir KDED +Comment[it]=Modulo demone KSSL per KDED +Comment[ja]=KDED 用 の KSSL デーモンモジュール +Comment[ka]=KSSL გუშაგის მოდული KDED-სთვის +Comment[kk]=KDED KSSL куәліктерді басқару қызметтің модулі +Comment[km]=ម៉ូឌុល daemon KSSL សម្រាប់ KDED +Comment[lb]=KSSL-Dämonmodul fir KDED +Comment[lt]=KSSL tarnybos modulis, skirtas KDED +Comment[lv]=KSSL Dēmona Modulis priekš KDED +Comment[mk]=KSSL даемон модул за KDED +Comment[ms]=Modul Daemon KSSL untuk KDED +Comment[nb]=KSSL nissemodul for KDED +Comment[nds]=KSSL-Dämoonmoduul för KDED +Comment[ne]=KDED का लागि डेइमन मोड्युल KSSL +Comment[nl]=KSSL daemon-module voor KDED +Comment[nn]=KSSL-nissemodul for KDED +Comment[pa]=KDED ਲਈ KSSL ਪੇਸ਼ਕਾਰੀ +Comment[pl]=Obsługa SSL w KDED +Comment[pt]=Módulo servidor de KSSL para o KDED +Comment[pt_BR]=Módulo de serviço KSSL para o KDED +Comment[ro]=Modul demon KSSL pentru KDED +Comment[ru]=Управление сертификатами SSL +Comment[rw]=Igice cya dayimoni KSSL cya KDED +Comment[se]=KDED:a KSSL-bálvámoduvla +Comment[sk]=Modul démona KSSL pre KDED +Comment[sl]=Strežniški modul KSSL za KDED +Comment[sr]=KSSL демон модул за KDED +Comment[sr@Latn]=KSSL demon modul za KDED +Comment[sv]=KSSL-demonmodul för KDED +Comment[ta]=KDEDக்கான KSSL டெமான் பகுதி +Comment[te]=కెడిఈడి కొరకు కెఎస్ ఎస్ ఎల్ సూత్రధారి మాడ్యూల్ +Comment[tg]=Модули Демон KSSL брои KDED +Comment[th]=โมดูลเดมอน KSSL สำหรับ KDED +Comment[tr]=KDED için KSSL program biirmi +Comment[tt]=KDED öçen KSSL xezmät +Comment[uk]=Модуль демону KSSL для KDED +Comment[uz]=KDED uchun KSSL xizmatining moduli +Comment[uz@cyrillic]=KDED учун KSSL хизматининг модули +Comment[vi]=Mô-đun trình nền KSSL cho KDED. +Comment[zh_CN]=KDED 的 KSSL 守护进程模块 +Comment[zh_HK]=KDED 使用的 SSL 伺服程式模組 +Comment[zh_TW]=KDED 使用的 KSSL 伺服程式模組 diff --git a/tdeio/misc/kssld/kssld.h b/tdeio/misc/kssld/kssld.h new file mode 100644 index 000000000..028a30809 --- /dev/null +++ b/tdeio/misc/kssld/kssld.h @@ -0,0 +1,154 @@ +/* + This file is part of the KDE libraries + + Copyright (c) 2001-2005 George Staikos + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ +#ifndef __KSSLD_H__ +#define __KSSLD_H__ + +#include +#include +#include +#include +#include +#include +#include +#include + + +class KSimpleConfig; +class KSSLCNode; +class KOpenSSLProxy; + +class KSSLD : public KDEDModule +{ + Q_OBJECT + K_DCOP + +public: + + KSSLD(const TQCString &name); + + virtual ~KSSLD(); + +k_dcop: + // + // Certificate Cache methods + // + void cacheAddCertificate(KSSLCertificate cert, + KSSLCertificateCache::KSSLCertificatePolicy policy, + bool permanent = true); + KSSLCertificateCache::KSSLCertificatePolicy cacheGetPolicyByCN(TQString cn); + + KSSLCertificateCache::KSSLCertificatePolicy cacheGetPolicyByCertificate(KSSLCertificate cert); + + bool cacheSeenCN(TQString cn); + bool cacheSeenCertificate(KSSLCertificate cert); + + bool cacheRemoveByCN(TQString cn); + bool cacheRemoveBySubject(TQString subject); + bool cacheRemoveByCertificate(KSSLCertificate cert); + + bool cacheIsPermanent(KSSLCertificate cert); + + void cacheReload(); + + bool cacheModifyByCN(TQString cn, + KSSLCertificateCache::KSSLCertificatePolicy policy, + bool permanent, + TQDateTime expires); + + bool cacheModifyByCertificate(KSSLCertificate cert, + KSSLCertificateCache::KSSLCertificatePolicy policy, + bool permanent, + TQDateTime expires); + + TQStringList cacheGetHostList(KSSLCertificate cert); + + bool cacheAddHost(KSSLCertificate cert, TQString host); + + bool cacheRemoveHost(KSSLCertificate cert, TQString host); + + /* Certificate Authorities */ + void caVerifyUpdate(); + bool caRegenerate(); + + TQStringList caList(); + + bool caUseForSSL(TQString subject); + + bool caUseForEmail(TQString subject); + + bool caUseForCode(TQString subject); + + bool caAdd(TQString certificate, bool ssl, bool email, bool code); + + bool caAddFromFile(TQString filename, bool ssl, bool email, bool code); + + bool caRemove(TQString subject); + + bool caRemoveFromFile(TQString filename); + + TQString caGetCert(TQString subject); + + bool caSetUse(TQString subject, bool ssl, bool email, bool code); + + TQStringList getKDEKeyByEmail(const TQString &email); + + KSSLCertificate getCertByMD5Digest(const TQString &key); + + // + // Certificate Home methods + // + + TQStringList getHomeCertificateList(); + + bool addHomeCertificateFile(TQString filename, TQString password, bool storePass /*=false*/); + + bool addHomeCertificatePKCS12(TQString base64cert, TQString passToStore); + + bool deleteHomeCertificateByFile(TQString filename, TQString password); + + bool deleteHomeCertificateByPKCS12(TQString base64cert, TQString password); + + bool deleteHomeCertificateByName(TQString name); + +private: + + void cacheClearList(); + void cacheSaveToDisk(); + void cacheLoadDefaultPolicies(); + + // for the cache portion: + KSimpleConfig *cfg; + TQPtrList certList; + + // Our pointer to OpenSSL + KOpenSSLProxy *kossl; + + // + void searchAddCert(KSSLCertificate *cert); + void searchRemoveCert(KSSLCertificate *cert); + + TQMap > skEmail; + TQMap skMD5Digest; +}; + + +#endif diff --git a/tdeio/misc/mms.protocol b/tdeio/misc/mms.protocol new file mode 100644 index 000000000..8fde7c000 --- /dev/null +++ b/tdeio/misc/mms.protocol @@ -0,0 +1,73 @@ +[Protocol] +helper=true +exec= +defaultMimetype=uri/mms +protocol=mms +input=none +output=none +reading=false +Icon=www +Class=:internet +Description=Microsoft Media Server Protocol +Description[af]=Microsoft Media Bediener Protokol +Description[be]=Пратакол Microsoft Media Server +Description[bn]=মাইক্রোসফ্‌ট মিডিয়া সার্ভার প্রোটোকল +Description[bs]=Microsoft Media Server protokol +Description[ca]=Protocol Microsoft Media Server +Description[cs]=Microsoft Media Server protokol +Description[csb]=Protokól Microsoft Media Server +Description[da]=Microsoft Medieserver-protokol +Description[de]=Microsoft Media Server Protokoll +Description[el]=Πρωτόκολλο Microsoft Media Server +Description[es]=Protocolo Microsoft Media Server +Description[et]=Microsoft Media Server protokoll +Description[eu]=Microsoft Media Server protokoloa +Description[fa]=قرارداد کارساز رسانۀ میکروسافت +Description[fi]=Microsoft Media -palvelinprotokolla +Description[fr]=Protocole Microsoft Media Server +Description[gl]=Protocolo Microsoft Media Server +Description[he]=שרת פרוטוקול של מדייה של מיקרוספט +Description[hi]=माइक्रोसॉफ़्ट मीडिया सर्वर प्रोटोकॉल +Description[hr]=Protokol Microsoft Media poslužitelja +Description[hu]=MMS protokoll +Description[id]=Protokol Server Microsoft Media +Description[is]=Microsoft Media Server samskiptaregla +Description[it]=Protocollo Microsoft Media Server +Description[ja]=Microsoft メディアサーバプロトコル +Description[ka]=Microsoft Media Server პროტოკოლი +Description[kk]=Microsoft Media Server протоколы +Description[km]=ពិធីការ​ម៉ាស៊ីន​បម្រី Microsoft Media +Description[lb]=Microsoft-Media Server-Protokoll +Description[lt]=Microsoft media serverio protokolas +Description[lv]=Microsoft Media Server protokols +Description[mk]=Microsoft Media Server-протокол +Description[ms]=Protokol Pelayan Media Microsoft +Description[nds]=Microsoft-Medienserverprotokoll +Description[ne]=माइक्रोसफ्ट मिडिया सर्भर प्रोटोकल +Description[nl]=Microsoft Media Server-protocol +Description[nn]=Microsoft Media Server-protokoll +Description[pa]=Microsoft Media ਸਰਵਰ ਪ੍ਰੋਟੋਕਾਲ +Description[pl]=Protokół Microsoft Media Server +Description[pt]=Protocolo Microsoft Media Server +Description[pt_BR]=Protocolo do Microsoft Media Server +Description[ro]=Protocol Microsoft Media Server +Description[ru]=Протокол Microsoft Media Server +Description[rw]=Porotokole Igihuza Seriveri ya Microsoft +Description[se]=Microsoft Media Server-protokolla +Description[sk]=Protokol pre Microsoft Media Server +Description[sl]=Protokol Microsoft Media Server +Description[sr]=Microsoft Media Server протокол +Description[sr@Latn]=Microsoft Media Server protokol +Description[sv]=Microsoft mediaserver-protokoll +Description[ta]=மைக்ரோசாப்ட் ஊடக சேவக நெறிமுறை +Description[te]=మైక్రొసాఫ్ట్ మీడియా సెర్వర్ ప్రొటొకాల్ +Description[tg]=Протоколи медиа сервер барои Microsoft +Description[th]=โปรโตคอลสำหรับเซิรฟเวอร์จัดการสื่อของไมโครซอฟต์ (MMS) +Description[tr]=Microsoft Media Server Protokolü +Description[tt]=Microsoft Media Server Protokolı +Description[uk]=Протокол медіа сервера Microsoft +Description[vi]=Giao thức trình phục vụ phương tiện Microsoft™. +Description[zh_CN]=Microsoft 媒体服务器协议 +Description[zh_HK]=Microsoft Media Server 協定 +Description[zh_TW]=Microsoft Media Server 協定 +URIMode=url diff --git a/tdeio/misc/mmst.protocol b/tdeio/misc/mmst.protocol new file mode 100644 index 000000000..1f0f7636b --- /dev/null +++ b/tdeio/misc/mmst.protocol @@ -0,0 +1,15 @@ +[Protocol] +defaultMimetype=uri/mmst +exec= +protocol=mmst +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false +Icon=www +Class=:internet +URIMode=url diff --git a/tdeio/misc/mmsu.protocol b/tdeio/misc/mmsu.protocol new file mode 100644 index 000000000..deda935fc --- /dev/null +++ b/tdeio/misc/mmsu.protocol @@ -0,0 +1,15 @@ +[Protocol] +defaultMimetype=uri/mmsu +exec= +protocol=mmsu +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false +Icon=www +Class=:internet +URIMode=url diff --git a/tdeio/misc/pnm.protocol b/tdeio/misc/pnm.protocol new file mode 100644 index 000000000..3ca3a7d23 --- /dev/null +++ b/tdeio/misc/pnm.protocol @@ -0,0 +1,15 @@ +[Protocol] +defaultMimetype=uri/pnm +exec= +protocol=pnm +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false +Icon=www +Class=:internet +URIMode=url diff --git a/tdeio/misc/rlogin.protocol b/tdeio/misc/rlogin.protocol new file mode 100644 index 000000000..3b103a905 --- /dev/null +++ b/tdeio/misc/rlogin.protocol @@ -0,0 +1,13 @@ +[Protocol] +exec=tdetelnetservice %u +protocol=rlogin +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false +DocPath=tdeioslave/rlogin.html +Icon=konsole diff --git a/tdeio/misc/rtsp.protocol b/tdeio/misc/rtsp.protocol new file mode 100644 index 000000000..301312260 --- /dev/null +++ b/tdeio/misc/rtsp.protocol @@ -0,0 +1,15 @@ +[Protocol] +defaultMimetype=audio/x-pn-realaudio +exec= +protocol=rtsp +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false +Icon=www +Class=:internet +URIMode=url diff --git a/tdeio/misc/rtspt.protocol b/tdeio/misc/rtspt.protocol new file mode 100644 index 000000000..9e4fe9626 --- /dev/null +++ b/tdeio/misc/rtspt.protocol @@ -0,0 +1,15 @@ +[Protocol] +defaultMimetype=uri/rtspt +exec= +protocol=rtspt +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false +Icon=www +Class=:internet +URIMode=url diff --git a/tdeio/misc/rtspu.protocol b/tdeio/misc/rtspu.protocol new file mode 100644 index 000000000..9cc9299f6 --- /dev/null +++ b/tdeio/misc/rtspu.protocol @@ -0,0 +1,15 @@ +[Protocol] +defaultMimetype=uri/rtspu +exec= +protocol=rtspu +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false +Icon=www +Class=:internet +URIMode=url diff --git a/tdeio/misc/ssh.protocol b/tdeio/misc/ssh.protocol new file mode 100644 index 000000000..b0c098f8f --- /dev/null +++ b/tdeio/misc/ssh.protocol @@ -0,0 +1,13 @@ +[Protocol] +exec=tdetelnetservice %u +protocol=ssh +input=none +output=none +helper=true +listing=false +reading=false +writing=false +makedir=false +deleting=false +Icon=konsole + diff --git a/tdeio/misc/tdefile/CMakeLists.txt b/tdeio/misc/tdefile/CMakeLists.txt new file mode 100644 index 000000000..9e90b956c --- /dev/null +++ b/tdeio/misc/tdefile/CMakeLists.txt @@ -0,0 +1,39 @@ +################################################# +# +# (C) 2010 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${TQT_INCLUDE_DIRS} + ${CMAKE_BINARY_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdeui + ${CMAKE_SOURCE_DIR}/tdeio + ${CMAKE_SOURCE_DIR}/tdeio/tdeio + ${CMAKE_SOURCE_DIR}/tdeio/tdefile +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### tdefile ##################################### + +set( target tdefile ) + +set( ${target}_SRCS + fileprops.cpp +) + +tde_add_executable( ${target} + SOURCES ${${target}_SRCS} + LINK tdeio-shared + DESTINATION ${BIN_INSTALL_DIR} +) \ No newline at end of file diff --git a/tdeio/misc/tdefile/Makefile.am b/tdeio/misc/tdefile/Makefile.am new file mode 100644 index 000000000..21cdb0627 --- /dev/null +++ b/tdeio/misc/tdefile/Makefile.am @@ -0,0 +1,10 @@ +METASOURCES = AUTO + +noinst_HEADERS = fileprops.h +INCLUDES= -I$(top_srcdir) -I$(top_srcdir)/tdeio/tdeio $(all_includes) + +bin_PROGRAMS = tdefile +tdefile_SOURCES = fileprops.cpp +tdefile_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor +tdefile_LDADD = $(LIB_KIO) + diff --git a/tdeio/misc/tdefile/README b/tdeio/misc/tdefile/README new file mode 100644 index 000000000..d063b6d58 --- /dev/null +++ b/tdeio/misc/tdefile/README @@ -0,0 +1,4 @@ +This is a commandline frontend to KFileMetaInfo. It allows +to read and write meta information of files. + +Carsten Pfeiffer diff --git a/tdeio/misc/tdefile/fileprops.cpp b/tdeio/misc/tdefile/fileprops.cpp new file mode 100644 index 000000000..bb209fbc0 --- /dev/null +++ b/tdeio/misc/tdefile/fileprops.cpp @@ -0,0 +1,480 @@ +/* This file is part of the KDE libraries + Copyright (C) 2002,2003 Carsten Pfeiffer + + library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation, version 2. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "fileprops.h" + +#define KFILEVERSION "0.2" +#define INDENT "\t" + +using namespace std; + +static TQString beatifyValue( const TQString& value ) +{ + if ( value.isNull() ) + return TQString("(no value for key available)"); + else if ( value.isEmpty() ) + return TQString("(empty)"); + + return value; +} + +FileProps::FileProps( const TQString& path, const TQStringList& suppliedGroups ) + : m_dirty( false ) +{ + m_info = new KFileMetaInfo(path, TQString::null, KFileMetaInfo::Everything); + m_userSuppliedGroups = !suppliedGroups.isEmpty(); + m_groupsToUse = m_userSuppliedGroups ? suppliedGroups : m_info->groups(); +} + +FileProps::~FileProps() +{ + sync(); + delete m_info; +} + +bool FileProps::sync() +{ + if ( !m_dirty ) + return true; + + return m_info->applyChanges(); +} + +bool FileProps::isValid() const +{ + return m_info->isValid(); +} + +TQStringList FileProps::supportedGroups() const +{ + return m_info->supportedGroups(); +} + +TQStringList FileProps::availableGroups() const +{ + return m_info->groups(); +} + +TQStringList FileProps::supportedKeys( const TQString& group ) const +{ + KFileMetaInfoGroup g = m_info->group( group ); + return g.supportedKeys(); +} + +TQStringList FileProps::availableKeys( const TQString& group ) const +{ + KFileMetaInfoGroup g = m_info->group( group ); + TQStringList allKeys = g.keys(); + TQStringList ret; + TQStringList::ConstIterator it = allKeys.begin(); + for ( ; it != allKeys.end(); ++it ) + { + if ( g.item( *it ).isValid() ) + ret.append( *it ); + } + + return ret; +} + +TQStringList FileProps::preferredKeys( const TQString& group ) const +{ + KFileMetaInfoGroup g = m_info->group( group ); + return g.preferredKeys(); +} + +TQString FileProps::getValue( const TQString& group, + const TQString& key ) const +{ + KFileMetaInfoGroup g = m_info->group( group ); + return FileProps::createKeyValue( g, key ); +} + +bool FileProps::setValue( const TQString& group, + const TQString& key, const TQString &value ) +{ + KFileMetaInfoGroup g = m_info->group( group ); + bool wasAdded = false; + if ( !g.isValid() ) + { + if ( m_info->addGroup( group ) ) + { + wasAdded = true; + g = m_info->group( group ); + } + else + return false; + } + + bool ok = g[key].setValue( value ); + + if ( !ok && wasAdded ) // remove the created group again + (void) m_info->removeGroup( group ); + + m_dirty |= ok; + return ok; +} + +TQStringList FileProps::allValues( const TQString& group ) const +{ + KFileMetaInfoGroup g = m_info->group( group ); + return FileProps::createKeyValueList( g, g.keys() ); +} + +TQStringList FileProps::preferredValues( const TQString& group ) const +{ + KFileMetaInfoGroup g = m_info->group( group ); + return FileProps::createKeyValueList( g, g.preferredKeys() ); +} + +// static helper: +// creates strings like +// "group: translatedKey: value" +TQString FileProps::createKeyValue( const KFileMetaInfoGroup& g, + const TQString& key ) +{ + static const int MAX_SPACE = 25; + KFileMetaInfoItem item = g.item( key ); + + TQString result("%1"); + result = result.arg( (item.isValid() ? item.translatedKey() : key) + ":", + -MAX_SPACE ); + result.append( beatifyValue( item.string() ) ); + + TQString group("%1"); + group = group.arg( g.translatedName() + ":", -MAX_SPACE ); + result.prepend( group ); + + return result; +} + +// static +TQStringList FileProps::createKeyValueList( const KFileMetaInfoGroup& g, + const TQStringList& keys ) +{ + TQStringList result; + TQStringList::ConstIterator it = keys.begin(); + + for ( ; it != keys.end(); ++it ) + result.append( FileProps::createKeyValue( g, *it ) ); + + return result; +} + +/////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////// + + + +// tdefile --mimetype --listsupported --listavailable --listpreferred --listwritable --getValue "key" --setValue "key=value" --allValues --preferredValues --dialog --quiet file [file...] +// "key" may be a list of keys, separated by commas +static KCmdLineOptions options[] = +{ + { "m", 0, 0 }, // short option for --mimetype + { "nomimetype", I18N_NOOP("Do not print the mimetype of the given file(s)"), 0 }, + + { "ls", 0, 0 }, // short option for --listsupported + { "listsupported ", + I18N_NOOP("List all supported metadata keys of the given file(s). " + "If mimetype is not specified, the mimetype of the given " + "files is used." ), "file" }, + + { "lp", 0, 0 }, // short option for --listpreferred + { "listpreferred ", + I18N_NOOP("List all preferred metadata keys of the given file(s). " + "If mimetype is not specified, the mimetype of the given " + "files is used." ), "file" }, + + { "la", 0, 0 }, // short option for --listavailable + { "listavailable", + I18N_NOOP("List all metadata keys which have a value in the given " + "file(s)."), 0 }, + + { "sm", 0, 0 }, // short option for --supportedMimetypes + { "supportedMimetypes", + I18N_NOOP("Prints all mimetypes for which metadata support is " + "available."), 0 }, + + { "q", 0, 0 }, // short option for --quiet + { "quiet", + I18N_NOOP("Do not print a warning when more than one file was given " + "and they do not all have the same mimetype."), 0 }, + + { "av", 0, 0 }, // short option for --allValues + { "allValues", + I18N_NOOP("Prints all metadata values, available in the given " + "file(s)."), 0 }, + + { "pv", 0, 0 }, // short option for --preferredValues + { "preferredValues", + I18N_NOOP("Prints the preferred metadata values, available in the " + "given file(s)."), 0 }, + + { "dialog", + I18N_NOOP("Opens a TDE properties dialog to allow viewing and " + "modifying of metadata of the given file(s)"), 0 }, + + { "getValue ", + I18N_NOOP("Prints the value for 'key' of the given file(s). 'key' " + "may also be a comma-separated list of keys"), 0 }, + + { "setValue ", + I18N_NOOP("Attempts to set the value 'value' for the metadata key " + "'key' for the given file(s)"), 0 }, + + { "!groups ", I18N_NOOP("The group to get values from or set values to"), + 0 }, + + { "+[files]", + I18N_NOOP("The file (or a number of files) to operate on."), 0 }, + KCmdLineLastOption +}; + + +// +// helper functions +// + +static void printSupportedMimeTypes() +{ + TQStringList allMimeTypes = KFileMetaInfoProvider::self()->supportedMimeTypes(); + if ( allMimeTypes.isEmpty() ) + { + cout << + i18n("No support for metadata extraction found.").local8Bit().data() + << endl; + return; + } + + cout << i18n("Supported MimeTypes:").local8Bit().data() << endl; + + TQStringList::ConstIterator it = allMimeTypes.begin(); + for ( ; it != allMimeTypes.end(); it++ ) + cout << (*it).local8Bit().data() << endl; +} + +// caller needs to delete the returned list! +static KFileItemList * fileItemList( const TDECmdLineArgs *args ) +{ + KFileItemList * items = new KFileItemList(); + items->setAutoDelete( true ); + for ( int i = 0; i < args->count(); i++ ) + items->append( new KFileItem( KFileItem::Unknown, + KFileItem::Unknown, + args->url( i ) )); + return items; +} + +static void showPropertiesDialog( const TDECmdLineArgs *args ) +{ + KFileItemList *items = fileItemList( args ); + new KPropertiesDialog( *items, 0L, "props dialog", true ); + delete items; +} + +static void printMimeTypes( const TDECmdLineArgs *args ) +{ + for ( int i = 0; i < args->count(); i++ ) + { + KURL url = args->url( i ); + KMimeType::Ptr mt = KMimeType::findByURL( url ); + cout << args->arg(i) << ": " << mt->comment().local8Bit().data() << " (" + << mt->name().local8Bit().data() << ")" << endl; + } +} + +static void printList( const TQStringList& list ) +{ + TQStringList::ConstIterator it = list.begin(); + for ( ; it != list.end(); ++it ) + cout << (*it).local8Bit().data() << endl; + cout << endl; +} + +static void processMetaDataOptions( const TQPtrList propList, + TDECmdLineArgs *args ) +{ +// tdefile --mimetype --supportedMimetypes --listsupported --listavailable --listpreferred --listwritable --getValue "key" --setValue "key=value" --allValues --preferredValues --dialog --quiet file [file...] +// "key" may be a list of keys, separated by commas + + TQString line("-- -------------------------------------------------------"); + FileProps *props; + TQPtrListIterator it( propList ); + for ( ; (props = it.current()); ++it ) + { + TQString file = props->fileName() + " "; + TQString fileString = line.replace( 3, file.length(), file ); + cout << TQFile::encodeName( fileString ).data() << endl; + + if ( args->isSet( "listsupported" ) ) + { + cout << "=Supported Keys=" << endl; + printList( props->supportedKeys() ); + } + if ( args->isSet( "listpreferred" ) ) + { + cout << "=Preferred Keys=" << endl; + printList( props->preferredKeys() ); + } + if ( args->isSet( "listavailable" ) ) + { + cout << "=Available Keys=" << endl; + TQStringList groups = props->availableGroups(); + TQStringList::ConstIterator git = groups.begin(); + for ( ; git != groups.end(); ++git ) + { + cout << "Group: " << (*git).local8Bit().data() << endl; + printList( props->availableKeys( *git ) ); + } + } +// if ( args->isSet( "listwritable" ) ) +// { +// cout << "TODO :)" << endl; +// } + if ( args->isSet( "getValue" ) ) + { + cout << "=Value=" << endl; + TQString key = TQString::fromLocal8Bit( args->getOption("getValue")); + TQStringList::ConstIterator git = props->groupsToUse().begin(); + for ( ; git != props->groupsToUse().end(); ++git ) + cout << props->getValue( *git, key ).local8Bit().data() << endl; + } + + if ( args->isSet( "setValue" ) ) + { + // separate key and value from the line "key=value" + TQString cmd = TQString::fromLocal8Bit( args->getOption("setValue")); + TQString key = cmd.section( '=', 0, 0 ); + TQString value = cmd.section( '=', 1 ); + + // either use supplied groups or all supported groups + // (not only the available!) + TQStringList groups = props->userSuppliedGroups() ? + props->groupsToUse() : + props->supportedGroups(); + + TQStringList::ConstIterator git = groups.begin(); + for ( ; git != groups.end(); ++git ) + props->setValue( *git, key, value ); + } + + if ( args->isSet( "allValues" ) ) + { + cout << "=All Values=" << endl; + TQStringList groups = props->availableGroups(); + TQStringList::ConstIterator group = groups.begin(); + for ( ; group != groups.end(); ++group ) + printList( props->allValues( *group ) ); + } + if ( args->isSet( "preferredValues" ) && !args->isSet("allValues") ) + { + cout << "=Preferred Values=" << endl; + TQStringList groups = props->availableGroups(); + TQStringList::ConstIterator group = groups.begin(); + for ( ; group != groups.end(); ++group ) + printList( props->preferredValues( *group ) ); + } + } + +} + +int main( int argc, char **argv ) +{ + TDEAboutData about( + "tdefile", I18N_NOOP( "tdefile" ), KFILEVERSION, + I18N_NOOP("A commandline tool to read and modify metadata of files." ), + TDEAboutData::License_LGPL, "(c) 2002, Carsten Pfeiffer", + 0 /*text*/, "http://devel-home.kde.org/~pfeiffer/", + "pfeiffer@kde.org" ); + + about.addAuthor( "Carsten Pfeiffer", 0, "pfeiffer@kde.org", + "http://devel-home.kde.org/~pfeiffer/" ); + + TDECmdLineArgs::init( argc, argv, &about ); + + TDECmdLineArgs::addCmdLineOptions( options ); + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + bool useGUI = args->isSet( "dialog" ); + + TDEApplication app( useGUI, useGUI ); + + TQPtrList m_props; + m_props.setAutoDelete( true ); + + bool quiet = args->isSet( "quiet" ); + + if ( args->isSet( "supportedMimetypes" ) ) + printSupportedMimeTypes(); + + int files = args->count(); + if ( files == 0 ) + TDECmdLineArgs::usage( i18n("No files specified") ); // exit()s + + if ( args->isSet( "dialog" ) ) + { + showPropertiesDialog( args ); + return true; + } + + TQStringList groupsToUse; + QCStringList suppliedGroups = args->getOptionList( "groups" ); + QCStringList::ConstIterator it = suppliedGroups.begin(); + for ( ; it != suppliedGroups.end(); ++it ) + groupsToUse.append( TQString::fromLocal8Bit( (*it) ) ); + + TQString mimeType; + + for ( int i = 0; i < files; i++ ) + { + if ( args->isSet( "mimetype" ) ) + printMimeTypes( args ); + + FileProps *props = new FileProps( args->url(i).path(), groupsToUse ); + if ( props->isValid() ) + m_props.append( props ); + else + { + if ( !quiet ) + { + cerr << args->arg(i) << ": " << + i18n("Cannot determine metadata").local8Bit().data() << endl; + } + delete props; + } + } + + + processMetaDataOptions( m_props, args ); + + m_props.clear(); // force destruction/sync of props + cout.flush(); + + return 0; +} diff --git a/tdeio/misc/tdefile/fileprops.h b/tdeio/misc/tdefile/fileprops.h new file mode 100644 index 000000000..45a79239d --- /dev/null +++ b/tdeio/misc/tdefile/fileprops.h @@ -0,0 +1,74 @@ +/* This file is part of the KDE libraries + Copyright (C) 2002 Carsten Pfeiffer + + library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation, version 2. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KFILEPROPS_H +#define KFILEPROPS_H + +#include + +#include + +class FileProps +{ +public: + FileProps( const TQString& path, const TQStringList& suppliedGroups ); + virtual ~FileProps(); + + bool isValid() const; + + TQString fileName() const { return m_info->path(); } + + TQStringList supportedGroups() const; + TQStringList availableGroups() const; + TQStringList translatedGroups(); + + const TQStringList& groupsToUse() const { return m_groupsToUse; } + bool userSuppliedGroups() const { return m_userSuppliedGroups; } + + TQStringList supportedKeys( const TQString& group ) const; + TQStringList availableKeys( const TQString& group ) const; + TQStringList preferredKeys( const TQString& group ) const; + + TQStringList supportedKeys() const { return m_info->supportedKeys(); } + TQStringList preferredKeys() const { return m_info->preferredKeys(); } + + TQString getValue( const TQString& group, const TQString& key ) const; + bool setValue( const TQString& group, + const TQString& key, const TQString &value ); + + TQStringList allValues( const TQString& group ) const; + TQStringList preferredValues( const TQString& group ) const; + + bool isReadOnly( const TQString& group, const TQString& key ); + +private: + static TQString createKeyValue( const KFileMetaInfoGroup& g, + const TQString& key ); + static TQStringList createKeyValueList( const KFileMetaInfoGroup&, + const TQStringList& ); + bool sync(); + + KFileMetaInfo *m_info; + bool m_dirty; + bool m_userSuppliedGroups; + + TQStringList m_groupsToUse; + +}; + +#endif // KFILEPROPS_H diff --git a/tdeio/misc/tdeio_uiserver.desktop b/tdeio/misc/tdeio_uiserver.desktop new file mode 100644 index 000000000..bba0a7c7c --- /dev/null +++ b/tdeio/misc/tdeio_uiserver.desktop @@ -0,0 +1,100 @@ +[Desktop Entry] +Type=Service +Name=tdeio_uiserver +Name[de]=Server der graphischen Oberfläche +Name[fy]=Kio_uiserver +Name[ja]=kio_uiサーバ +Name[mn]=График гадаргуугийн сервер +Name[nds]=tdeio_uiserver, Server för de graafsche Böversiet +Name[nl]=Kio_uiserver +Name[nso]=kio_uiseabi +Name[ro]=Kio_uiserver +Name[sv]=Kio-gränssnittsserver +Name[ta]=kio_uiசேவையகம் +Name[te]=కేఐఓ_యుఐసెర్వర్ +Exec=tdeio_uiserver +Comment=TDE's Progress Info UI server +Comment[af]=TDE se vordering inligting UI bediener +Comment[ar]=خادم معلومات تقدم واجهة كيدي +Comment[az]=TDE'nin İrəliləmə Bilgisi İstifadaçi Ara Üz Vericisi +Comment[be]=Сервер паведамленняў аб выкананні дзеянняў +Comment[bg]=Сървър за отчитане на прогреса (TDE's Progress Info UI server) +Comment[bn]=কে.ডি.ই. অগ্রগতি তথ্য UI সার্ভার +Comment[br]=Servijer stlenn EA Progress TDE +Comment[bs]=TDEov Progess Info UI server +Comment[ca]=Servidor d'informació de progrés del TDE +Comment[cs]=UI server zobrazující informace o průběhu +Comment[csb]=Serwer wëdowiédzë ò pòkròkù procesë +Comment[cy]=Gweinydd UI TDE i Ddangos Cynnydd +Comment[da]=TDE's fremgangsinfo-UI-server +Comment[de]=Ein UI-Server, der Fortschrittsinformationen darstellt +Comment[el]=Εξυπηρετητής πληροφοριών προόδου περιβάλλοντος χρήσης του TDE +Comment[eo]=Progresinforma servo +Comment[es]=Servidor UI de información de progreso de TDE +Comment[et]=TDE edenemise info UI server +Comment[eu]=TDEren aurrerapen-informazioen UI zerbitzaria +Comment[fa]=اطلاعات پیشرفت کارساز UI TDE +Comment[fi]=TDE:n edistymispalkin käyttöliittymäpalvelin +Comment[fr]=Serveur graphique d'infos de progression de TDE +Comment[fy]=TDE's tsjinner foar ynformaasje oer de fuortgong +Comment[gl]=Servidor UI de Información de Progreso de TDE +Comment[he]=שרת ממשק מידע ההתקדמות של TDE +Comment[hi]=केडीई का प्रोग्रेस जानकारी UI सर्वर +Comment[hr]=TDEov Progess Info UI poslužitelj +Comment[hu]=TDE folyamatinformációs kiszolgáló +Comment[id]=Perkembangan TDE mengenai info server UI +Comment[is]=Þjónn sem sýnir framvindu ferla +Comment[it]=Server informazioni avanzamento di TDE +Comment[ja]=TDE 進捗情報 UI サーバ +Comment[ka]=TDE-ს მონაცემთა გადაცემის სერვერი +Comment[kk]=TDE деректерді алу-беруді бақылау сервері +Comment[km]=ម៉ាស៊ីន​បម្រើ UI នៃ​ព័ត៌មាន​វឌ្ឍនភាព​របស់ TDE +Comment[ko]=TDE에서 보다 발전된 정보 UI 서버 +Comment[lb]=UI-Server vu TDE, dee Fortschrëttsinformatiounen uweist +Comment[lt]=TDE eigos informacijos UI serveris +Comment[lv]=TDE Progresa Info UI serveris +Comment[mk]=TDE сервер за информации за прогресот +Comment[mn]=Прогресс мэдээллээр дүрслэгдсэн хэрэглэгчийн харьцах хэсгийн сервер +Comment[ms]=Pelayan Info UI TDE +Comment[mt]=Server tal-progress tal-UI TDE +Comment[nb]=TDE UI-tjener for framgangsinfo +Comment[nds]=Server för graafsche Vörankamen-Informatschonen +Comment[ne]=TDE को प्रगति सूचना UI सर्भर +Comment[nl]=TDE's server voor informatie over de voortgang. +Comment[nn]=TDE UI-tenar for framgangsinfo +Comment[nso]=Seabi sa UI ya Tshedimoso ya Tswelopele ya TDE +Comment[oc]=Servor d'informacion de progress TDE +Comment[pa]=TDE ਦੀ ਤਰੱਕੀ ਜਾਣਕਾਰੀ UI ਸਰਵਰ +Comment[pl]=Serwer informacji o postępie procesu +Comment[pt]=Servidor de informações sobre o progresso das operações +Comment[pt_BR]=Servidor de informação de progresso do TDE +Comment[ro]=Server informaţii de progres TDE +Comment[ru]=Сервер монитора передачи данных TDE +Comment[rw]=Amakuru y'Aho bigeze ya TDE Seriveri UI +Comment[se]=TDE:a ovdánandieđuid UI-bálvá +Comment[sk]=TDE Progres Info UI server +Comment[sl]=Strežnik TDE's Progress Info UI +Comment[sq]=UI Shërbyesi për Informimin e Progresit të TDEs +Comment[sr]=TDE-ов UI сервер информација о напретку +Comment[sr@Latn]=TDE-ov UI server informacija o napretku +Comment[sv]=TDE:s server för förloppsinformation +Comment[ta]=கேடிஇயின் முன்னேற்ற தகவல் முகப்புப் சேவையகம் +Comment[te]=కెడిఈ యొక్క ప్రగతి సమాచార యూఐ సెర్వర్ +Comment[tg]=Инкишофи TDE's Info UI Сервер +Comment[th]=เซิร์ฟเวอร์แสดงข้อมูลความคืบหน้าของ TDE +Comment[tr]=TDE'nin İlerleme Bilgisi arayüz sunucusu +Comment[tt]=TDE'nıñ Alğakiteşne Küzätü servere +Comment[uk]=Сервер графічного інтерфейсу інформації про розвиток TDE +Comment[uz]=TDE'ning maʼlumot uzatishni nazorat qilish serveri +Comment[uz@cyrillic]=TDE'нинг маълумот узатишни назорат қилиш сервери +Comment[ven]=UI siva ya mafhungo a mwelaphanda a TDE +Comment[vi]=Trình phục vụ giao diện người dùng cho thông tin tiến hành của TDE. +Comment[xh]=Umcedisi we UI Wenqubela Yenkcukacha we TDE +Comment[zh_CN]=TDE 的进度信息用户界面服务器 +Comment[zh_HK]=TDE 的進度資訊介面伺服程式 +Comment[zh_TW]=TDE 的進度資訊使用者介面伺服器 +Comment[zu]=Umlekeleli we-UI Yolwazi Lwenqubo lwe-TDE +ServiceTypes= +# It is a server +X-DCOP-ServiceType=Unique +X-TDE-StartupNotify=false diff --git a/tdeio/misc/tdemailservice.cpp b/tdeio/misc/tdemailservice.cpp new file mode 100644 index 000000000..3f9b04feb --- /dev/null +++ b/tdeio/misc/tdemailservice.cpp @@ -0,0 +1,45 @@ +/* This file is part of the KDE libraries + Copyright (C) 2000 Simon Hausmann + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +static const KCmdLineOptions options[] = +{ + { "+url", 0, 0 }, + KCmdLineLastOption +}; + +int main( int argc, char **argv ) +{ + KLocale::setMainCatalogue("tdelibs"); + TDECmdLineArgs::init( argc, argv, "tdemailservice", I18N_NOOP("KMailService"), I18N_NOOP("Mail service"), "unknown" ); + TDECmdLineArgs::addCmdLineOptions( options ); + + TDEApplication a( false, false ); + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + + if ( args->count() != 1 ) + return 1; + + a.invokeMailer(KURL(args->arg(0)), a.startupId(), true); + + return 0; +} diff --git a/tdeio/misc/tdemailservice.protocol b/tdeio/misc/tdemailservice.protocol new file mode 100644 index 000000000..240c76aca --- /dev/null +++ b/tdeio/misc/tdemailservice.protocol @@ -0,0 +1,15 @@ +[Protocol] +exec=tdemailservice %u +protocol=mailto +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false +DocPath=tdeioslave/mailto.html +Icon=mail_new +Class=:internet +URIMode=mailto diff --git a/tdeio/misc/tdentlm/CMakeLists.txt b/tdeio/misc/tdentlm/CMakeLists.txt new file mode 100644 index 000000000..dc26da9a1 --- /dev/null +++ b/tdeio/misc/tdentlm/CMakeLists.txt @@ -0,0 +1,43 @@ +################################################# +# +# (C) 2010 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${TQT_INCLUDE_DIRS} + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdecore + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/tdecore +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### headers ################################### + +install(FILES tdentlm.h DESTINATION ${INCLUDE_INSTALL_DIR}/tdeio ) + + +##### tdentlm ################################### + +set( target tdentlm ) + +set( ${target}_SRCS + tdentlm.cpp des.cpp +) + +tde_add_library( ${target} SHARED + SOURCES ${${target}_SRCS} + VERSION 0.0.0 + LINK tdecore-shared + DESTINATION ${LIB_INSTALL_DIR} +) diff --git a/tdeio/misc/tdentlm/Makefile.am b/tdeio/misc/tdentlm/Makefile.am new file mode 100644 index 000000000..16164dbe3 --- /dev/null +++ b/tdeio/misc/tdentlm/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES=$(all_includes) + +lib_LTLIBRARIES = libtdentlm.la +METASOURCES = AUTO + +tdentlmincludedir = $(includedir)/tdeio +tdentlminclude_HEADERS = tdentlm.h + +libtdentlm_la_SOURCES = tdentlm.cpp des.cpp +libtdentlm_la_LDFLAGS = $(all_libraries) -version-info 0:0:0 -no-undefined +libtdentlm_la_LIBADD = $(LIB_TDECORE) $(LIB_QT) + diff --git a/tdeio/misc/tdentlm/des.cpp b/tdeio/misc/tdentlm/des.cpp new file mode 100644 index 000000000..bb4fab88b --- /dev/null +++ b/tdeio/misc/tdentlm/des.cpp @@ -0,0 +1,513 @@ + +/* Sofware DES functions + * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from + * the 1977 public-domain program by Jim Gillogly + * Modified for additional speed - 6 December 1988 Phil Karn + * Modified for parameterized key schedules - Jan 1991 Phil Karn + * Callers now allocate a key schedule as follows: + * kn = (char (*)[8])malloc(sizeof(char) * 8 * 16); + * or + * char kn[16][8]; + */ + +/* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos + * All modifications are placed under the license of libmcrypt. + */ + +/* $Id$ */ + +#include +#include +#include "des.h" + +static void permute_ip (unsigned char *inblock, DES_KEY * key, unsigned char *outblock); +static void permute_fp (unsigned char *inblock, DES_KEY * key, unsigned char *outblock); +static void perminit_ip (DES_KEY * key); +static void spinit (DES_KEY * key); +static void perminit_fp (DES_KEY * key); +static TQ_UINT32 f (DES_KEY * key, TQ_UINT32 r, char *subkey); + + +/* Tables defined in the Data Encryption Standard documents */ + +/* initial permutation IP */ +static const char ip[] = { + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7 +}; + +/* final permutation IP^-1 */ +static const char fp[] = { + 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25 +}; + +/* expansion operation matrix + * This is for reference only; it is unused in the code + * as the f() function performs it implicitly for speed + */ +#ifdef notdef +static const char ei[] = { + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1 +}; +#endif + +/* permuted choice table (key) */ +static const char pc1[] = { + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4 +}; + +/* number left rotations of pc1 */ +static const char totrot[] = { + 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 +}; + +/* permuted choice key (table) */ +static const char pc2[] = { + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 +}; + +/* The (in)famous S-boxes */ +static const char si[8][64] = { + /* S1 */ + {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}, + + /* S2 */ + {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}, + + /* S3 */ + {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}, + + /* S4 */ + {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}, + + /* S5 */ + {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}, + + /* S6 */ + {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}, + + /* S7 */ + {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}, + + /* S8 */ + {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}, + +}; + +/* 32-bit permutation function P used on the output of the S-boxes */ +static const char p32i[] = { + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25 +}; + +/* End of DES-defined tables */ + +/* Lookup tables initialized once only at startup by desinit() */ + +/* bit 0 is left-most in byte */ +static const int bytebit[] = { + 0200, 0100, 040, 020, 010, 04, 02, 01 +}; + +static const int nibblebit[] = { + 010, 04, 02, 01 +}; + +/* Allocate space and initialize DES lookup arrays + * mode == 0: standard Data Encryption Algorithm + */ +static int +desinit (DES_KEY * key) +{ + + spinit (key); + perminit_ip (key); + perminit_fp (key); + + return 0; +} + + +/* Set key (initialize key schedule array) */ +int +ntlm_des_set_key (DES_KEY * dkey, char *user_key, int /*len*/) +{ + char pc1m[56]; /* place to modify pc1 into */ + char pcr[56]; /* place to rotate pc1 into */ + int i, j, l; + int m; + + memset(dkey, 0, sizeof (DES_KEY)); + desinit (dkey); + + /* Clear key schedule */ + + + for (j = 0; j < 56; j++) + { /* convert pc1 to bits of key */ + l = pc1[j] - 1; /* integer bit location */ + m = l & 07; /* find bit */ + pc1m[j] = (user_key[l >> 3] & /* find which key byte l is in */ + bytebit[m]) /* and which bit of that byte */ + ? 1 : 0; /* and store 1-bit result */ + + } + for (i = 0; i < 16; i++) + { /* key chunk for each iteration */ + for (j = 0; j < 56; j++) /* rotate pc1 the right amount */ + pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l - 28]; + /* rotate left and right halves independently */ + for (j = 0; j < 48; j++) + { /* select bits individually */ + /* check bit that goes to kn[j] */ + if (pcr[pc2[j] - 1]) + { + /* mask it in if it's there */ + l = j % 6; + dkey->kn[i][j / 6] |= bytebit[l] >> 2; + } + } + } + return 0; +} + +/* In-place encryption of 64-bit block */ +static void +ntlm_des_encrypt (DES_KEY * key, unsigned char *block) +{ + TQ_UINT32 left, right; + char *knp; + TQ_UINT32 work[2]; /* Working data storage */ + + permute_ip (block, key, (unsigned char *) work); /* Initial Permutation */ + left = KFromToBigEndian(work[0]); + right = KFromToBigEndian(work[1]); + + /* Do the 16 rounds. + * The rounds are numbered from 0 to 15. On even rounds + * the right half is fed to f() and the result exclusive-ORs + * the left half; on odd rounds the reverse is done. + */ + knp = &key->kn[0][0]; + left ^= f (key, right, knp); + knp += 8; + right ^= f (key, left, knp); + knp += 8; + left ^= f (key, right, knp); + knp += 8; + right ^= f (key, left, knp); + knp += 8; + left ^= f (key, right, knp); + knp += 8; + right ^= f (key, left, knp); + knp += 8; + left ^= f (key, right, knp); + knp += 8; + right ^= f (key, left, knp); + knp += 8; + left ^= f (key, right, knp); + knp += 8; + right ^= f (key, left, knp); + knp += 8; + left ^= f (key, right, knp); + knp += 8; + right ^= f (key, left, knp); + knp += 8; + left ^= f (key, right, knp); + knp += 8; + right ^= f (key, left, knp); + knp += 8; + left ^= f (key, right, knp); + knp += 8; + right ^= f (key, left, knp); + + /* Left/right half swap, plus byte swap if little-endian */ + work[1] = KFromToBigEndian( left ); + work[0] = KFromToBigEndian( right ); + + permute_fp ((unsigned char *) work, key, block); /* Inverse initial permutation */ +} + +/* Permute inblock with perm */ +static void +permute_ip (unsigned char *inblock, DES_KEY * key, unsigned char *outblock) +{ + unsigned char *ib, *ob; /* ptr to input or output block */ + char *p, *q; + int j; + + /* Clear output block */ + memset(outblock, 0, 8); + + ib = inblock; + for (j = 0; j < 16; j += 2, ib++) + { /* for each input nibble */ + ob = outblock; + p = key->iperm[j][(*ib >> 4) & 0xf]; + q = key->iperm[j + 1][*ib & 0xf]; + /* and each output byte, OR the masks together */ + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + } +} + +/* Permute inblock with perm */ +static void +permute_fp (unsigned char *inblock, DES_KEY * key, unsigned char *outblock) +{ + unsigned char *ib, *ob; /* ptr to input or output block */ + char *p, *q; + int j; + + /* Clear output block */ + memset(outblock, 0, 8); + + ib = inblock; + for (j = 0; j < 16; j += 2, ib++) + { /* for each input nibble */ + ob = outblock; + p = key->fperm[j][(*ib >> 4) & 0xf]; + q = key->fperm[j + 1][*ib & 0xf]; + /* and each output byte, OR the masks together */ + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + *ob++ |= *p++ | *q++; + } +} + +/* The nonlinear function f(r,k), the heart of DES */ +static TQ_UINT32 +f (DES_KEY * key, TQ_UINT32 r, char *subkey) +{ + TQ_UINT32 *spp; + TQ_UINT32 rval, rt; + int er; + +#ifdef TRACE + printf ("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ", + r, + subkey[0], subkey[1], subkey[2], + subkey[3], subkey[4], subkey[5], subkey[6], subkey[7]); +#endif + /* Run E(R) ^ K through the combined S & P boxes. + * This code takes advantage of a convenient regularity in + * E, namely that each group of 6 bits in E(R) feeding + * a single S-box is a contiguous segment of R. + */ + subkey += 7; + + /* Compute E(R) for each block of 6 bits, and run thru boxes */ + er = ((int) r << 1) | ((r & 0x80000000) ? 1 : 0); + spp = &key->sp[7][0]; + rval = spp[(er ^ *subkey--) & 0x3f]; + spp -= 64; + rt = (TQ_UINT32) r >> 3; + rval |= spp[((int) rt ^ *subkey--) & 0x3f]; + spp -= 64; + rt >>= 4; + rval |= spp[((int) rt ^ *subkey--) & 0x3f]; + spp -= 64; + rt >>= 4; + rval |= spp[((int) rt ^ *subkey--) & 0x3f]; + spp -= 64; + rt >>= 4; + rval |= spp[((int) rt ^ *subkey--) & 0x3f]; + spp -= 64; + rt >>= 4; + rval |= spp[((int) rt ^ *subkey--) & 0x3f]; + spp -= 64; + rt >>= 4; + rval |= spp[((int) rt ^ *subkey--) & 0x3f]; + spp -= 64; + rt >>= 4; + rt |= (r & 1) << 5; + rval |= spp[((int) rt ^ *subkey) & 0x3f]; +#ifdef TRACE + printf (" %08lx\n", rval); +#endif + return rval; +} + +/* initialize a perm array */ +static void +perminit_ip (DES_KEY * key) +{ + int l, j, k; + int i, m; + + /* Clear the permutation array */ + memset(key->iperm, 0, 16 * 16 * 8); + + for (i = 0; i < 16; i++) /* each input nibble position */ + for (j = 0; j < 16; j++) /* each possible input nibble */ + for (k = 0; k < 64; k++) + { /* each output bit position */ + l = ip[k] - 1; /* where does this bit come from */ + if ((l >> 2) != i) /* does it come from input posn? */ + continue; /* if not, bit k is 0 */ + if (!(j & nibblebit[l & 3])) + continue; /* any such bit in input? */ + m = k & 07; /* which bit is this in the byte */ + key->iperm[i][j][k >> 3] |= bytebit[m]; + } +} + +static void +perminit_fp (DES_KEY * key) +{ + int l, j, k; + int i, m; + + /* Clear the permutation array */ + memset(key->fperm, 0, 16 * 16 * 8); + + for (i = 0; i < 16; i++) /* each input nibble position */ + for (j = 0; j < 16; j++) /* each possible input nibble */ + for (k = 0; k < 64; k++) + { /* each output bit position */ + l = fp[k] - 1; /* where does this bit come from */ + if ((l >> 2) != i) /* does it come from input posn? */ + continue; /* if not, bit k is 0 */ + if (!(j & nibblebit[l & 3])) + continue; /* any such bit in input? */ + m = k & 07; /* which bit is this in the byte */ + key->fperm[i][j][k >> 3] |= bytebit[m]; + } +} + +/* Initialize the lookup table for the combined S and P boxes */ +static void +spinit (DES_KEY * key) +{ + char pbox[32]; + int p, i, s, j, rowcol; + TQ_UINT32 val; + + /* Compute pbox, the inverse of p32i. + * This is easier to work with + */ + for (p = 0; p < 32; p++) + { + for (i = 0; i < 32; i++) + { + if (p32i[i] - 1 == p) + { + pbox[p] = i; + break; + } + } + } + for (s = 0; s < 8; s++) + { /* For each S-box */ + for (i = 0; i < 64; i++) + { /* For each possible input */ + val = 0; + /* The row number is formed from the first and last + * bits; the column number is from the middle 4 + */ + rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf); + for (j = 0; j < 4; j++) + { /* For each output bit */ + if (si[s][rowcol] & (8 >> j)) + { + val |= 1L << (31 - pbox[4 * s + j]); + } + } + key->sp[s][i] = val; + } + } +} + +int +ntlm_des_ecb_encrypt (const void *plaintext, int len, DES_KEY * akey, + unsigned char output[8]) +{ + int j; + const unsigned char *plain = (const unsigned char *) plaintext; + + for (j = 0; j < len / 8; j++) + { + memcpy (&output[j * 8], &plain[j * 8], 8); + ntlm_des_encrypt (akey, &output[j * 8]); + } + + if (j == 0 && len != 0) + return -1; /* no blocks were encrypted */ + return 0; +} diff --git a/tdeio/misc/tdentlm/des.h b/tdeio/misc/tdentlm/des.h new file mode 100644 index 000000000..0f6f59dc9 --- /dev/null +++ b/tdeio/misc/tdentlm/des.h @@ -0,0 +1,19 @@ +#ifndef KNTLM_DES_H +#define KNTLM_DES_H + +#include + +typedef struct des_key +{ + char kn[16][8]; + TQ_UINT32 sp[8][64]; + char iperm[16][16][8]; + char fperm[16][16][8]; +} DES_KEY; + +int +ntlm_des_ecb_encrypt (const void *plaintext, int len, DES_KEY * akey, unsigned char output[8]); +int +ntlm_des_set_key (DES_KEY * dkey, char *user_key, int len); + +#endif /* KNTLM_DES_H */ diff --git a/tdeio/misc/tdentlm/kswap.h b/tdeio/misc/tdentlm/kswap.h new file mode 100644 index 000000000..9eca243de --- /dev/null +++ b/tdeio/misc/tdentlm/kswap.h @@ -0,0 +1,428 @@ +/* + This file is part of the KDE libraries. + Copyright (c) 2004 Szombathelyi Gyrgy + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KSWAP_H +#define KSWAP_H + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +/** + * \defgroup KSWAP Byte-swapping functions + * kswap.h contains functions that will help converting + * 16, 32 and 64 bit length data between little-endian and + * big-endian representations. + * + * The KSWAP_16, KSWAP_32 and KSWAP_64 functions are always + * swaps the byte order of the supplied argument (which should be + * 16, 32 or 64 bit wide). These functions are inline, and tries to + * use the most optimized function of the underlying system + * (bswap_xx functions from byteswap.h in GLIBC, or ntohs and ntohl + * on little-endian machines, and if neither are applicable, some fast + * custom code). + * + * The KFromTo{Little|Big}Endian functions are for converting big-endian and + * little-endian data to and from the machine endianness. + */ + +#ifdef HAVE_BYTESWAP_H +#include + + inline TQ_UINT16 KSWAP_16( TQ_UINT16 b ) { return bswap_16( b ); } + inline TQ_INT16 KSWAP_16( TQ_INT16 b ) { return bswap_16( (TQ_UINT16)b ); } + inline TQ_UINT32 KSWAP_32( TQ_UINT32 b ) { return bswap_32( b ); } + inline TQ_INT32 KSWAP_32( TQ_INT32 b ) { return bswap_32( (TQ_UINT32)b ); } + inline TQ_UINT64 KSWAP_64( TQ_UINT64 b ) { return bswap_64( b ); } + inline TQ_INT64 KSWAP_64( TQ_INT64 b ) { return bswap_64( (TQ_UINT64)b ); } + +#else /* HAVE_BYTESWAP_H */ +#ifdef WORDS_BIGENDIAN + inline TQ_UINT16 KSWAP_16( TQ_UINT16 b ) + { + return (((b) & 0x00ff) << 8 | ((b) & 0xff00) >> 8); + } + + inline TQ_INT16 KSWAP_16( TQ_INT16 b ) + { + return ((((TQ_UINT16)b) & 0x00ff) << 8 | (((TQ_UINT16)b) & 0xff00) >> 8); + } + + inline TQ_UINT32 KSWAP_32( TQ_UINT32 b ) + { + return + ((((b) & 0xff000000) >> 24) | (((b) & 0x00ff0000) >> 8) | \ + (((b) & 0x0000ff00) << 8) | (((b) & 0x000000ff) << 24)); + } + + inline TQ_INT32 KSWAP_32( TQ_INT32 b ) + { + return + (((((TQ_UINT32)b) & 0xff000000) >> 24) | ((((TQ_UINT32)b) & 0x00ff0000) >> 8) | \ + ((((TQ_UINT32)b) & 0x0000ff00) << 8) | ((((TQ_UINT32)b) & 0x000000ff) << 24)); + } +#else /* WORDS_BIGENDIAN */ +#include +#include + + inline TQ_UINT16 KSWAP_16( TQ_UINT16 b ) { return htons(b); } + inline TQ_INT16 KSWAP_16( TQ_INT16 b ) { return htons((TQ_UINT16)b); } + inline TQ_UINT32 KSWAP_32( TQ_UINT32 b ) { return htonl(b); } + inline TQ_INT32 KSWAP_32( TQ_INT32 b ) { return htonl((TQ_UINT32)b); } +#endif + inline TQ_UINT64 KSWAP_64( TQ_UINT64 b ) + { + union { + TQ_UINT64 ll; + TQ_UINT32 l[2]; + } w, r; + w.ll = b; + r.l[0] = KSWAP_32( w.l[1] ); + r.l[1] = KSWAP_32( w.l[0] ); + return r.ll; + } + + inline TQ_INT64 KSWAP_64( TQ_INT64 b ) + { + union { + TQ_UINT64 ll; + TQ_UINT32 l[2]; + } w, r; + w.ll = (TQ_UINT64) b; + r.l[0] = KSWAP_32( w.l[1] ); + r.l[1] = KSWAP_32( w.l[0] ); + return r.ll; + } +#endif /* !HAVE_BYTESWAP_H */ + +/** + * \ingroup KSWAP + * Converts a 16 bit unsigned value from/to big-endian byte order to/from the machine order. + */ +inline TQ_UINT16 KFromToBigEndian( TQ_UINT16 b ) +{ +#ifdef WORDS_BIGENDIAN + return b; +#else + return KSWAP_16(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 16 bit unsigned array from/to big-endian byte order to/from the machine order. + */ +inline void KFromToBigEndian( TQ_UINT16 *out, TQ_UINT16 *in, uint len ) +{ +#ifdef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<1 ) ; +#else + while ( len>0 ) { *out = KSWAP_16( *in ); out++; in++; len--; } +#endif +} + +/** + * \ingroup KSWAP + * Converts a 32 bit unsigned value from/to big-endian byte order to/from the machine order. + */ +inline TQ_UINT32 KFromToBigEndian( TQ_UINT32 b ) +{ +#ifdef WORDS_BIGENDIAN + return b; +#else + return KSWAP_32(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 32 bit unsigned array from/to big-endian byte order to/from the machine order. + */ +inline void KFromToBigEndian( TQ_UINT32 *out, TQ_UINT32 *in, uint len ) +{ +#ifdef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<2 ) ; +#else + while ( len>0 ) { *out = KSWAP_32( *in ); out++; in++; len--; } +#endif +} + +/** + * \ingroup KSWAP + * Converts a 64 bit unsigned value from/to big-endian byte order to/from the machine order. + */ +inline TQ_UINT64 KFromToBigEndian( TQ_UINT64 b ) +{ +#ifdef WORDS_BIGENDIAN + return b; +#else + return KSWAP_64(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 64 bit unsigned array from/to big-endian byte order to/from the machine order. + */ +inline void KFromToBigEndian( TQ_UINT64 *out, TQ_UINT64 *in, uint len ) +{ +#ifdef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<3 ) ; +#else + while ( len>0 ) { *out = KSWAP_64( *in ); out++; in++; len--; } +#endif +} + +/** + * \ingroup KSWAP + * Converts a 16 bit signed value from/to big-endian byte order to/from the machine order. + */ +inline TQ_INT16 KFromToBigEndian( TQ_INT16 b ) +{ +#ifdef WORDS_BIGENDIAN + return b; +#else + return KSWAP_16(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 16 bit signed array from/to big-endian byte order to/from the machine order. + */ +inline void KFromToBigEndian( TQ_INT16 *out, TQ_INT16 *in, uint len ) +{ +#ifdef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<1 ) ; +#else + while ( len>0 ) { *out = KSWAP_16( *in ); out++; in++; len--; } +#endif +} + +/** + * \ingroup KSWAP + * Converts a 32 bit signed value from/to big-endian byte order to/from the machine order. + */ +inline TQ_INT32 KFromToBigEndian( TQ_INT32 b ) +{ +#ifdef WORDS_BIGENDIAN + return b; +#else + return KSWAP_32(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 32 bit signed array from/to big-endian byte order to/from the machine order. + */ +inline void KFromToBigEndian( TQ_INT32 *out, TQ_INT32 *in, uint len ) +{ +#ifdef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<2 ) ; +#else + while ( len>0 ) { *out = KSWAP_32( *in ); out++; in++; len--; } +#endif +} + +/** + * \ingroup KSWAP + * Converts a 64 bit signed value from/to big-endian byte order to/from the machine order. + */ +inline TQ_INT64 KFromToBigEndian( TQ_INT64 b ) +{ +#ifdef WORDS_BIGENDIAN + return b; +#else + return KSWAP_64(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 64 bit signed array from/to big-endian byte order to/from the machine order. + */ +inline void KFromToBigEndian( TQ_INT64 *out, TQ_INT64 *in, uint len ) +{ +#ifdef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<3 ) ; +#else + while ( len>0 ) { *out = KSWAP_64( *in ); out++; in++; len--; } +#endif +} + +/** + * \ingroup KSWAP + * Converts a 16 bit unsigned value from/to little-endian byte order to/from the machine order. + */ +inline TQ_UINT16 KFromToLittleEndian( TQ_UINT16 b ) +{ +#ifndef WORDS_BIGENDIAN + return b; +#else + return KSWAP_16(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 16 bit unsigned array from/to little-endian byte order to/from the machine order. + */ +inline void KFromToLittleEndian( TQ_UINT16 *out, TQ_UINT16 *in, uint len ) +{ +#ifndef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<1 ) ; +#else + while ( len>0 ) { *out = KSWAP_16( *in ); out++; in++; len--; } +#endif +} + +/** + * \ingroup KSWAP + * Converts a 32 bit unsigned value from/to little-endian byte order to/from the machine order. + */ +inline TQ_UINT32 KFromToLittleEndian( TQ_UINT32 b ) +{ +#ifndef WORDS_BIGENDIAN + return b; +#else + return KSWAP_32(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 32 bit unsigned array from/to little-endian byte order to/from the machine order. + */ +inline void KFromToLittleEndian( TQ_UINT32 *out, TQ_UINT32 *in, uint len ) +{ +#ifndef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<2 ) ; +#else + while ( len>0 ) { *out = KSWAP_32( *in ); out++; in++; len--; } +#endif +} + +/** + * \ingroup KSWAP + * Converts a 64 bit unsigned value from/to little-endian byte order to/from the machine order. + */ +inline TQ_UINT64 KFromToLittleEndian( TQ_UINT64 b ) +{ +#ifndef WORDS_BIGENDIAN + return b; +#else + return KSWAP_64(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 64 bit unsigned array from/to little-endian byte order to/from the machine order. + */ +inline void KFromToLittleEndian( TQ_UINT64 *out, TQ_UINT64 *in, uint len ) +{ +#ifndef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<3 ) ; +#else + while ( len>0 ) { *out = KSWAP_64( *in ); out++; in++; len--; } +#endif +} + +/** + * \ingroup KSWAP + * Converts a 16 bit signed value from/to little-endian byte order to/from the machine order. + */ +inline TQ_INT16 KFromToLittleEndian( TQ_INT16 b ) +{ +#ifndef WORDS_BIGENDIAN + return b; +#else + return KSWAP_16(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 16 bit signed array from/to little-endian byte order to/from the machine order. + */ +inline void KFromToLittleEndian( TQ_INT16 *out, TQ_INT16 *in, uint len ) +{ +#ifndef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<1 ) ; +#else + while ( len>0 ) { *out = KSWAP_16( *in ); out++; in++; len--; } +#endif +} + +/** + * \ingroup KSWAP + * Converts a 32 bit signed value from/to little-endian byte order to/from the machine order. + */ +inline TQ_INT32 KFromToLittleEndian( TQ_INT32 b ) +{ +#ifndef WORDS_BIGENDIAN + return b; +#else + return KSWAP_32(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 32 bit signed array from/to little-endian byte order to/from the machine order. + */ +inline void KFromToLittleEndian( TQ_INT32 *out, TQ_INT32 *in, uint len ) +{ +#ifndef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<2 ) ; +#else + while ( len>0 ) { *out = KSWAP_32( *in ); out++; in++; len--; } +#endif +} + +/** + * \ingroup KSWAP + * Converts a 64 bit signed value from/to little-endian byte order to/from the machine order. + */ +inline TQ_INT64 KFromToLittleEndian( TQ_INT64 b ) +{ +#ifndef WORDS_BIGENDIAN + return b; +#else + return KSWAP_64(b); +#endif +} + +/** + * \ingroup KSWAP + * Converts a 64 bit signed array from/to little-endian byte order to/from the machine order. + */ +inline void KFromToLittleEndian( TQ_INT64 *out, TQ_INT64 *in, uint len ) +{ +#ifndef WORDS_BIGENDIAN + if ( out != in ) memcpy( out, in, len<<3 ) ; +#else + while ( len>0 ) { *out = KSWAP_64( *in ); out++; in++; len--; } +#endif +} + +#endif /* KSWAP_H */ diff --git a/tdeio/misc/tdentlm/tdentlm.cpp b/tdeio/misc/tdentlm/tdentlm.cpp new file mode 100644 index 000000000..2ef5d1cb6 --- /dev/null +++ b/tdeio/misc/tdentlm/tdentlm.cpp @@ -0,0 +1,389 @@ +/* This file is part of the KDE libraries + Copyright (c) 2004 Szombathelyi Gy�gy + + The implementation is based on the documentation and sample code + at http://davenport.sourceforge.net/ntlm.html + The DES encryption functions are from libntlm + at http://josefsson.org/libntlm/ + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include +#include +#include +#include + +#include "des.h" +#include "tdentlm.h" + +TQString KNTLM::getString( const TQByteArray &buf, const SecBuf &secbuf, bool unicode ) +{ + //watch for buffer overflows + TQ_UINT32 offset; + TQ_UINT16 len; + offset = KFromToLittleEndian((TQ_UINT32)secbuf.offset); + len = KFromToLittleEndian(secbuf.len); + if ( offset > buf.size() || + offset + len > buf.size() ) return TQString::null; + + TQString str; + const char *c = buf.data() + offset; + + if ( unicode ) { + str = UnicodeLE2TQString( (TQChar*) c, len >> 1 ); + } else { + str = TQString::fromLatin1( c, len ); + } + return str; +} + +TQByteArray KNTLM::getBuf( const TQByteArray &buf, const SecBuf &secbuf ) +{ + TQByteArray ret; + TQ_UINT32 offset; + TQ_UINT16 len; + offset = KFromToLittleEndian((TQ_UINT32)secbuf.offset); + len = KFromToLittleEndian(secbuf.len); + //watch for buffer overflows + if ( offset > buf.size() || + offset + len > buf.size() ) return ret; + ret.duplicate( buf.data() + offset, buf.size() ); + return ret; +} + +void KNTLM::addString( TQByteArray &buf, SecBuf &secbuf, const TQString &str, bool unicode ) +{ + TQByteArray tmp; + + if ( unicode ) { + tmp = QString2UnicodeLE( str ); + addBuf( buf, secbuf, tmp ); + } else { + const char *c; + c = str.latin1(); + tmp.setRawData( c, str.length() ); + addBuf( buf, secbuf, tmp ); + tmp.resetRawData( c, str.length() ); + } +} + +void KNTLM::addBuf( TQByteArray &buf, SecBuf &secbuf, TQByteArray &data ) +{ + TQ_UINT32 offset; + TQ_UINT16 len, maxlen; + offset = (buf.size() + 1) & 0xfffffffe; + len = data.size(); + maxlen = data.size(); + + secbuf.offset = KFromToLittleEndian((TQ_UINT32)offset); + secbuf.len = KFromToLittleEndian(len); + secbuf.maxlen = KFromToLittleEndian(maxlen); + buf.resize( offset + len ); + memcpy( buf.data() + offset, data.data(), data.size() ); +} + +bool KNTLM::getNegotiate( TQByteArray &negotiate, const TQString &domain, const TQString &workstation, TQ_UINT32 flags ) +{ + TQByteArray rbuf( sizeof(Negotiate) ); + + rbuf.fill( 0 ); + memcpy( rbuf.data(), "NTLMSSP", 8 ); + ((Negotiate*) rbuf.data())->msgType = KFromToLittleEndian( (TQ_UINT32)1 ); + if ( !domain.isEmpty() ) { + flags |= Negotiate_Domain_Supplied; + addString( rbuf, ((Negotiate*) rbuf.data())->domain, domain ); + } + if ( !workstation.isEmpty() ) { + flags |= Negotiate_WS_Supplied; + addString( rbuf, ((Negotiate*) rbuf.data())->domain, workstation ); + } + ((Negotiate*) rbuf.data())->flags = KFromToLittleEndian( flags ); + negotiate = rbuf; + return true; +} + +bool KNTLM::getAuth( TQByteArray &auth, const TQByteArray &challenge, const TQString &user, + const TQString &password, const TQString &domain, const TQString &workstation, + bool forceNTLM, bool forceNTLMv2 ) +{ + TQByteArray rbuf( sizeof(Auth) ); + Challenge *ch = (Challenge *) challenge.data(); + TQByteArray response; + uint chsize = challenge.size(); + bool unicode = false; + TQString dom; + + //challenge structure too small + if ( chsize < 32 ) return false; + + unicode = KFromToLittleEndian(ch->flags) & Negotiate_Unicode; + if ( domain.isEmpty() ) + dom = getString( challenge, ch->targetName, unicode ); + else + dom = domain; + + rbuf.fill( 0 ); + memcpy( rbuf.data(), "NTLMSSP", 8 ); + ((Auth*) rbuf.data())->msgType = KFromToLittleEndian( (TQ_UINT32)3 ); + ((Auth*) rbuf.data())->flags = ch->flags; + TQByteArray targetInfo = getBuf( challenge, ch->targetInfo ); + +// if ( forceNTLMv2 || (!targetInfo.isEmpty() && (KFromToLittleEndian(ch->flags) & Negotiate_Target_Info)) /* may support NTLMv2 */ ) { +// if ( KFromToLittleEndian(ch->flags) & Negotiate_NTLM ) { +// if ( targetInfo.isEmpty() ) return false; +// response = getNTLMv2Response( dom, user, password, targetInfo, ch->challengeData ); +// addBuf( rbuf, ((Auth*) rbuf.data())->ntResponse, response ); +// } else { +// if ( !forceNTLM ) { +// response = getLMv2Response( dom, user, password, ch->challengeData ); +// addBuf( rbuf, ((Auth*) rbuf.data())->lmResponse, response ); +// } else +// return false; +// } +// } else { //if no targetinfo structure and NTLMv2 or LMv2 not forced, try the older methods + + response = getNTLMResponse( password, ch->challengeData ); + addBuf( rbuf, ((Auth*) rbuf.data())->ntResponse, response ); + response = getLMResponse( password, ch->challengeData ); + addBuf( rbuf, ((Auth*) rbuf.data())->lmResponse, response ); +// } + if ( !dom.isEmpty() ) + addString( rbuf, ((Auth*) rbuf.data())->domain, dom, unicode ); + addString( rbuf, ((Auth*) rbuf.data())->user, user, unicode ); + if ( !workstation.isEmpty() ) + addString( rbuf, ((Auth*) rbuf.data())->workstation, workstation, unicode ); + + auth = rbuf; + + return true; +} + +TQByteArray KNTLM::getLMResponse( const TQString &password, const unsigned char *challenge ) +{ + TQByteArray hash, answer; + + hash = lmHash( password ); + hash.resize( 21 ); + memset( hash.data() + 16, 0, 5 ); + answer = lmResponse( hash, challenge ); + hash.fill( 0 ); + return answer; +} + +TQByteArray KNTLM::lmHash( const TQString &password ) +{ + TQByteArray keyBytes( 14 ); + TQByteArray hash( 16 ); + DES_KEY ks; + const char *magic = "KGS!@#$%"; + + keyBytes.fill( 0 ); + strncpy( keyBytes.data(), password.upper().latin1(), 14 ); + + convertKey( (unsigned char*) keyBytes.data(), &ks ); + ntlm_des_ecb_encrypt( magic, 8, &ks, (unsigned char*) hash.data() ); + + convertKey( (unsigned char*) keyBytes.data() + 7, &ks ); + ntlm_des_ecb_encrypt( magic, 8, &ks, (unsigned char*) hash.data() + 8 ); + + keyBytes.fill( 0 ); + memset( &ks, 0, sizeof (ks) ); + + return hash; +} + +TQByteArray KNTLM::lmResponse( const TQByteArray &hash, const unsigned char *challenge ) +{ + DES_KEY ks; + TQByteArray answer( 24 ); + + convertKey( (unsigned char*) hash.data(), &ks ); + ntlm_des_ecb_encrypt( challenge, 8, &ks, (unsigned char*) answer.data() ); + + convertKey( (unsigned char*) hash.data() + 7, &ks ); + ntlm_des_ecb_encrypt( challenge, 8, &ks, (unsigned char*) answer.data() + 8 ); + + convertKey( (unsigned char*) hash.data() + 14, &ks ); + ntlm_des_ecb_encrypt( challenge, 8, &ks, (unsigned char*) answer.data() + 16 ); + + memset( &ks, 0, sizeof (ks) ); + return answer; +} + +TQByteArray KNTLM::getNTLMResponse( const TQString &password, const unsigned char *challenge ) +{ + TQByteArray hash, answer; + + hash = ntlmHash( password ); + hash.resize( 21 ); + memset( hash.data() + 16, 0, 5 ); + answer = lmResponse( hash, challenge ); + hash.fill( 0 ); + return answer; +} + +TQByteArray KNTLM::ntlmHash( const TQString &password ) +{ + KMD4::Digest digest; + TQByteArray ret, unicode; + unicode = QString2UnicodeLE( password ); + + KMD4 md4( unicode ); + md4.rawDigest( digest ); + ret.duplicate( (const char*) digest, sizeof( digest ) ); + return ret; +} + +TQByteArray KNTLM::getNTLMv2Response( const TQString &target, const TQString &user, + const TQString &password, const TQByteArray &targetInformation, + const unsigned char *challenge ) +{ + TQByteArray hash = ntlmv2Hash( target, user, password ); + TQByteArray blob = createBlob( targetInformation ); + return lmv2Response( hash, blob, challenge ); +} + +TQByteArray KNTLM::getLMv2Response( const TQString &target, const TQString &user, + const TQString &password, const unsigned char *challenge ) +{ + TQByteArray hash = ntlmv2Hash( target, user, password ); + TQByteArray clientChallenge( 8 ); + for ( uint i = 0; i<8; i++ ) { + clientChallenge.data()[i] = TDEApplication::random() % 0xff; + } + return lmv2Response( hash, clientChallenge, challenge ); +} + +TQByteArray KNTLM::ntlmv2Hash( const TQString &target, const TQString &user, const TQString &password ) +{ + TQByteArray hash1 = ntlmHash( password ); + TQByteArray key, ret; + TQString id = user.upper() + target.upper(); + key = QString2UnicodeLE( id ); + ret = hmacMD5( key, hash1 ); + return ret; +} + +TQByteArray KNTLM::lmv2Response( const TQByteArray &hash, + const TQByteArray &clientData, const unsigned char *challenge ) +{ + TQByteArray data( 8 + clientData.size() ); + memcpy( data.data(), challenge, 8 ); + memcpy( data.data() + 8, clientData.data(), clientData.size() ); + TQByteArray mac = hmacMD5( data, hash ); + mac.resize( 16 + clientData.size() ); + memcpy( mac.data() + 16, clientData.data(), clientData.size() ); + return mac; +} + +TQByteArray KNTLM::createBlob( const TQByteArray &targetinfo ) +{ + TQByteArray blob( sizeof(Blob) + 4 + targetinfo.size() ); + blob.fill( 0 ); + + Blob *bl = (Blob *) blob.data(); + bl->signature = KFromToBigEndian( (TQ_UINT32) 0x01010000 ); + TQ_UINT64 now = TQDateTime::currentDateTime().toTime_t(); + now += (TQ_UINT64)3600*(TQ_UINT64)24*(TQ_UINT64)134774; + now *= (TQ_UINT64)10000000; + bl->timestamp = KFromToLittleEndian( now ); + for ( uint i = 0; i<8; i++ ) { + bl->challenge[i] = TDEApplication::random() % 0xff; + } + memcpy( blob.data() + sizeof(Blob), targetinfo.data(), targetinfo.size() ); + return blob; +} + +TQByteArray KNTLM::hmacMD5( const TQByteArray &data, const TQByteArray &key ) +{ + TQ_UINT8 ipad[64], opad[64]; + KMD5::Digest digest; + TQByteArray ret; + + memset( ipad, 0x36, sizeof(ipad) ); + memset( opad, 0x5c, sizeof(opad) ); + for ( int i = key.size()-1; i >= 0; i-- ) { + ipad[i] ^= key[i]; + opad[i] ^= key[i]; + } + + TQByteArray content( data.size()+64 ); + memcpy( content.data(), ipad, 64 ); + memcpy( content.data() + 64, data.data(), data.size() ); + KMD5 md5( content ); + md5.rawDigest( digest ); + content.resize( sizeof(digest) + 64 ); + memcpy( content.data(), opad, 64 ); + memcpy( content.data() + 64, digest, sizeof(digest) ); + md5.reset(); + md5.update( content ); + md5.rawDigest( digest ); + + ret.duplicate( (const char*) digest, sizeof( digest ) ); + return ret; +} + +/* +* turns a 56 bit key into the 64 bit, odd parity key and sets the key. +* The key schedule ks is also set. +*/ +void KNTLM::convertKey( unsigned char *key_56, void* ks ) +{ + unsigned char key[8]; + + key[0] = key_56[0]; + key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1); + key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2); + key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3); + key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4); + key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5); + key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6); + key[7] = (key_56[6] << 1) & 0xFF; + + for ( uint i=0; i<8; i++ ) { + unsigned char b = key[i]; + bool needsParity = (((b>>7) ^ (b>>6) ^ (b>>5) ^ (b>>4) ^ (b>>3) ^ (b>>2) ^ (b>>1)) & 0x01) == 0; + if ( needsParity ) + key[i] |= 0x01; + else + key[i] &= 0xfe; + } + + ntlm_des_set_key ( (DES_KEY*) ks, (char*) &key, sizeof (key)); + + memset (&key, 0, sizeof (key)); +} + +TQByteArray KNTLM::QString2UnicodeLE( const TQString &target ) +{ + TQByteArray unicode( target.length() * 2 ); + for ( uint i = 0; i < target.length(); i++ ) { + ((TQ_UINT16*)unicode.data())[ i ] = KFromToLittleEndian( target[i].unicode() ); + } + return unicode; +} + +TQString KNTLM::UnicodeLE2TQString( const TQChar* data, uint len ) +{ + TQString ret; + for ( uint i = 0; i < len; i++ ) { + ret += KFromToLittleEndian( data[ i ].unicode() ); + } + return ret; +} diff --git a/tdeio/misc/tdentlm/tdentlm.h b/tdeio/misc/tdentlm/tdentlm.h new file mode 100644 index 000000000..06b8febab --- /dev/null +++ b/tdeio/misc/tdentlm/tdentlm.h @@ -0,0 +1,233 @@ +/* + This file is part of the KDE libraries. + Copyright (c) 2004 Szombathelyi Gyrgy + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef KNTLM_H +#define KNTLM_H + +#include +#include +#include + +#include + +/** + * @short KNTLM class implements the NTLM authentication protocol. + * + * The KNTLM class is useful for creating the authentication structures which + * can be used for various servers which implements NTLM type authentication. + * A comprehensive description of the NTLM authentication protocol can be found + * at http://davenport.sourceforge.net/ntlm.html + * The class also contains methods to create the LanManager and NT (MD4) hashes + * of a password. + * This class doesn't maintain any state information, so all methods are static. + */ + +class TDEIO_EXPORT KNTLM { +public: + + enum Flags { + Negotiate_Unicode = 0x00000001, + Negotiate_OEM = 0x00000002, + Request_Target = 0x00000004, + Negotiate_Sign = 0x00000010, + Negotiate_Seal = 0x00000020, + Negotiate_Datagram_Style = 0x00000040, + Negotiate_LM_Key = 0x00000080, + Negotiate_Netware = 0x00000100, + Negotiate_NTLM = 0x00000200, + Negotiate_Domain_Supplied = 0x00001000, + Negotiate_WS_Supplied = 0x00002000, + Negotiate_Local_Call = 0x00004000, + Negotiate_Always_Sign = 0x00008000, + Target_Type_Domain = 0x00010000, + Target_Type_Server = 0x00020000, + Target_Type_Share = 0x00040000, + Negotiate_NTLM2_Key = 0x00080000, + Request_Init_Response = 0x00100000, + Request_Accept_Response = 0x00200000, + Request_NonNT_Key = 0x00400000, + Negotiate_Target_Info = 0x00800000, + Negotiate_128 = 0x20000000, + Negotiate_Key_Exchange = 0x40000000, + Negotiate_56 = 0x80000000 + }; + + typedef struct + { + TQ_UINT16 len; + TQ_UINT16 maxlen; + TQ_UINT32 offset; + } SecBuf; + + /** + * The NTLM Type 1 structure + */ + typedef struct + { + char signature[8]; /* "NTLMSSP\0" */ + TQ_UINT32 msgType; /* 1 */ + TQ_UINT32 flags; + SecBuf domain; + SecBuf workstation; + } Negotiate; + + /** + * The NTLM Type 2 structure + */ + typedef struct + { + char signature[8]; + TQ_UINT32 msgType; /* 2 */ + SecBuf targetName; + TQ_UINT32 flags; + TQ_UINT8 challengeData[8]; + TQ_UINT32 context[2]; + SecBuf targetInfo; + } Challenge; + + /** + * The NTLM Type 3 structure + */ + typedef struct + { + char signature[8]; + TQ_UINT32 msgType; /* 3 */ + SecBuf lmResponse; + SecBuf ntResponse; + SecBuf domain; + SecBuf user; + SecBuf workstation; + SecBuf sessionKey; + TQ_UINT32 flags; + } Auth; + + typedef struct + { + TQ_UINT32 signature; + TQ_UINT32 reserved; + TQ_UINT64 timestamp; + TQ_UINT8 challenge[8]; + TQ_UINT8 unknown[4]; + //Target info block - variable length + } Blob; + + /** + * Creates the initial message (type 1) which should be sent to the server. + * + * @param negotiate - a buffer where the Type 1 message will returned. + * @param domain - the domain name which should be send with the message. + * @param workstation - the workstation name which should be send with the message. + * @param flags - various flags, in most cases the defaults will good. + * + * @return true if creating the structure succeeds, false otherwise. + */ + static bool getNegotiate( TQByteArray &negotiate, const TQString &domain = TQString::null, + const TQString &workstation = TQString::null, + TQ_UINT32 flags = Negotiate_Unicode | Request_Target | Negotiate_NTLM ); + /** + * Creates the type 3 message which should be sent to the server after + * the challenge (type 2) received. + * + * @param auth - a buffer where the Type 3 message will returned. + * @param challenge - the Type 2 message returned by the server. + * @param user - user's name. + * @param password - user's password. + * @param domain - the target domain. If left empty, it will be extracted + * from the challenge. + * @param workstation - the user's workstation. + * @param forceNTLM - force the use of NTLM authentication (either v1 or v2). + * @param forceNTLMv2 - force the use of NTLMv2 or LMv2 authentication. If false, NTLMv2 + * support is autodetected from the challenge. + * + * @return true if auth filled with the Type 3 message, false if an error occured + * (challenge data invalid, or NTLM authentication forced, but the challenge data says + * no NTLM supported). + */ + static bool getAuth( TQByteArray &auth, const TQByteArray &challenge, const TQString &user, + const TQString &password, const TQString &domain = TQString::null, + const TQString &workstation = TQString::null, bool forceNTLM = false, bool forceNTLMv2 = false ); + + /** + * Returns the LanManager response from the password and the server challenge. + */ + static TQByteArray getLMResponse( const TQString &password, const unsigned char *challenge ); + /** + * Calculates the LanManager hash of the specified password. + */ + static TQByteArray lmHash( const TQString &password ); + /** + * Calculates the LanManager response from the LanManager hash and the server challenge. + */ + static TQByteArray lmResponse( const TQByteArray &hash, const unsigned char *challenge ); + + /** + * Returns the NTLM response from the password and the server challenge. + */ + static TQByteArray getNTLMResponse( const TQString &password, const unsigned char *challenge ); + /** + * Returns the NTLM hash (MD4) from the password. + */ + static TQByteArray ntlmHash( const TQString &password ); + + /** + * Calculates the NTLMv2 response. + */ + static TQByteArray getNTLMv2Response( const TQString &target, const TQString &user, + const TQString &password, const TQByteArray &targetInformation, + const unsigned char *challenge ); + + /** + * Calculates the LMv2 response. + */ + static TQByteArray getLMv2Response( const TQString &target, const TQString &user, + const TQString &password, const unsigned char *challenge ); + + /** + * Returns the NTLMv2 hash. + */ + static TQByteArray ntlmv2Hash( const TQString &target, const TQString &user, const TQString &password ); + + /** + * Calculates the LMv2 response. + */ + static TQByteArray lmv2Response( const TQByteArray &hash, + const TQByteArray &clientData, const unsigned char *challenge ); + + /** + * Extracts a string field from an NTLM structure. + */ + static TQString getString( const TQByteArray &buf, const SecBuf &secbuf, bool unicode ); + /** + * Extracts a byte array from an NTLM structure. + */ + static TQByteArray getBuf( const TQByteArray &buf, const SecBuf &secbuf ); + + static TQByteArray createBlob( const TQByteArray &targetinfo ); + + static TQByteArray hmacMD5( const TQByteArray &data, const TQByteArray &key ); +private: + static TQByteArray QString2UnicodeLE( const TQString &target ); + static TQString UnicodeLE2TQString( const TQChar* data, uint len ); + + static void addBuf( TQByteArray &buf, SecBuf &secbuf, TQByteArray &data ); + static void addString( TQByteArray &buf, SecBuf &secbuf, const TQString &str, bool unicode = false ); + static void convertKey( unsigned char *key_56, void* ks ); +}; + +#endif /* KNTLM_H */ diff --git a/tdeio/misc/tdesasl/CMakeLists.txt b/tdeio/misc/tdesasl/CMakeLists.txt new file mode 100644 index 000000000..d48322d93 --- /dev/null +++ b/tdeio/misc/tdesasl/CMakeLists.txt @@ -0,0 +1,42 @@ +################################################# +# +# (C) 2010 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${TQT_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdecore +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### headers ################################### + +install(FILES tdesasl.h DESTINATION ${INCLUDE_INSTALL_DIR}/tdeio ) + + +##### tdesasl ################################### + +set( target tdesasl ) + +set( ${target}_SRCS + tdesasl.cpp +) + +tde_add_library( ${target} SHARED + SOURCES ${${target}_SRCS} + VERSION 1.2.0 + LINK tdecore-shared + DESTINATION ${LIB_INSTALL_DIR} +) diff --git a/tdeio/misc/tdesasl/Makefile.am b/tdeio/misc/tdesasl/Makefile.am new file mode 100644 index 000000000..4ebde7e8d --- /dev/null +++ b/tdeio/misc/tdesasl/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES=$(all_includes) + +lib_LTLIBRARIES = libtdesasl.la +METASOURCES = AUTO + +tdesaslincludedir = $(includedir)/tdeio +tdesaslinclude_HEADERS = tdesasl.h + +libtdesasl_la_SOURCES = tdesasl.cpp +libtdesasl_la_LDFLAGS = $(all_libraries) -version-info 3:0:2 -no-undefined +libtdesasl_la_LIBADD = $(LIB_TDECORE) $(LIB_QT) + diff --git a/tdeio/misc/tdesasl/tdesasl.cpp b/tdeio/misc/tdesasl/tdesasl.cpp new file mode 100644 index 000000000..ef0768f98 --- /dev/null +++ b/tdeio/misc/tdesasl/tdesasl.cpp @@ -0,0 +1,285 @@ +/* This file is part of the KDE libraries + Copyright (C) 2001-2002 Michael Hckel + $Id$ + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "tdesasl.h" + +#include +#include + +#include + +#include +#include + +KDESasl::KDESasl(const KURL &aUrl) +{ + mProtocol = aUrl.protocol(); + mUser = aUrl.user(); + mPass = aUrl.pass(); + mFirst = true; +} + +KDESasl::KDESasl(const TQString &aUser, const TQString &aPass, + const TQString &aProtocol) +{ + mProtocol = aProtocol; + mUser = aUser; + mPass = aPass; + mFirst = true; +} + +KDESasl::~KDESasl() { +} + +TQCString KDESasl::chooseMethod(const TQStrIList aMethods) +{ + if (aMethods.contains("DIGEST-MD5")) mMethod = "DIGEST-MD5"; + else if (aMethods.contains("CRAM-MD5")) mMethod = "CRAM-MD5"; + else if (aMethods.contains("PLAIN")) mMethod = "PLAIN"; + else if (aMethods.contains("LOGIN")) mMethod = "LOGIN"; + else mMethod = TQCString(); + return mMethod; +} + +void KDESasl::setMethod(const TQCString &aMethod) +{ + mMethod = aMethod.upper(); +} + +TQByteArray KDESasl::getPlainResponse() +{ + TQCString user = mUser.utf8(); + TQCString pass = mPass.utf8(); + int userlen = user.length(); + int passlen = pass.length(); + // result = $user\0$user\0$pass (no trailing \0) + TQByteArray result(2 * userlen + passlen + 2); + if ( userlen ) { + memcpy( result.data(), user.data(), userlen ); + memcpy( result.data() + userlen + 1, user.data(), userlen ); + } + if ( passlen ) + memcpy( result.data() + 2 * userlen + 2, pass.data(), passlen ); + result[userlen] = result[2*userlen+1] = '\0'; + return result; +} + +TQByteArray KDESasl::getLoginResponse() +{ + TQByteArray result = (mFirst) ? mUser.utf8() : mPass.utf8(); + mFirst = !mFirst; + if (result.size()) result.resize(result.size() - 1); + return result; +} + +TQByteArray KDESasl::getCramMd5Response(const TQByteArray &aChallenge) +{ + uint i; + TQByteArray secret = mPass.utf8(); + int len = mPass.utf8().length(); + secret.resize(len); + if (secret.size() > 64) + { + KMD5 md5(secret); + secret.duplicate((const char*)(&(md5.rawDigest()[0])), 16); + len = 16; + } + secret.resize(64); + for (i = len; i < 64; i++) secret[i] = 0; + TQByteArray XorOpad(64); + for (i = 0; i < 64; i++) XorOpad[i] = secret[i] ^ 0x5C; + TQByteArray XorIpad(64); + for (i = 0; i < 64; i++) XorIpad[i] = secret[i] ^ 0x36; + KMD5 md5; + md5.update(XorIpad); + md5.update(aChallenge); + KMD5 md5a; + md5a.update(XorOpad); + md5a.update(md5.rawDigest(), 16); + TQByteArray result = mUser.utf8(); + len = mUser.utf8().length(); + result.resize(len + 33); + result[len] = ' '; + TQCString ch = md5a.hexDigest(); + for (i = 0; i < 32; i++) result[i+len+1] = *(ch.data() + i); + return result; +} + +TQByteArray KDESasl::getDigestMd5Response(const TQByteArray &aChallenge) +{ + mFirst = !mFirst; + if (mFirst) return TQByteArray(); + TQCString str, realm, nonce, qop, algorithm, charset; + TQCString nc = "00000001"; + unsigned int a, b, c, d; + a = 0; + while (a < aChallenge.size()) + { + b = a; + while (b < aChallenge.size() && aChallenge[b] != '=') b++; + c = b + 1; + if (aChallenge[c] == '"') + { + d = c + 1; + while (d < aChallenge.size() && aChallenge[d] != '"') d++; + c++; + } else { + d = c; + while (d < aChallenge.size() && aChallenge[d] != ',') d++; + } + str = TQCString(aChallenge.data() + c, d - c + 1); + if (tqstrnicmp(aChallenge.data() + a, "realm=", 6) == 0) realm = str; + else if (tqstrnicmp(aChallenge.data() + a, "nonce=", 6) == 0) nonce = str; + else if (tqstrnicmp(aChallenge.data() + a, "qop=", 4) == 0) qop = str; + else if (tqstrnicmp(aChallenge.data() + a, "algorithm=", 10) == 0) + algorithm = str; + else if (tqstrnicmp(aChallenge.data() + a, "charset=", 8) == 0) + charset = str; + a = (d < aChallenge.size() && aChallenge[d] == '"') ? d + 2 : d + 1; + } + if (qop.isEmpty()) qop = "auth"; + qop = "auth"; + bool utf8 = tqstricmp(charset, "utf-8") == 0; + TQCString digestUri = TQCString(mProtocol.latin1()) + "/" + realm; + + /* Calculate the response */ + /* Code based on code from the http io-slave + Copyright (C) 2000,2001 Dawit Alemayehu + Copyright (C) 2000,2001 Waldo Bastian + Copyright (C) 2000,2001 George Staikos */ + KMD5 md, md2; + TQCString HA1, HA2; + TQCString cnonce; + cnonce.setNum((1 + static_cast(100000.0*rand()/(RAND_MAX+1.0)))); + cnonce = KCodecs::base64Encode( cnonce ); + + // Calculate H(A1) + TQCString authStr = (utf8) ? mUser.utf8() : TQCString(mUser.latin1()); + authStr += ':'; + authStr += realm; + authStr += ':'; + authStr += (utf8) ? mPass.utf8() : TQCString(mPass.latin1()); + + md.update( authStr ); + authStr = ""; + if ( algorithm == "md5-sess" ) + { + authStr += ':'; + authStr += nonce; + authStr += ':'; + authStr += cnonce; + } + md2.reset(); + /* SASL authentication uses rawDigest here, whereas HTTP authentication uses + hexDigest() */ + md2.update(md.rawDigest(), 16); + md2.update( authStr ); + md2.hexDigest( HA1 ); + + // Calcualte H(A2) + authStr = "AUTHENTICATE:"; + authStr += digestUri; + if ( qop == "auth-int" || qop == "auth-conf" ) + { + authStr += ":00000000000000000000000000000000"; + } + md.reset(); + md.update( authStr ); + md.hexDigest( HA2 ); + + // Calcualte the response. + authStr = HA1; + authStr += ':'; + authStr += nonce; + authStr += ':'; + if ( !qop.isEmpty() ) + { + authStr += nc; + authStr += ':'; + authStr += cnonce; + authStr += ':'; + authStr += qop; + authStr += ':'; + } + authStr += HA2; + md.reset(); + md.update( authStr ); + TQCString response = md.hexDigest(); + /* End of response calculation */ + + TQCString result; + if (utf8) + { + result = "charset=utf-8,username=\"" + mUser.utf8(); + } else { + result = "charset=iso-8859-1,username=\"" + TQCString(mUser.latin1()); + } + result += "\",realm=\"" + realm + "\",nonce=\"" + nonce; + result += "\",nc=" + nc + ",cnonce=\"" + cnonce; + result += "\",digest-uri=\"" + digestUri; + result += "\",response=" + response + ",qop=" + qop; + TQByteArray ba; + ba.duplicate(result.data(), result.length()); + return ba; +} + +TQByteArray KDESasl::getBinaryResponse(const TQByteArray &aChallenge, bool aBase64) +{ + if (aBase64) + { + TQByteArray ba; + KCodecs::base64Decode(aChallenge, ba); + KCodecs::base64Encode(getBinaryResponse(ba, false), ba); + return ba; + } + if (tqstricmp(mMethod, "PLAIN") == 0) return getPlainResponse(); + if (tqstricmp(mMethod, "LOGIN") == 0) return getLoginResponse(); + if (tqstricmp(mMethod, "CRAM-MD5") == 0) + return getCramMd5Response(aChallenge); + if (tqstricmp(mMethod, "DIGEST-MD5") == 0) + return getDigestMd5Response(aChallenge); +// return getDigestMd5Response(TQCString("realm=\"elwood.innosoft.com\",nonce=\"OA6MG9tEQGm2hh\",qop=\"auth\",algorithm=md5-sess,charset=utf-8")); + return TQByteArray(); +} + +TQCString KDESasl::getResponse(const TQByteArray &aChallenge, bool aBase64) +{ + TQByteArray ba = getBinaryResponse(aChallenge, aBase64); + return TQCString(ba.data(), ba.size() + 1); +} + +TQCString KDESasl::method() const { + return mMethod; +} + +bool KDESasl::clientStarts() const { + return method() == "PLAIN"; +} + +bool KDESasl::dialogComplete( int n ) const { + if ( method() == "PLAIN" || method() == "CRAM-MD5" ) + return n >= 1; + if ( method() == "LOGIN" || method() == "DIGEST-MD5" ) + return n >= 2; + return true; +} + +bool KDESasl::isClearTextMethod() const { + return method() == "PLAIN" || method() == "LOGIN" ; +} diff --git a/tdeio/misc/tdesasl/tdesasl.h b/tdeio/misc/tdesasl/tdesasl.h new file mode 100644 index 000000000..0c57096a8 --- /dev/null +++ b/tdeio/misc/tdesasl/tdesasl.h @@ -0,0 +1,169 @@ +/* This file is part of the KDE libraries + Copyright (C) 2001-2002 Michael Hckel + $Id$ + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef TDESASL_H +#define TDESASL_H + +#include + +#include + +class KURL; +class TQStrIList; + +/** + * This library can create responses for SASL authentication for a given + * challenge and a given secret. This way of authentication is common for + * SMTP, POP3, IMAP and LDAP. + * + * SASL is one way strong encryption and therefore useful for authentication, + * but not for secret information transfer. + * It is possibly to prove with SASL to know a shared secret like a password. + * It is not possible with SASL to transfer any other information in an + * encrypted way. For that purpose OpenPGP or SSL are useful. + * + * Currently PLAIN (RFC 2595), LOGIN (not really a SASL mechanism, but + * used like that in IMAP and SMTP), CRAM-MD5 (RFC 2195) and + * DIGEST-MD5 (RFC 2831) authentication are supported. PLAIN and + * LOGIN transmit the credentials in the clear (apart from a possible + * base64 encoding). + * + * For KDE 3.2, the API has been extended to allow transparent use of + * all currently supported SASL mechanisms. Example: + * \code + * KDESasl sasl( myUser, myPass, myProtocol ); + * if ( !sasl.chooseMethod( myMechanismsSupportedByServer ) ) + * return false; // couldn't agree on a method + * + * int numResponses = 0; + * if ( sasl.clientStarts() ) { // check whether we're supposed to start the dialog + * ++numResponses; + * mySendAuthCommand( sasl.method(), sasl.getResponse() ); + * } else { + * mySendAuthCommand( sasl.method() ); + * } + * for ( ; !sasl.dialogComplete( numResponses ) ; ++numResponses ) { + * TQByteArray challenge = myRecvChallenge(); + * mySendResponse( sasl.getResponse( challenge ) ); + * } + * return myCheckSuccess(); + * \endcode + * + * @author Michael Hckel + * @version $Id$ + */ + +class TDEIO_EXPORT KDESasl +{ + +public: + /** + * Construct a sasl object and initialize it with the username and password + * passed via the url. + */ + KDESasl(const KURL &aUrl); + /** + * This is a conveniece function and differs from the above function only by + * what arguments it accepts. + */ + KDESasl(const TQString &aUser, const TQString &aPass, const TQString &aProtocol); + /* + * You need to have a virtual destructor! + */ + virtual ~KDESasl(); + /** + * @returns the most secure method from the given methods and use it for + * further operations. + */ + virtual TQCString chooseMethod(const TQStrIList aMethods); + /** + * Explicitely set the SASL method used. + */ + virtual void setMethod(const TQCString &aMethod); + /** + * @return the SASL method used. + * @since 3.2 + */ + TQCString method() const; + /** + * @param numCalls number of times getResponse() has been called. + * @return whether the challenge/response dialog has completed + * + * @since 3.2 + */ + bool dialogComplete( int numCalls ) const; + /** + * @return whether the currently selected mechanism results in + * cleartext passwords being sent over the network and thus should + * be used only under TLS/SSL cover or for legacy servers. + * + * @since 3.2 + */ + bool isClearTextMethod() const; + /** + * Creates a response using the formerly chosen SASL method. + * For LOGIN authentication you have to call this function twice. KDESasl + * realizes on its own, if you are calling it for the first or for the + * second time. + * @param aChallenge is the challenge sent to create a response for + * @param aBase64 specifies, whether the authentication protocol uses base64 + * encoding. The challenge is decoded from base64 and the response is + * encoded base64 if set to true. + */ + TQCString getResponse(const TQByteArray &aChallenge=TQByteArray(), bool aBase64 = true); + /** + * Create a response as above but place it in a QByteArray + */ + TQByteArray getBinaryResponse(const TQByteArray &aChallenge=TQByteArray(), bool aBase64=true); + /** + * Returns true if the client is supposed to initiate the + * challenge-respinse dialog with an initial response (which most + * protocols can transfer alongside the authentication command as an + * optional second parameter). This method relieves the sasl user + * from knowing details about the mechanism. If true, use + * #getResponse() with a null challenge. + * + * @since 3.2 + */ + bool clientStarts() const; +protected: + /** + * PLAIN authentication as described in RFC 2595 + */ + virtual TQByteArray getPlainResponse(); + /** + * LOGIN authentication + */ + virtual TQByteArray getLoginResponse(); + /** + * CRAM-MD5 authentication as described in RFC 2195 + */ + virtual TQByteArray getCramMd5Response(const TQByteArray &aChallenge); + /** + * DIGEST-MD5 authentication as described in RFC 2831 + */ + virtual TQByteArray getDigestMd5Response(const TQByteArray &aChallenge); + +private: + TQString mProtocol, mUser, mPass; + TQCString mMethod; + bool mFirst; +}; + +#endif diff --git a/tdeio/misc/tdesendbugmail/CMakeLists.txt b/tdeio/misc/tdesendbugmail/CMakeLists.txt new file mode 100644 index 000000000..3dffadb22 --- /dev/null +++ b/tdeio/misc/tdesendbugmail/CMakeLists.txt @@ -0,0 +1,37 @@ +################################################# +# +# (C) 2010 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${TQT_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdeio/tdeio +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### tdesendbugmail ############################## + +set( target tdesendbugmail ) + +set( ${target}_SRCS + main.cpp smtp.cpp +) + +tde_add_executable( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK tdeio-shared + DESTINATION ${BIN_INSTALL_DIR} +) diff --git a/tdeio/misc/tdesendbugmail/Makefile.am b/tdeio/misc/tdesendbugmail/Makefile.am new file mode 100644 index 000000000..f9087a4fe --- /dev/null +++ b/tdeio/misc/tdesendbugmail/Makefile.am @@ -0,0 +1,26 @@ +# This file is part of the KDE libraries +# Copyright (C) 2000 Stephan Kulow + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. + +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public License +# along with this library; see the file COPYING.LIB. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +bin_PROGRAMS = tdesendbugmail +INCLUDES= -I$(srcdir)/.. $(all_includes) + +tdesendbugmail_SOURCES = main.cpp smtp.cpp +tdesendbugmail_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor +tdesendbugmail_LDADD = ../../libtdeio.la + +METASOURCES = AUTO diff --git a/tdeio/misc/tdesendbugmail/main.cpp b/tdeio/misc/tdesendbugmail/main.cpp new file mode 100644 index 000000000..162e6ad5c --- /dev/null +++ b/tdeio/misc/tdesendbugmail/main.cpp @@ -0,0 +1,142 @@ +// $Id$ + +#include +#include "main.h" +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "smtp.h" + +static KCmdLineOptions options[] = { + { "subject ", I18N_NOOP("Subject line"), 0 }, + { "recipient ", I18N_NOOP("Recipient"), "submit@bugs.kde.org" }, + KCmdLineLastOption +}; + +void BugMailer::slotError(int errornum) { + kdDebug() << "slotError\n"; + TQString str, lstr; + + switch(errornum) { + case SMTP::CONNECTERROR: + lstr = i18n("Error connecting to server."); + break; + case SMTP::NOTCONNECTED: + lstr = i18n("Not connected."); + break; + case SMTP::CONNECTTIMEOUT: + lstr = i18n("Connection timed out."); + break; + case SMTP::INTERACTTIMEOUT: + lstr = i18n("Time out waiting for server interaction."); + break; + default: + lstr = sm->getLastLine().stripWhiteSpace(); + lstr = i18n("Server said: \"%1\"").arg(lstr); + } + fputs(lstr.utf8().data(), stdout); + fflush(stdout); + + ::exit(1); +} + +void BugMailer::slotSend() { + kdDebug() << "slotSend\n"; + ::exit(0); +} + +int main(int argc, char **argv) { + + KLocale::setMainCatalogue("tdelibs"); + TDEAboutData d("tdesendbugmail", I18N_NOOP("KSendBugMail"), "1.0", + I18N_NOOP("Sends a short bug report to submit@bugs.kde.org"), + TDEAboutData::License_GPL, "(c) 2000 Stephan Kulow"); + d.addAuthor("Stephan Kulow", I18N_NOOP("Author"), "coolo@kde.org"); + + TDECmdLineArgs::init(argc, argv, &d); + TDECmdLineArgs::addCmdLineOptions(options); + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + + TDEApplication a(false, false); + + TQCString recipient = args->getOption("recipient"); + if (recipient.isEmpty()) + recipient = "submit@bugs.kde.org"; + else { + if (recipient.at(0) == '\'') { + recipient = recipient.mid(1).left(recipient.length() - 2); + } + } + kdDebug() << "recp \"" << recipient << "\"\n"; + + TQCString subject = args->getOption("subject"); + if (subject.isEmpty()) + subject = "(no subject)"; + else { + if (subject.at(0) == '\'') + subject = subject.mid(1).left(subject.length() - 2); + } + TQTextIStream input(stdin); + TQString text, line; + while (!input.eof()) { + line = input.readLine(); + text += line + "\r\n"; + } + kdDebug() << text << endl; + + KEMailSettings emailConfig; + emailConfig.setProfile(emailConfig.defaultProfileName()); + TQString fromaddr = emailConfig.getSetting(KEMailSettings::EmailAddress); + if (!fromaddr.isEmpty()) { + TQString name = emailConfig.getSetting(KEMailSettings::RealName); + if (!name.isEmpty()) + fromaddr = name + TQString::fromLatin1(" <") + fromaddr + TQString::fromLatin1(">"); + } else { + struct passwd *p; + p = getpwuid(getuid()); + fromaddr = TQString::fromLatin1(p->pw_name); + fromaddr += "@"; + char buffer[256]; + buffer[0] = '\0'; + if(!gethostname(buffer, sizeof(buffer))) + buffer[sizeof(buffer)-1] = '\0'; + fromaddr += buffer; + } + kdDebug() << "fromaddr \"" << fromaddr << "\"" << endl; + + TQString server = emailConfig.getSetting(KEMailSettings::OutServer); + if (server.isEmpty()) + server=TQString::fromLatin1("bugs.kde.org"); + + SMTP *sm = new SMTP; + BugMailer bm(sm); + + TQObject::connect(sm, TQT_SIGNAL(messageSent()), &bm, TQT_SLOT(slotSend())); + TQObject::connect(sm, TQT_SIGNAL(error(int)), &bm, TQT_SLOT(slotError(int))); + sm->setServerHost(server); + sm->setPort(25); + sm->setSenderAddress(fromaddr); + sm->setRecipientAddress(recipient); + sm->setMessageSubject(subject); + sm->setMessageHeader(TQString::fromLatin1("From: %1\r\nTo: %2\r\n").arg(fromaddr).arg(recipient.data())); + sm->setMessageBody(text); + sm->sendMessage(); + + int r = a.exec(); + kdDebug() << "execing " << r << endl; + delete sm; + return r; +} + +#include "main.moc" diff --git a/tdeio/misc/tdesendbugmail/main.h b/tdeio/misc/tdesendbugmail/main.h new file mode 100644 index 000000000..39d424bef --- /dev/null +++ b/tdeio/misc/tdesendbugmail/main.h @@ -0,0 +1,20 @@ +#ifndef BUG_MAILER_H +#define BUG_MAILER_H "$Id$" + +#include + +class SMTP; + +class BugMailer : public TQObject { + Q_OBJECT +public: + BugMailer(SMTP* s) : TQObject(0, "mailer"), sm(s) {} + +public slots: + void slotError(int); + void slotSend(); +private: + SMTP *sm; +}; + +#endif diff --git a/tdeio/misc/tdesendbugmail/smtp.cpp b/tdeio/misc/tdesendbugmail/smtp.cpp new file mode 100644 index 000000000..d282782fc --- /dev/null +++ b/tdeio/misc/tdesendbugmail/smtp.cpp @@ -0,0 +1,336 @@ +/* $Id$ */ + +#include +#include +#include + +#include + +#include "smtp.h" + +SMTP::SMTP(char *serverhost, unsigned short int port, int timeout) +{ + struct utsname uts; + + serverHost = serverhost; + hostPort = port; + timeOut = timeout * 1000; + + senderAddress = "user@example.net"; + recipientAddress = "user@example.net"; + messageSubject = "(no subject)"; + messageBody = "empty"; + messageHeader = ""; + + connected = false; + finished = false; + + sock = 0L; + state = INIT; + serverState = NONE; + + uname(&uts); + domainName = uts.nodename; + + + if(domainName.isEmpty()) + domainName = "somemachine.example.net"; + + kdDebug() << "SMTP object created" << endl; + + connect(&connectTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(connectTimerTick())); + connect(&timeOutTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(connectTimedOut())); + connect(&interactTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(interactTimedOut())); + + // some sendmail will give 'duplicate helo' error, quick fix for now + connect(this, TQT_SIGNAL(messageSent()), TQT_SLOT(closeConnection())); +} + +SMTP::~SMTP() +{ + if(sock){ + delete sock; + sock = 0L; + } + connectTimer.stop(); + timeOutTimer.stop(); +} + +void SMTP::setServerHost(const TQString& serverhost) +{ + serverHost = serverhost; +} + +void SMTP::setPort(unsigned short int port) +{ + hostPort = port; +} + +void SMTP::setTimeOut(int timeout) +{ + timeOut = timeout; +} + +void SMTP::setSenderAddress(const TQString& sender) +{ + senderAddress = sender; + int index = senderAddress.find('<'); + if (index == -1) + return; + senderAddress = senderAddress.mid(index + 1); + index = senderAddress.find('>'); + if (index != -1) + senderAddress = senderAddress.left(index); + senderAddress = senderAddress.simplifyWhiteSpace(); + while (1) { + index = senderAddress.find(' '); + if (index != -1) + senderAddress = senderAddress.mid(index + 1); // take one side + else + break; + } + index = senderAddress.find('@'); + if (index == -1) + senderAddress.append("@localhost"); // won't go through without a local mail system + +} + +void SMTP::setRecipientAddress(const TQString& recipient) +{ + recipientAddress = recipient; +} + +void SMTP::setMessageSubject(const TQString& subject) +{ + messageSubject = subject; +} + +void SMTP::setMessageBody(const TQString& message) +{ + messageBody = message; +} + +void SMTP::setMessageHeader(const TQString &header) +{ + messageHeader = header; +} + +void SMTP::openConnection(void) +{ + kdDebug() << "started connect timer" << endl; + connectTimer.start(100, true); +} + +void SMTP::closeConnection(void) +{ + socketClose(sock); +} + +void SMTP::sendMessage(void) +{ + if(!connected) + connectTimerTick(); + if(state == FINISHED && connected){ + kdDebug() << "state was == FINISHED\n" << endl; + finished = false; + state = IN; + writeString = TQString::fromLatin1("helo %1\r\n").arg(domainName); + write(sock->socket(), writeString.ascii(), writeString.length()); + } + if(connected){ + kdDebug() << "enabling read on sock...\n" << endl; + interactTimer.start(timeOut, true); + sock->enableRead(true); + } +} +#include + +void SMTP::connectTimerTick(void) +{ + connectTimer.stop(); +// timeOutTimer.start(timeOut, true); + + kdDebug() << "connectTimerTick called..." << endl; + + if(sock){ + delete sock; + sock = 0L; + } + + kdDebug() << "connecting to " << serverHost << ":" << hostPort << " ..... " << endl; + sock = new TDESocket(serverHost.ascii(), hostPort); + + if(sock == 0L || sock->socket() < 0) { + timeOutTimer.stop(); + kdDebug() << "connection failed!" << endl; + socketClose(sock); + emit error(CONNECTERROR); + connected = false; + return; + } + connected = true; + finished = false; + state = INIT; + serverState = NONE; + + connect(sock, TQT_SIGNAL(readEvent(TDESocket *)), this, TQT_SLOT(socketRead(TDESocket *))); + connect(sock, TQT_SIGNAL(closeEvent(TDESocket *)), this, TQT_SLOT(socketClose(TDESocket *))); + // sock->enableRead(true); + timeOutTimer.stop(); + kdDebug() << "connected" << endl; +} + +void SMTP::connectTimedOut(void) +{ + timeOutTimer.stop(); + + if(sock) + sock->enableRead(false); + kdDebug() << "socket connection timed out" << endl; + socketClose(sock); + emit error(CONNECTTIMEOUT); +} + +void SMTP::interactTimedOut(void) +{ + interactTimer.stop(); + + if(sock) + sock->enableRead(false); + kdDebug() << "time out waiting for server interaction" << endl; + socketClose(sock); + emit error(INTERACTTIMEOUT); +} + +void SMTP::socketRead(TDESocket *socket) +{ + int n, nl; + + kdDebug() << "socketRead() called..." << endl; + interactTimer.stop(); + + if(socket == 0L || socket->socket() < 0) + return; + n = read(socket->socket(), readBuffer, SMTP_READ_BUFFER_SIZE-1 ); + + if(n < 0) + return; + + readBuffer[n] = '\0'; + lineBuffer += readBuffer; + nl = lineBuffer.find('\n'); + if(nl == -1) + return; + lastLine = lineBuffer.left(nl); + lineBuffer = lineBuffer.right(lineBuffer.length() - nl - 1); + processLine(&lastLine); + if(connected) + interactTimer.start(timeOut, true); +} + +void SMTP::socketClose(TDESocket *socket) +{ + timeOutTimer.stop(); + disconnect(sock, TQT_SIGNAL(readEvent(TDESocket *)), this, TQT_SLOT(socketRead(TDESocket *))); + disconnect(sock, TQT_SIGNAL(closeEvent(TDESocket *)), this, TQT_SLOT(socketClose(TDESocket *))); + socket->enableRead(false); + kdDebug() << "connection terminated" << endl; + connected = false; + if(socket){ + delete socket; + socket = 0L; + sock = 0L; + } + emit connectionClosed(); +} + +void SMTP::processLine(TQString *line) +{ + int i, stat; + TQString tmpstr; + + i = line->find(' '); + tmpstr = line->left(i); + if(i > 3) + kdDebug() << "warning: SMTP status code longer then 3 digits: " << tmpstr << endl; + stat = tmpstr.toInt(); + serverState = (SMTPServerStatus)stat; + lastState = state; + + kdDebug() << "smtp state: [" << stat << "][" << *line << "]" << endl; + + switch(stat){ + case GREET: //220 + state = IN; + writeString = TQString::fromLatin1("helo %1\r\n").arg(domainName); + kdDebug() << "out: " << writeString << endl; + write(sock->socket(), writeString.ascii(), writeString.length()); + break; + case GOODBYE: //221 + state = QUIT; + break; + case SUCCESSFUL://250 + switch(state){ + case IN: + state = READY; + writeString = TQString::fromLatin1("mail from: %1\r\n").arg(senderAddress); + kdDebug() << "out: " << writeString << endl; + write(sock->socket(), writeString.ascii(), writeString.length()); + break; + case READY: + state = SENTFROM; + writeString = TQString::fromLatin1("rcpt to: %1\r\n").arg(recipientAddress); + kdDebug() << "out: " << writeString << endl; + write(sock->socket(), writeString.ascii(), writeString.length()); + break; + case SENTFROM: + state = SENTTO; + writeString = TQString::fromLatin1("data\r\n"); + kdDebug() << "out: " << writeString << endl; + write(sock->socket(), writeString.ascii(), writeString.length()); + break; + case DATA: + state = FINISHED; + finished = true; + sock->enableRead(false); + emit messageSent(); + break; + default: + state = CERROR; + kdDebug() << "smtp error (state error): [" << lastState << "]:[" << stat << "][" << *line << "]" << endl; + socketClose(sock); + emit error(COMMAND); + break; + } + break; + case READYDATA: //354 + state = DATA; + writeString = TQString::fromLatin1("Subject: %1\r\n").arg(messageSubject); + writeString += messageHeader; + writeString += "\r\n"; + writeString += messageBody; + writeString += TQString::fromLatin1(".\r\n"); + kdDebug() << "out: " << writeString; + write(sock->socket(), writeString.ascii(), writeString.length()); + break; + case ERROR: //501 + state = CERROR; + kdDebug() << "smtp error (command error): [" << lastState << "]:[" << stat << "][" << *line << "]\n" << endl; + socketClose(sock); + emit error(COMMAND); + break; + case UNKNOWN: //550 + state = CERROR; + kdDebug() << "smtp error (unknown user): [" << lastState << "]:[" << stat << "][" << *line << "]" << endl; + socketClose(sock); + emit error(UNKNOWNUSER); + break; + default: + state = CERROR; + kdDebug() << "unknown response: [" << lastState << "]:[" << stat << "][" << *line << "]" << endl; + socketClose(sock); + emit error(UNKNOWNRESPONSE); + } +} + +#include "smtp.moc" diff --git a/tdeio/misc/tdesendbugmail/smtp.h b/tdeio/misc/tdesendbugmail/smtp.h new file mode 100644 index 000000000..acdb4a3c3 --- /dev/null +++ b/tdeio/misc/tdesendbugmail/smtp.h @@ -0,0 +1,144 @@ +/* $Id$ */ + +#ifndef SMTP_H +#define SMTP_H + +#include +#include +#include + +/*int SMTPServerStatus[] = { + 220, // greeting from server + 221, // server acknolages goodbye + 250, // command successful + 354, // ready to receive data + 501, // error + 550, // user unknown + 0 // null +}; + +int SMTPClientStatus[] = { + 50, // not logged in yet. + 100, // logged in, got 220 + 150, // sent helo, got 250 + 200, // sent mail from, got 250 + 250, // sent rctp to, got 250 + 300, // data sent, got 354 + 350, // sent data/., got 250 + 400, // send quit, got 221 + 450, // finished, logged out + 0 // null +}; +*/ + +#define DEFAULT_SMTP_PORT 25 +#define DEFAULT_SMTP_SERVER localhost +#define DEFAULT_SMTP_TIMEOUT 60 + +#define SMTP_READ_BUFFER_SIZE 256 + +class SMTP:public QObject +{ + Q_OBJECT +public: + SMTP(char *serverhost = 0, unsigned short int port = 0, int timeout = DEFAULT_SMTP_TIMEOUT); + ~SMTP(); + + void setServerHost(const TQString& serverhost); + void setPort(unsigned short int port); + void setTimeOut(int timeout); + + bool isConnected(){return connected;}; + bool isFinished(){return finished;}; + TQString getLastLine(){return lastLine;}; + + void setSenderAddress(const TQString& sender); + void setRecipientAddress(const TQString& recipient); + void setMessageSubject(const TQString& subject); + void setMessageBody(const TQString& message); + void setMessageHeader(const TQString &header); + + typedef enum { + NONE = 0, // null + GREET = 220, // greeting from server + GOODBYE = 221, // server acknolages quit + SUCCESSFUL = 250, // command successful + READYDATA = 354, // server ready to receive data + ERROR = 501, // error + UNKNOWN = 550 // user unknown + }SMTPServerStatus; + + typedef enum { + INIT = 50, // not logged in yet + IN = 100, // logged in, got 220 + READY = 150, // sent HELO, got 250 + SENTFROM = 200, // sent MAIL FROM:, got 250 + SENTTO = 250, // sent RCTP TO:, got 250 + DATA = 300, // DATA sent, got 354 + FINISHED = 350, // finished sending data, got 250 + QUIT = 400, // sent QUIT, got 221 + OUT = 450, // finished, logged out + CERROR = 500 // didn't finish, had error or connection drop + }SMTPClientStatus; + + typedef enum { + NOERROR = 0, + CONNECTERROR = 10, + NOTCONNECTED = 11, + CONNECTTIMEOUT = 15, + INTERACTTIMEOUT = 16, + UNKNOWNRESPONSE = 20, + UNKNOWNUSER = 30, + COMMAND = 40 + }SMTPError; + +protected: + void processLine(TQString *line); + +public slots: + void openConnection(); + void sendMessage(); + void closeConnection(); + + void connectTimerTick(); + void connectTimedOut(); + void interactTimedOut(); + + void socketRead(TDESocket *); + void socketClose(TDESocket *); + +signals: + void connectionClosed(); + void messageSent(); + void error(int); + +private: + TQString serverHost; + unsigned short int hostPort; + int timeOut; + + bool connected; + bool finished; + + TQString senderAddress; + TQString recipientAddress; + TQString messageSubject; + TQString messageBody, messageHeader; + + SMTPClientStatus state; + SMTPClientStatus lastState; + SMTPServerStatus serverState; + + TQString domainName; + + TDESocket *sock; + TQTimer connectTimer; + TQTimer timeOutTimer; + TQTimer interactTimer; + + char readBuffer[SMTP_READ_BUFFER_SIZE]; + TQString lineBuffer; + TQString lastLine; + TQString writeString; +}; +#endif diff --git a/tdeio/misc/tdetelnetservice.cpp b/tdeio/misc/tdetelnetservice.cpp new file mode 100644 index 000000000..655a5b32a --- /dev/null +++ b/tdeio/misc/tdetelnetservice.cpp @@ -0,0 +1,112 @@ +/* + Copyright (c) 2001 Malte Starostik + based on tdemailservice.cpp, + Copyright (c) 2000 Simon Hausmann + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +// $Id$ + +#include +#include +#include +#include +#include +#include +#include + +static const KCmdLineOptions options[] = +{ + {"+url", 0, 0}, + KCmdLineLastOption +}; + +int main(int argc, char **argv) +{ + KLocale::setMainCatalogue("tdelibs"); + TDECmdLineArgs::init(argc, argv, "tdetelnetservice", I18N_NOOP("telnet service"), + I18N_NOOP("telnet protocol handler"), "unknown"); + TDECmdLineArgs::addCmdLineOptions(options); + + TDEApplication app; + + TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); + + if (args->count() != 1) + return 1; + + TDEConfig *config = new TDEConfig("kdeglobals", true); + config->setGroup("General"); + TQString terminal = config->readPathEntry("TerminalApplication", "konsole"); + + KURL url(args->arg(0)); + TQStringList cmd; + if (terminal == "konsole") + cmd << "--noclose"; + + cmd << "-e"; + if ( url.protocol() == "telnet" ) + cmd << "telnet"; + else if ( url.protocol() == "ssh" ) + cmd << "ssh"; + else if ( url.protocol() == "rlogin" ) + cmd << "rlogin"; + else { + kdError() << "Invalid protocol " << url.protocol() << endl; + return 2; + } + + if (!app.authorize("shell_access")) + { + KMessageBox::sorry(0, + i18n("You do not have permission to access the %1 protocol.").arg(url.protocol())); + return 3; + } + + if (!url.user().isEmpty()) + { + cmd << "-l"; + cmd << url.user(); + } + + TQString host; + if (!url.host().isEmpty()) + host = url.host(); // telnet://host + else if (!url.path().isEmpty()) + host = url.path(); // telnet:host + + if (host.isEmpty() || host.startsWith("-")) + { + kdError() << "Invalid hostname " << host << endl; + return 2; + } + + cmd << host; + + if (url.port()){ + if ( url.protocol() == "ssh" ) + cmd << "-p" << TQString::number(url.port()); + else + cmd << TQString::number(url.port()); + } + + app.tdeinitExec(terminal, cmd); + + return 0; +} + +// vim: ts=4 sw=4 noet diff --git a/tdeio/misc/tdewalletd/CMakeLists.txt b/tdeio/misc/tdewalletd/CMakeLists.txt new file mode 100644 index 000000000..2d0d2ef28 --- /dev/null +++ b/tdeio/misc/tdewalletd/CMakeLists.txt @@ -0,0 +1,49 @@ +################################################# +# +# (C) 2010 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +include_directories( + ${TQT_INCLUDE_DIRS} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR}/tdecore + ${CMAKE_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/dcop + ${CMAKE_SOURCE_DIR}/tdecore + ${CMAKE_SOURCE_DIR}/tdeui + ${CMAKE_SOURCE_DIR}/tdewallet/client + ${CMAKE_SOURCE_DIR}/tdewallet/backend + ${CMAKE_SOURCE_DIR}/tdeio/tdeio +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install(FILES tdewalletd.desktop DESTINATION ${SERVICES_INSTALL_DIR}/kded ) + + +#### kded_tdewalletd ############################## + +set( target kded_tdewalletd ) + +set( ${target}_SRCS + tdewalletd.cpp tdewalletd.skel ktimeout.cpp tdewalletwizard.ui + kbetterthankdialogbase.ui +) + +tde_add_kpart( ${target} AUTOMOC + SOURCES ${${target}_SRCS} + LINK tdeinit_kded-shared tdewalletbackend-shared + DEPENDENCIES dcopidl + DESTINATION ${PLUGIN_INSTALL_DIR} +) diff --git a/tdeio/misc/tdewalletd/Makefile.am b/tdeio/misc/tdewalletd/Makefile.am new file mode 100644 index 000000000..5d52fa810 --- /dev/null +++ b/tdeio/misc/tdewalletd/Makefile.am @@ -0,0 +1,35 @@ +# This file is part of the KDE libraries +# Copyright (C) 2002 George Staikos + +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. + +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. + +# You should have received a copy of the GNU Library General Public License +# along with this library; see the file COPYING.LIB. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. + +INCLUDES= -I$(srcdir)/.. -I$(top_srcdir) -I$(top_srcdir)/tdewallet/backend -I$(top_builddir)/tdewallet/backend -I$(top_srcdir)/tdewallet/client -I$(top_builddir)/tdewallet/client $(all_includes) + +kde_module_LTLIBRARIES = kded_tdewalletd.la + +kded_tdewalletd_la_LDFLAGS = $(all_libraries) -module -avoid-version +kded_tdewalletd_la_LIBADD = $(LIB_KIO) ../../../tdewallet/backend/libtdewalletbackend.la ../../../tdewallet/client/libtdewalletclient.la $(LIB_KDED) $(LIB_QT) $(top_builddir)/dcop/libDCOP.la $(LIB_TDECORE) $(LIB_TDEUI) +kded_tdewalletd_la_SOURCES = tdewalletd.cpp tdewalletd.skel ktimeout.cpp tdewalletwizard.ui kbetterthankdialogbase.ui + +METASOURCES = AUTO + +noinst_HEADERS = tdewalletd.h ktimeout.h tdewalletwizard.ui.h + +services_DATA = tdewalletd.desktop +servicesdir = $(kde_servicesdir)/kded + +tdewalletwizard.lo: tdewalletwizard.ui tdewalletwizard.ui.h +kbetterthankdialogbase.lo: kbetterthankdialogbase.ui kbetterthankdialogbase.ui.h diff --git a/tdeio/misc/tdewalletd/kbetterthankdialogbase.ui b/tdeio/misc/tdewalletd/kbetterthankdialogbase.ui new file mode 100644 index 000000000..a02d5def7 --- /dev/null +++ b/tdeio/misc/tdewalletd/kbetterthankdialogbase.ui @@ -0,0 +1,154 @@ + +KBetterThanKDialogBase + + + KBetterThanKDialogBase + + + + 0 + 0 + 479 + 109 + + + + + + + + unnamed + + + Fixed + + + + _label + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 41 + 21 + + + + + + layout1 + + + + unnamed + + + + _allowOnce + + + Allow &Once + + + true + + + + + _allowAlways + + + Allow &Always + + + + + _deny + + + &Deny + + + + + _denyForever + + + Deny &Forever + + + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 61 + 21 + + + + + + + + + + _allowOnce + clicked() + KBetterThanKDialogBase + clicked() + + + _allowAlways + clicked() + KBetterThanKDialogBase + clicked() + + + _deny + clicked() + KBetterThanKDialogBase + clicked() + + + _denyForever + clicked() + KBetterThanKDialogBase + clicked() + + + + kactivelabel.h + kbetterthankdialogbase.ui.h + + + clicked() + setLabel( const TQString & label ) + init() + accept() + reject() + + + + kactivelabel.h + + diff --git a/tdeio/misc/tdewalletd/kbetterthankdialogbase.ui.h b/tdeio/misc/tdewalletd/kbetterthankdialogbase.ui.h new file mode 100644 index 000000000..2b3e16b0d --- /dev/null +++ b/tdeio/misc/tdewalletd/kbetterthankdialogbase.ui.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you want to add, delete, or rename functions or slots, use +** Qt Designer to update this file, preserving your code. +** +** You should not define a constructor or destructor in this file. +** Instead, write your code in functions called init() and destroy(). +** These will automatically be called by the form's constructor and +** destructor. +*****************************************************************************/ + + +void KBetterThanKDialogBase::clicked() +{ + if (sender() == _allowOnce) { + done(0); + } else if (sender() == _allowAlways) { + done(1); + } else if (sender() == _deny) { + done(2); + } else if (sender() == _denyForever) { + done(3); + } +} + + +void KBetterThanKDialogBase::setLabel( const TQString & label ) +{ + _label->setText(label); +} + + +void KBetterThanKDialogBase::init() +{ + _allowOnce->setFocus(); +} + + +void KBetterThanKDialogBase::accept() +{ + setResult(0); +} + + +void KBetterThanKDialogBase::reject() +{ + TQDialog::reject(); + setResult(2); +} diff --git a/tdeio/misc/tdewalletd/ktimeout.cpp b/tdeio/misc/tdewalletd/ktimeout.cpp new file mode 100644 index 000000000..c431ecf69 --- /dev/null +++ b/tdeio/misc/tdewalletd/ktimeout.cpp @@ -0,0 +1,84 @@ +/* + This file is part of the KDE libraries + + Copyright (c) 2003 George Staikos + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "ktimeout.h" + +KTimeout::KTimeout(int size) +: TQObject(), _timers(size) { + _timers.setAutoDelete(true); +} + + +KTimeout::~KTimeout() { + clear(); +} + + +void KTimeout::clear() { + _timers.clear(); +} + + +void KTimeout::removeTimer(int id) { + TQTimer *t = _timers.find(id); + if (t != 0L) { + _timers.remove(id); // autodeletes + } +} + + +void KTimeout::addTimer(int id, int timeout) { + if (_timers.find(id) != 0L) { + return; + } + + TQTimer *t = new TQTimer; + connect(t, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeout())); + t->start(timeout); + _timers.insert(id, t); +} + + +void KTimeout::resetTimer(int id, int timeout) { + TQTimer *t = _timers.find(id); + if (t) { + t->changeInterval(timeout); + } +} + + +void KTimeout::timeout() { + const TQTimer *t = static_cast(sender()); + if (t) { + TQIntDictIterator it(_timers); + for (; it.current(); ++it) { + if (it.current() == t) { + emit timedOut(it.currentKey()); + return; + } + } + } +} + + +#include "ktimeout.moc" + diff --git a/tdeio/misc/tdewalletd/ktimeout.h b/tdeio/misc/tdewalletd/ktimeout.h new file mode 100644 index 000000000..441e4ed77 --- /dev/null +++ b/tdeio/misc/tdewalletd/ktimeout.h @@ -0,0 +1,52 @@ +/* + This file is part of the KDE libraries + + Copyright (c) 2003 George Staikos + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ +#ifndef _KTIMEOUT_H_ +#define _KTIMEOUT_H_ + +#include +#include +#include + +// @internal +class KTimeout : public TQObject { + Q_OBJECT + public: + KTimeout(int size = 29); + virtual ~KTimeout(); + + signals: + void timedOut(int id); + + public slots: + void resetTimer(int id, int timeout); + void addTimer(int id, int timeout); + void removeTimer(int id); + void clear(); + + private slots: + void timeout(); + + private: + TQIntDict _timers; +}; + +#endif diff --git a/tdeio/misc/tdewalletd/tdewalletd.cpp b/tdeio/misc/tdewalletd/tdewalletd.cpp new file mode 100644 index 000000000..a8b3ade1a --- /dev/null +++ b/tdeio/misc/tdewalletd/tdewalletd.cpp @@ -0,0 +1,1514 @@ +/* + This file is part of the KDE libraries + + Copyright (c) 2002-2004 George Staikos + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "kbetterthankdialogbase.h" +#include "tdewalletwizard.h" +#include "tdewalletd.h" +#include "ktimeout.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +extern "C" { + KDE_EXPORT KDEDModule *create_tdewalletd(const TQCString &name) { + return new KWalletD(name); + } +} + + +class KWalletTransaction { + public: + KWalletTransaction() { + tType = Unknown; + transaction = 0L; + client = 0L; + modal = false; + } + + ~KWalletTransaction() { + // Don't delete these! + transaction = 0L; + client = 0L; + } + + enum Type { Unknown, Open, ChangePassword, OpenFail }; + DCOPClient *client; + DCOPClientTransaction *transaction; + Type tType; + TQCString rawappid, returnObject; + TQCString appid; + uint wId; + TQString wallet; + bool modal; +}; + + +KWalletD::KWalletD(const TQCString &name) +: KDEDModule(name), _failed(0) { + srand(time(0)); + _showingFailureNotify = false; + _transactions.setAutoDelete(true); + _timeouts = new KTimeout(17); + _closeIdle = false; + _idleTime = 0; + connect(_timeouts, TQT_SIGNAL(timedOut(int)), this, TQT_SLOT(timedOut(int))); + reconfigure(); + TDEGlobal::dirs()->addResourceType("tdewallet", "share/apps/tdewallet"); + connect(TDEApplication::dcopClient(), + TQT_SIGNAL(applicationRemoved(const TQCString&)), + this, + TQT_SLOT(slotAppUnregistered(const TQCString&))); + _dw = new KDirWatch(this, "KWallet Directory Watcher"); + _dw->addDir(TDEGlobal::dirs()->saveLocation("tdewallet")); + _dw->startScan(true); + connect(_dw, TQT_SIGNAL(dirty(const TQString&)), this, TQT_SLOT(emitWalletListDirty())); +} + + +KWalletD::~KWalletD() { + delete _timeouts; + _timeouts = 0; + + closeAllWallets(); + _transactions.clear(); +} + + +int KWalletD::generateHandle() { + int rc; + + // ASSUMPTION: RAND_MAX is fairly large. + do { + rc = rand(); + } while (_wallets.find(rc) || rc == 0); + + return rc; +} + + +void KWalletD::processTransactions() { + static bool processing = false; + + if (processing) { + return; + } + + processing = true; + + // Process remaining transactions + KWalletTransaction *xact; + while (!_transactions.isEmpty()) { + xact = _transactions.first(); + TQCString replyType; + int res; + + assert(xact->tType != KWalletTransaction::Unknown); + + switch (xact->tType) { + case KWalletTransaction::Open: + res = doTransactionOpen(xact->appid, xact->wallet, xact->wId, xact->modal); + replyType = "int"; + if (!xact->returnObject.isEmpty()) { + DCOPRef(xact->rawappid, xact->returnObject).send("walletOpenResult", res); + } + + // multiple requests from the same client + // should not produce multiple password + // dialogs on a failure + if (res < 0) { + TQPtrListIterator it(_transactions); + KWalletTransaction *x; + while ((x = it.current()) && x != xact) { + ++it; + } + if (x) { + ++it; + } + while ((x = it.current())) { + if (xact->appid == x->appid && x->tType == KWalletTransaction::Open && x->wallet == xact->wallet && x->wId == xact->wId) { + x->tType = KWalletTransaction::OpenFail; + } + ++it; + } + } + break; + case KWalletTransaction::OpenFail: + res = -1; + replyType = "int"; + if (!xact->returnObject.isEmpty()) { + DCOPRef(xact->rawappid, xact->returnObject).send("walletOpenResult", res); + } + break; + case KWalletTransaction::ChangePassword: + doTransactionChangePassword(xact->appid, xact->wallet, xact->wId); + // fall through - no return + default: + _transactions.removeRef(xact); + continue; + } + + if (xact->returnObject.isEmpty() && xact->tType != KWalletTransaction::ChangePassword) { + TQByteArray replyData; + TQDataStream stream(replyData, IO_WriteOnly); + stream << res; + xact->client->endTransaction(xact->transaction, replyType, replyData); + } + _transactions.removeRef(xact); + } + + processing = false; +} + + +void KWalletD::openAsynchronous(const TQString& wallet, const TQCString& returnObject, uint wId) { + DCOPClient *dc = callingDcopClient(); + if (!dc) { + return; + } + + TQCString appid = dc->senderId(); + if (!_enabled || + !TQRegExp("^[A-Za-z0-9]+[A-Za-z0-9\\s\\-_]*$").exactMatch(wallet)) { + DCOPRef(appid, returnObject).send("walletOpenResult", -1); + return; + } + + TQCString peerName = friendlyDCOPPeerName(); + + KWalletTransaction *xact = new KWalletTransaction; + + xact->appid = peerName; + xact->rawappid = appid; + xact->client = callingDcopClient(); + xact->wallet = wallet; + xact->wId = wId; + xact->tType = KWalletTransaction::Open; + xact->returnObject = returnObject; + _transactions.append(xact); + + DCOPRef(appid, returnObject).send("walletOpenResult", 0); + + TQTimer::singleShot(0, this, TQT_SLOT(processTransactions())); + checkActiveDialog(); +} + + +int KWalletD::openPath(const TQString& path, uint wId) { + if (!_enabled) { // guard + return -1; + } + + // FIXME: setup transaction + int rc = internalOpen(friendlyDCOPPeerName(), path, true, wId); + return rc; +} + + +int KWalletD::open(const TQString& wallet, uint wId) { + if (!_enabled) { // guard + return -1; + } + + if (!TQRegExp("^[A-Za-z0-9]+[A-Za-z0-9\\s\\-_]*$").exactMatch(wallet)) { + return -1; + } + + TQCString appid = friendlyDCOPPeerName(); + + KWalletTransaction *xact = new KWalletTransaction; + _transactions.append(xact); + + xact->appid = appid; + xact->client = callingDcopClient(); + xact->transaction = xact->client->beginTransaction(); + xact->wallet = wallet; + xact->wId = wId; + xact->tType = KWalletTransaction::Open; + xact->modal = true; // mark dialogs as modal, the app has blocking wait + TQTimer::singleShot(0, this, TQT_SLOT(processTransactions())); + checkActiveDialog(); + return 0; // process later +} + + +// Sets up a dialog that will be shown by tdewallet. +void KWalletD::setupDialog( TQWidget* dialog, WId wId, const TQCString& appid, bool modal ) { + if( wId != 0 ) + KWin::setMainWindow( dialog, wId ); // correct, set dialog parent + else { + if( appid.isEmpty()) + kdWarning() << "Using tdewallet without parent window!" << endl; + else + kdWarning() << "Application '" << appid << "' using tdewallet without parent window!" << endl; + // allow dialog activation even if it interrupts, better than trying hacks + // with keeping the dialog on top or on all desktops + kapp->updateUserTimestamp(); + } + if( modal ) + KWin::setState( dialog->winId(), NET::Modal ); + else + KWin::clearState( dialog->winId(), NET::Modal ); + activeDialog = dialog; +} + +// If there's a dialog already open and another application tries some operation that'd lead to +// opening a dialog, that application will be blocked by this dialog. A proper solution would +// be to set the second application's window also as a parent for the active dialog, so that +// KWin properly handles focus changes and so on, but there's currently no support for multiple +// dialog parents. Hopefully to be done in KDE4, for now just use all kinds of bad hacks to make +// sure the user doesn't overlook the active dialog. +void KWalletD::checkActiveDialog() { + if( !activeDialog || !activeDialog->isShown()) + return; + kapp->updateUserTimestamp(); + KWin::setState( activeDialog->winId(), NET::KeepAbove ); + KWin::setOnAllDesktops( activeDialog->winId(), true ); + KWin::forceActiveWindow( activeDialog->winId()); +} + +int KWalletD::doTransactionOpen(const TQCString& appid, const TQString& wallet, uint wId, bool modal) { + if (_firstUse && !wallets().contains(KWallet::Wallet::LocalWallet())) { + // First use wizard + KWalletWizard *wiz = new KWalletWizard(0); + setupDialog( wiz, wId, appid, modal ); + int rc = wiz->exec(); + if (rc == TQDialog::Accepted) { + TDEConfig cfg("tdewalletrc"); + cfg.setGroup("Wallet"); + cfg.writeEntry("First Use", false); + cfg.writeEntry("Enabled", wiz->_useWallet->isChecked()); + cfg.writeEntry("Close When Idle", wiz->_closeIdle->isChecked()); + cfg.writeEntry("Use One Wallet", !wiz->_networkWallet->isChecked()); + cfg.sync(); + reconfigure(); + + if (!wiz->_useWallet->isChecked()) { + delete wiz; + return -1; + } + + // Create the wallet + KWallet::Backend *b = new KWallet::Backend(KWallet::Wallet::LocalWallet()); + TQByteArray p; + p.duplicate(wiz->_pass1->text().utf8(), wiz->_pass1->text().length()); + b->open(p); + b->createFolder(KWallet::Wallet::PasswordFolder()); + b->createFolder(KWallet::Wallet::FormDataFolder()); + b->close(p); + p.fill(0); + delete b; + delete wiz; + } else { + delete wiz; + return -1; + } + } else if (_firstUse) { + TDEConfig cfg("tdewalletrc"); + _firstUse = false; + cfg.setGroup("Wallet"); + cfg.writeEntry("First Use", false); + cfg.sync(); + } + + int rc = internalOpen(appid, wallet, false, wId, modal); + return rc; +} + +int KWalletD::tryOpen(const TQString& wallet, const TQCString& password) +{ + if (isOpen(wallet)) + return 0; + + if (_tryOpenBlocked.isActive()) { + kdDebug() << "tryOpen is active.." << endl; + return -1; + } + + if (!KWallet::Backend::exists(wallet)) + return -2; + + KWallet::Backend *b = new KWallet::Backend(wallet, false /*isPath*/); + int rc = b->open(TQByteArray().duplicate(password, strlen(password))); + if (rc == 0) { + _wallets.insert(rc = generateHandle(), b); + _passwords[wallet] = password; + b->ref(); + _tryOpenBlocked.stop(); + TQByteArray data; + TQDataStream ds(data, IO_WriteOnly); + ds << wallet; + emitDCOPSignal("walletOpened(TQString)", data); + } + else { + delete b; + // make sure that we're not bombed with a dictionary attack + _tryOpenBlocked.start (30 * 1000, true /*single shot*/); + if (++_failed > 5) { + _failed = 0; + TQTimer::singleShot(0, this, TQT_SLOT(notifyFailures())); + } + + rc = -1; + } + return rc; +} + +int KWalletD::internalOpen(const TQCString& appid, const TQString& wallet, bool isPath, WId w, bool modal) { + int rc = -1; + bool brandNew = false; + + TQCString thisApp; + if (appid.isEmpty()) { + thisApp = "TDE System"; + } else { + thisApp = appid; + } + + if (implicitDeny(wallet, thisApp)) { + return -1; + } + + for (TQIntDictIterator i(_wallets); i.current(); ++i) { + if (i.current()->walletName() == wallet) { + rc = i.currentKey(); + break; + } + } + + if (rc == -1) { + if (_wallets.count() > 20) { + kdDebug() << "Too many wallets open." << endl; + return -1; + } + + KWallet::Backend *b = new KWallet::Backend(wallet, isPath); + KPasswordDialog *kpd = 0L; + bool emptyPass = false; + if ((isPath && TQFile::exists(wallet)) || (!isPath && KWallet::Backend::exists(wallet))) { + int pwless = b->open(TQByteArray()); + if (0 != pwless || !b->isOpen()) { + if (pwless == 0) { + // release, start anew + delete b; + b = new KWallet::Backend(wallet, isPath); + } + kpd = new KPasswordDialog(KPasswordDialog::Password, false, 0); + if (appid.isEmpty()) { + kpd->setPrompt(i18n("TDE has requested to open the wallet '%1'. Please enter the password for this wallet below.").arg(TQStyleSheet::escape(wallet))); + } else { + kpd->setPrompt(i18n("The application '%1' has requested to open the wallet '%2'. Please enter the password for this wallet below.").arg(TQStyleSheet::escape(appid)).arg(TQStyleSheet::escape(wallet))); + } + brandNew = false; + kpd->setButtonOK(KGuiItem(i18n("&Open"),"fileopen")); + } else { + emptyPass = true; + } + } else if (wallet == KWallet::Wallet::LocalWallet() || + wallet == KWallet::Wallet::NetworkWallet()) { + // Auto create these wallets. + kpd = new KPasswordDialog(KPasswordDialog::NewPassword, false, 0); + if (appid.isEmpty()) { + kpd->setPrompt(i18n("TDE has requested to open the wallet. This is used to store sensitive data in a secure fashion. Please enter a password to use with this wallet or click cancel to deny the application's request.")); + } else { + kpd->setPrompt(i18n("The application '%1' has requested to open the TDE wallet. This is used to store sensitive data in a secure fashion. Please enter a password to use with this wallet or click cancel to deny the application's request.").arg(TQStyleSheet::escape(appid))); + } + brandNew = true; + kpd->setButtonOK(KGuiItem(i18n("&Open"),"fileopen")); + } else { + kpd = new KPasswordDialog(KPasswordDialog::NewPassword, false, 0); + if (appid.length() == 0) { + kpd->setPrompt(i18n("TDE has requested to create a new wallet named '%1'. Please choose a password for this wallet, or cancel to deny the application's request.").arg(TQStyleSheet::escape(wallet))); + } else { + kpd->setPrompt(i18n("The application '%1' has requested to create a new wallet named '%2'. Please choose a password for this wallet, or cancel to deny the application's request.").arg(TQStyleSheet::escape(appid)).arg(TQStyleSheet::escape(wallet))); + } + brandNew = true; + kpd->setButtonOK(KGuiItem(i18n("C&reate"),"filenew")); + } + + if (kpd) { + kpd->setCaption(i18n("TDE Wallet Service")); + kpd->setAllowEmptyPasswords(true); + } + + const char *p = 0L; + while (!b->isOpen()) { + assert(kpd); // kpd can't be null if isOpen() is false + setupDialog( kpd, w, appid, modal ); + if (kpd->exec() == KDialog::Accepted) { + p = kpd->password(); + int rc = b->open(TQByteArray().duplicate(p, strlen(p))); + if (!b->isOpen()) { + kpd->setPrompt(i18n("Error opening the wallet '%1'. Please try again.
(Error code %2: %3)").arg(TQStyleSheet::escape(wallet)).arg(rc).arg(KWallet::Backend::openRCToString(rc))); + kpd->clearPassword(); + } + } else { + break; + } + } + + if (!emptyPass && (!p || !b->isOpen())) { + delete b; + delete kpd; + return -1; + } + + if (emptyPass && _openPrompt && !isAuthorizedApp(appid, wallet, w)) { + delete b; + delete kpd; + return -1; + } + + _wallets.insert(rc = generateHandle(), b); + if (emptyPass) { + _passwords[wallet] = ""; + } else { + _passwords[wallet] = p; + } + _handles[appid].append(rc); + + delete kpd; // don't refactor this!! Argh I hate KPassDlg + + if (brandNew) { + createFolder(rc, KWallet::Wallet::PasswordFolder()); + createFolder(rc, KWallet::Wallet::FormDataFolder()); + } + + b->ref(); + if (_closeIdle && _timeouts) { + _timeouts->addTimer(rc, _idleTime); + } + TQByteArray data; + TQDataStream ds(data, IO_WriteOnly); + ds << wallet; + if (brandNew) { + emitDCOPSignal("walletCreated(TQString)", data); + } + emitDCOPSignal("walletOpened(TQString)", data); + if (_wallets.count() == 1 && _launchManager) { + TDEApplication::startServiceByDesktopName("tdewalletmanager-tdewalletd"); + } + } else { + if (!_handles[appid].contains(rc) && _openPrompt && !isAuthorizedApp(appid, wallet, w)) { + return -1; + } + _handles[appid].append(rc); + _wallets.find(rc)->ref(); + } + + return rc; +} + + +bool KWalletD::isAuthorizedApp(const TQCString& appid, const TQString& wallet, WId w) { + int response = 0; + + TQCString thisApp; + if (appid.isEmpty()) { + thisApp = "TDE System"; + } else { + thisApp = appid; + } + + if (!implicitAllow(wallet, thisApp)) { + KBetterThanKDialogBase *dialog = new KBetterThanKDialogBase; + if (appid.isEmpty()) { + dialog->setLabel(i18n("TDE has requested access to the open wallet '%1'.").arg(TQStyleSheet::escape(wallet))); + } else { + dialog->setLabel(i18n("The application '%1' has requested access to the open wallet '%2'.").arg(TQStyleSheet::escape(TQString(appid))).arg(TQStyleSheet::escape(wallet))); + } + setupDialog( dialog, w, appid, false ); + response = dialog->exec(); + delete dialog; + } + + if (response == 0 || response == 1) { + if (response == 1) { + TDEConfig cfg("tdewalletrc"); + cfg.setGroup("Auto Allow"); + TQStringList apps = cfg.readListEntry(wallet); + if (!apps.contains(thisApp)) { + apps += thisApp; + _implicitAllowMap[wallet] += thisApp; + cfg.writeEntry(wallet, apps); + cfg.sync(); + } + } + } else if (response == 3) { + TDEConfig cfg("tdewalletrc"); + cfg.setGroup("Auto Deny"); + TQStringList apps = cfg.readListEntry(wallet); + if (!apps.contains(thisApp)) { + apps += thisApp; + _implicitDenyMap[wallet] += thisApp; + cfg.writeEntry(wallet, apps); + cfg.sync(); + } + return false; + } else { + return false; + } + return true; +} + + +int KWalletD::deleteWallet(const TQString& wallet) { + TQString path = TDEGlobal::dirs()->saveLocation("tdewallet") + TQDir::separator() + wallet + ".kwl"; + + if (TQFile::exists(path)) { + close(wallet, true); + TQFile::remove(path); + TQByteArray data; + TQDataStream ds(data, IO_WriteOnly); + ds << wallet; + emitDCOPSignal("walletDeleted(TQString)", data); + return 0; + } + + return -1; +} + + +void KWalletD::changePassword(const TQString& wallet, uint wId) { + TQCString appid = friendlyDCOPPeerName(); + + KWalletTransaction *xact = new KWalletTransaction; + + xact->appid = appid; + xact->client = callingDcopClient(); + xact->wallet = wallet; + xact->wId = wId; + xact->tType = KWalletTransaction::ChangePassword; + + _transactions.append(xact); + + TQTimer::singleShot(0, this, TQT_SLOT(processTransactions())); + checkActiveDialog(); +} + + +void KWalletD::doTransactionChangePassword(const TQCString& appid, const TQString& wallet, uint wId) { + TQIntDictIterator it(_wallets); + KWallet::Backend *w = 0L; + int handle = -1; + bool reclose = false; + + for (; it.current(); ++it) { + if (it.current()->walletName() == wallet) { + break; + } + } + + if (!it.current()) { + handle = doTransactionOpen(appid, wallet, wId,false); + if (-1 == handle) { + KMessageBox::sorryWId(wId, i18n("Unable to open wallet. The wallet must be opened in order to change the password."), i18n("TDE Wallet Service")); + return; + } + + w = _wallets.find(handle); + reclose = true; + } else { + handle = it.currentKey(); + w = it.current(); + } + + assert(w); + + KPasswordDialog *kpd; + kpd = new KPasswordDialog(KPasswordDialog::NewPassword, false, 0); + kpd->setPrompt(i18n("Please choose a new password for the wallet '%1'.").arg(TQStyleSheet::escape(wallet))); + kpd->setCaption(i18n("TDE Wallet Service")); + kpd->setAllowEmptyPasswords(true); + setupDialog( kpd, wId, appid, false ); + if (kpd->exec() == KDialog::Accepted) { + const char *p = kpd->password(); + if (p) { + _passwords[wallet] = p; + TQByteArray pa; + pa.duplicate(p, strlen(p)); + int rc = w->close(pa); + if (rc < 0) { + KMessageBox::sorryWId(wId, i18n("Error re-encrypting the wallet. Password was not changed."), i18n("TDE Wallet Service")); + reclose = true; + } else { + rc = w->open(pa); + if (rc < 0) { + KMessageBox::sorryWId(wId, i18n("Error reopening the wallet. Data may be lost."), i18n("TDE Wallet Service")); + reclose = true; + } + } + } + } + + delete kpd; + + if (reclose) { + close(handle, true); + } +} + + +int KWalletD::close(const TQString& wallet, bool force) { + int handle = -1; + KWallet::Backend *w = 0L; + + for (TQIntDictIterator it(_wallets); + it.current(); + ++it) { + if (it.current()->walletName() == wallet) { + handle = it.currentKey(); + w = it.current(); + break; + } + } + + return closeWallet(w, handle, force); +} + + +int KWalletD::closeWallet(KWallet::Backend *w, int handle, bool force) { + if (w) { + const TQString& wallet = w->walletName(); + assert(_passwords.contains(wallet)); + if (w->refCount() == 0 || force) { + invalidateHandle(handle); + if (_closeIdle && _timeouts) { + _timeouts->removeTimer(handle); + } + _wallets.remove(handle); + if (_passwords.contains(wallet)) { + w->close(TQByteArray().duplicate(_passwords[wallet].data(), _passwords[wallet].length())); + _passwords[wallet].fill(0); + _passwords.remove(wallet); + } + doCloseSignals(handle, wallet); + delete w; + return 0; + } + return 1; + } + + return -1; +} + + +int KWalletD::close(int handle, bool force) { + TQCString appid = friendlyDCOPPeerName(); + KWallet::Backend *w = _wallets.find(handle); + bool contains = false; + + if (w) { // the handle is valid + if (_handles.contains(appid)) { // we know this app + if (_handles[appid].contains(handle)) { + // the app owns this handle + _handles[appid].remove(_handles[appid].find(handle)); + contains = true; + if (_handles[appid].isEmpty()) { + _handles.remove(appid); + } + } + } + + // watch the side effect of the deref() + if ((contains && w->deref() == 0 && !_leaveOpen) || force) { + if (_closeIdle && _timeouts) { + _timeouts->removeTimer(handle); + } + _wallets.remove(handle); + if (force) { + invalidateHandle(handle); + } + if (_passwords.contains(w->walletName())) { + w->close(TQByteArray().duplicate(_passwords[w->walletName()].data(), _passwords[w->walletName()].length())); + _passwords[w->walletName()].fill(0); + _passwords.remove(w->walletName()); + } + doCloseSignals(handle, w->walletName()); + delete w; + return 0; + } + return 1; // not closed + } + + return -1; // not open to begin with, or other error +} + + +bool KWalletD::isOpen(const TQString& wallet) const { + for (TQIntDictIterator it(_wallets); + it.current(); + ++it) { + if (it.current()->walletName() == wallet) { + return true; + } + } + return false; +} + + +bool KWalletD::isOpen(int handle) { + if (handle == 0) { + return false; + } + + KWallet::Backend *rc = _wallets.find(handle); + + if (rc == 0 && ++_failed > 5) { + _failed = 0; + TQTimer::singleShot(0, this, TQT_SLOT(notifyFailures())); + } else if (rc != 0) { + _failed = 0; + } + + return rc != 0; +} + + +TQStringList KWalletD::wallets() const { + TQString path = TDEGlobal::dirs()->saveLocation("tdewallet"); + TQDir dir(path, "*.kwl"); + TQStringList rc; + + dir.setFilter(TQDir::Files | TQDir::NoSymLinks); + + const TQFileInfoList *list = dir.entryInfoList(); + TQFileInfoListIterator it(*list); + TQFileInfo *fi; + while ((fi = it.current()) != 0L) { + TQString fn = fi->fileName(); + if (fn.endsWith(".kwl")) { + fn.truncate(fn.length()-4); + } + rc += fn; + ++it; + } + return rc; +} + + +void KWalletD::sync(int handle) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + TQByteArray p; + TQString wallet = b->walletName(); + p.duplicate(_passwords[wallet].data(), _passwords[wallet].length()); + b->sync(p); + p.fill(0); + } +} + + +TQStringList KWalletD::folderList(int handle) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + return b->folderList(); + } + + return TQStringList(); +} + + +bool KWalletD::hasFolder(int handle, const TQString& f) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + return b->hasFolder(f); + } + + return false; +} + + +bool KWalletD::removeFolder(int handle, const TQString& f) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + bool rc = b->removeFolder(f); + // write changes to disk immediately + TQByteArray p; + TQString wallet = b->walletName(); + p.duplicate(_passwords[wallet].data(), _passwords[wallet].length()); + b->sync(p); + p.fill(0); + TQByteArray data; + TQDataStream ds(data, IO_WriteOnly); + ds << b->walletName(); + emitDCOPSignal("folderListUpdated(TQString)", data); + return rc; + } + + return false; +} + + +bool KWalletD::createFolder(int handle, const TQString& f) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + bool rc = b->createFolder(f); + // write changes to disk immediately + TQByteArray p; + TQString wallet = b->walletName(); + p.duplicate(_passwords[wallet].data(), _passwords[wallet].length()); + b->sync(p); + p.fill(0); + TQByteArray data; + TQDataStream ds(data, IO_WriteOnly); + ds << b->walletName(); + emitDCOPSignal("folderListUpdated(TQString)", data); + return rc; + } + + return false; +} + + +TQByteArray KWalletD::readMap(int handle, const TQString& folder, const TQString& key) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + KWallet::Entry *e = b->readEntry(key); + if (e && e->type() == KWallet::Wallet::Map) { + return e->map(); + } + } + + return TQByteArray(); +} + + +TQMap KWalletD::readMapList(int handle, const TQString& folder, const TQString& key) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + TQPtrList e = b->readEntryList(key); + TQMap rc; + TQPtrListIterator it(e); + KWallet::Entry *entry; + while ((entry = it.current())) { + if (entry->type() == KWallet::Wallet::Map) { + rc.insert(entry->key(), entry->map()); + } + ++it; + } + return rc; + } + + return TQMap(); +} + + +TQByteArray KWalletD::readEntry(int handle, const TQString& folder, const TQString& key) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + KWallet::Entry *e = b->readEntry(key); + if (e) { + return e->value(); + } + } + + return TQByteArray(); +} + + +TQMap KWalletD::readEntryList(int handle, const TQString& folder, const TQString& key) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + TQPtrList e = b->readEntryList(key); + TQMap rc; + TQPtrListIterator it(e); + KWallet::Entry *entry; + while ((entry = it.current())) { + rc.insert(entry->key(), entry->value()); + ++it; + } + return rc; + } + + return TQMap(); +} + + +TQStringList KWalletD::entryList(int handle, const TQString& folder) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + return b->entryList(); + } + + return TQStringList(); +} + + +TQString KWalletD::readPassword(int handle, const TQString& folder, const TQString& key) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + KWallet::Entry *e = b->readEntry(key); + if (e && e->type() == KWallet::Wallet::Password) { + return e->password(); + } + } + + return TQString::null; +} + + +TQMap KWalletD::readPasswordList(int handle, const TQString& folder, const TQString& key) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + TQPtrList e = b->readEntryList(key); + TQMap rc; + TQPtrListIterator it(e); + KWallet::Entry *entry; + while ((entry = it.current())) { + if (entry->type() == KWallet::Wallet::Password) { + rc.insert(entry->key(), entry->password()); + } + ++it; + } + return rc; + } + + return TQMap(); +} + + +int KWalletD::writeMap(int handle, const TQString& folder, const TQString& key, const TQByteArray& value) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + KWallet::Entry e; + e.setKey(key); + e.setValue(value); + e.setType(KWallet::Wallet::Map); + b->writeEntry(&e); + // write changes to disk immediately + TQByteArray p; + TQString wallet = b->walletName(); + p.duplicate(_passwords[wallet].data(), _passwords[wallet].length()); + b->sync(p); + p.fill(0); + emitFolderUpdated(b->walletName(), folder); + return 0; + } + + return -1; +} + + +int KWalletD::writeEntry(int handle, const TQString& folder, const TQString& key, const TQByteArray& value, int entryType) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + KWallet::Entry e; + e.setKey(key); + e.setValue(value); + e.setType(KWallet::Wallet::EntryType(entryType)); + b->writeEntry(&e); + // write changes to disk immediately + TQByteArray p; + TQString wallet = b->walletName(); + p.duplicate(_passwords[wallet].data(), _passwords[wallet].length()); + b->sync(p); + p.fill(0); + emitFolderUpdated(b->walletName(), folder); + return 0; + } + + return -1; +} + + +int KWalletD::writeEntry(int handle, const TQString& folder, const TQString& key, const TQByteArray& value) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + KWallet::Entry e; + e.setKey(key); + e.setValue(value); + e.setType(KWallet::Wallet::Stream); + b->writeEntry(&e); + // write changes to disk immediately + TQByteArray p; + TQString wallet = b->walletName(); + p.duplicate(_passwords[wallet].data(), _passwords[wallet].length()); + b->sync(p); + p.fill(0); + emitFolderUpdated(b->walletName(), folder); + return 0; + } + + return -1; +} + + +int KWalletD::writePassword(int handle, const TQString& folder, const TQString& key, const TQString& value) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + KWallet::Entry e; + e.setKey(key); + e.setValue(value); + e.setType(KWallet::Wallet::Password); + b->writeEntry(&e); + // write changes to disk immediately + TQByteArray p; + TQString wallet = b->walletName(); + p.duplicate(_passwords[wallet].data(), _passwords[wallet].length()); + b->sync(p); + p.fill(0); + emitFolderUpdated(b->walletName(), folder); + return 0; + } + + return -1; +} + + +int KWalletD::entryType(int handle, const TQString& folder, const TQString& key) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + if (!b->hasFolder(folder)) { + return KWallet::Wallet::Unknown; + } + b->setFolder(folder); + if (b->hasEntry(key)) { + return b->readEntry(key)->type(); + } + } + + return KWallet::Wallet::Unknown; +} + + +bool KWalletD::hasEntry(int handle, const TQString& folder, const TQString& key) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + if (!b->hasFolder(folder)) { + return false; + } + b->setFolder(folder); + return b->hasEntry(key); + } + + return false; +} + + +int KWalletD::removeEntry(int handle, const TQString& folder, const TQString& key) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + if (!b->hasFolder(folder)) { + return 0; + } + b->setFolder(folder); + bool rc = b->removeEntry(key); + // write changes to disk immediately + TQByteArray p; + TQString wallet = b->walletName(); + p.duplicate(_passwords[wallet].data(), _passwords[wallet].length()); + b->sync(p); + p.fill(0); + emitFolderUpdated(b->walletName(), folder); + return rc ? 0 : -3; + } + + return -1; +} + + +void KWalletD::slotAppUnregistered(const TQCString& app) { + if (_handles.contains(app)) { + TQValueList l = _handles[app]; + for (TQValueList::Iterator i = l.begin(); i != l.end(); ++i) { + _handles[app].remove(*i); + KWallet::Backend *w = _wallets.find(*i); + if (w && !_leaveOpen && 0 == w->deref()) { + close(w->walletName(), true); + } + } + _handles.remove(app); + } +} + + +void KWalletD::invalidateHandle(int handle) { + for (TQMap >::Iterator i = _handles.begin(); + i != _handles.end(); + ++i) { + i.data().remove(handle); + } +} + + +KWallet::Backend *KWalletD::getWallet(const TQCString& appid, int handle) { + if (handle == 0) { + return 0L; + } + + KWallet::Backend *w = _wallets.find(handle); + + if (w) { // the handle is valid + if (_handles.contains(appid)) { // we know this app + if (_handles[appid].contains(handle)) { + // the app owns this handle + _failed = 0; + if (_closeIdle && _timeouts) { + _timeouts->resetTimer(handle, _idleTime); + } + return w; + } + } + } + + if (++_failed > 5) { + _failed = 0; + TQTimer::singleShot(0, this, TQT_SLOT(notifyFailures())); + } + + return 0L; +} + + +void KWalletD::notifyFailures() { + if (!_showingFailureNotify) { + _showingFailureNotify = true; + KMessageBox::information(0, i18n("There have been repeated failed attempts to gain access to a wallet. An application may be misbehaving."), i18n("TDE Wallet Service")); + _showingFailureNotify = false; + } +} + + +void KWalletD::doCloseSignals(int handle, const TQString& wallet) { + TQByteArray data; + TQDataStream ds(data, IO_WriteOnly); + ds << handle; + emitDCOPSignal("walletClosed(int)", data); + + TQByteArray data2; + TQDataStream ds2(data2, IO_WriteOnly); + ds2 << wallet; + emitDCOPSignal("walletClosed(TQString)", data2); + + if (_wallets.isEmpty()) { + emitDCOPSignal("allWalletsClosed()", TQByteArray()); + } +} + + +int KWalletD::renameEntry(int handle, const TQString& folder, const TQString& oldName, const TQString& newName) { + KWallet::Backend *b; + + if ((b = getWallet(friendlyDCOPPeerName(), handle))) { + b->setFolder(folder); + int rc = b->renameEntry(oldName, newName); + // write changes to disk immediately + TQByteArray p; + TQString wallet = b->walletName(); + p.duplicate(_passwords[wallet].data(), _passwords[wallet].length()); + b->sync(p); + p.fill(0); + emitFolderUpdated(b->walletName(), folder); + return rc; + } + + return -1; +} + + +TQStringList KWalletD::users(const TQString& wallet) const { + TQStringList rc; + + for (TQIntDictIterator it(_wallets); + it.current(); + ++it) { + if (it.current()->walletName() == wallet) { + for (TQMap >::ConstIterator hit = _handles.begin(); hit != _handles.end(); ++hit) { + if (hit.data().contains(it.currentKey())) { + rc += hit.key(); + } + } + break; + } + } + + return rc; +} + + +bool KWalletD::disconnectApplication(const TQString& wallet, const TQCString& application) { + for (TQIntDictIterator it(_wallets); + it.current(); + ++it) { + if (it.current()->walletName() == wallet) { + if (_handles[application].contains(it.currentKey())) { + _handles[application].remove(it.currentKey()); + + if (_handles[application].isEmpty()) { + _handles.remove(application); + } + + if (it.current()->deref() == 0) { + close(it.current()->walletName(), true); + } + + TQByteArray data; + TQDataStream ds(data, IO_WriteOnly); + ds << wallet; + ds << application; + emitDCOPSignal("applicationDisconnected(TQString,TQCString)", data); + + return true; + } + } + } + + return false; +} + + +void KWalletD::emitFolderUpdated(const TQString& wallet, const TQString& folder) { + TQByteArray data; + TQDataStream ds(data, IO_WriteOnly); + ds << wallet; + ds << folder; + emitDCOPSignal("folderUpdated(TQString,TQString)", data); +} + + +void KWalletD::emitWalletListDirty() { + emitDCOPSignal("walletListDirty()", TQByteArray()); +} + + +void KWalletD::reconfigure() { + TDEConfig cfg("tdewalletrc"); + cfg.setGroup("Wallet"); + _firstUse = cfg.readBoolEntry("First Use", true); + _enabled = cfg.readBoolEntry("Enabled", true); + _launchManager = cfg.readBoolEntry("Launch Manager", true); + _leaveOpen = cfg.readBoolEntry("Leave Open", false); + bool idleSave = _closeIdle; + _closeIdle = cfg.readBoolEntry("Close When Idle", false); + _openPrompt = cfg.readBoolEntry("Prompt on Open", true); + int timeSave = _idleTime; + // in minutes! + _idleTime = cfg.readNumEntry("Idle Timeout", 10) * 60 * 1000; + + if (cfg.readBoolEntry("Close on Screensaver", false)) { + connectDCOPSignal("kdesktop", "KScreensaverIface", "KDE_start_screensaver()", "closeAllWallets()", false); + } else { + disconnectDCOPSignal("kdesktop", "KScreensaverIface", "KDE_start_screensaver()", "closeAllWallets()"); + } + + // Handle idle changes + if (_closeIdle) { + if (_idleTime != timeSave) { // Timer length changed + TQIntDictIterator it(_wallets); + for (; it.current(); ++it) { + _timeouts->resetTimer(it.currentKey(), _idleTime); + } + } + + if (!idleSave) { // add timers for all the wallets + TQIntDictIterator it(_wallets); + for (; it.current(); ++it) { + _timeouts->addTimer(it.currentKey(), _idleTime); + } + } + } else { + _timeouts->clear(); + } + + // Update the implicit allow stuff + _implicitAllowMap.clear(); + cfg.setGroup("Auto Allow"); + TQStringList entries = cfg.entryMap("Auto Allow").keys(); + for (TQStringList::Iterator i = entries.begin(); i != entries.end(); ++i) { + _implicitAllowMap[*i] = cfg.readListEntry(*i); + } + + // Update the implicit allow stuff + _implicitDenyMap.clear(); + cfg.setGroup("Auto Deny"); + entries = cfg.entryMap("Auto Deny").keys(); + for (TQStringList::Iterator i = entries.begin(); i != entries.end(); ++i) { + _implicitDenyMap[*i] = cfg.readListEntry(*i); + } + + // Update if wallet was enabled/disabled + if (!_enabled) { // close all wallets + while (!_wallets.isEmpty()) { + TQIntDictIterator it(_wallets); + if (!it.current()) { // necessary? + break; + } + closeWallet(it.current(), it.currentKey(), true); + } + } +} + + +bool KWalletD::isEnabled() const { + return _enabled; +} + + +bool KWalletD::folderDoesNotExist(const TQString& wallet, const TQString& folder) { + if (!wallets().contains(wallet)) { + return true; + } + + for (TQIntDictIterator it(_wallets); it.current(); ++it) { + if (it.current()->walletName() == wallet) { + return it.current()->folderDoesNotExist(folder); + } + } + + KWallet::Backend *b = new KWallet::Backend(wallet); + b->open(TQByteArray()); + bool rc = b->folderDoesNotExist(folder); + delete b; + return rc; +} + + +bool KWalletD::keyDoesNotExist(const TQString& wallet, const TQString& folder, const TQString& key) { + if (!wallets().contains(wallet)) { + return true; + } + + for (TQIntDictIterator it(_wallets); it.current(); ++it) { + if (it.current()->walletName() == wallet) { + return it.current()->entryDoesNotExist(folder, key); + } + } + + KWallet::Backend *b = new KWallet::Backend(wallet); + b->open(TQByteArray()); + bool rc = b->entryDoesNotExist(folder, key); + delete b; + return rc; +} + + +bool KWalletD::implicitAllow(const TQString& wallet, const TQCString& app) { + return _implicitAllowMap[wallet].contains(TQString::fromLocal8Bit(app)); +} + + +bool KWalletD::implicitDeny(const TQString& wallet, const TQCString& app) { + return _implicitDenyMap[wallet].contains(TQString::fromLocal8Bit(app)); +} + + +TQCString KWalletD::friendlyDCOPPeerName() { + DCOPClient *dc = callingDcopClient(); + if (!dc) { + return ""; + } + return dc->senderId().replace(TQRegExp("-[0-9]+$"), ""); +} + + +void KWalletD::timedOut(int id) { + KWallet::Backend *w = _wallets.find(id); + if (w) { + closeWallet(w, id, true); + } +} + + +void KWalletD::closeAllWallets() { + TQIntDict tw = _wallets; + + for (TQIntDictIterator it(tw); it.current(); ++it) { + closeWallet(it.current(), it.currentKey(), true); + } + + tw.clear(); + + // All of this should be basically noop. Let's just be safe. + _wallets.clear(); + + for (TQMap::Iterator it = _passwords.begin(); + it != _passwords.end(); + ++it) { + it.data().fill(0); + } + _passwords.clear(); +} + + +TQString KWalletD::networkWallet() { + return KWallet::Wallet::NetworkWallet(); +} + + +TQString KWalletD::localWallet() { + return KWallet::Wallet::LocalWallet(); +} + + +#include "tdewalletd.moc" diff --git a/tdeio/misc/tdewalletd/tdewalletd.desktop b/tdeio/misc/tdewalletd/tdewalletd.desktop new file mode 100644 index 000000000..1e65fe0df --- /dev/null +++ b/tdeio/misc/tdewalletd/tdewalletd.desktop @@ -0,0 +1,151 @@ +[Desktop Entry] +Type=Service +ServiceTypes=KDEDModule +X-TDE-ModuleType=Library +X-TDE-Library=tdewalletd +X-TDE-FactoryName=tdewalletd +X-TDE-Kded-autoload=false +X-TDE-Kded-load-on-demand=true +Name=KWallet Daemon Module +Name[af]=KBeursie Bediener Module +Name[ar]=مراقب وحدة KWallet +Name[az]=KWallet Demon Modulu +Name[be]=Модуль сервіса KWallet +Name[bg]=Демон Портфейл +Name[bn]=কে-ওয়ালেট ডিমন মডিউল +Name[br]=Mollad an diaoul KWallet +Name[ca]=Mòdul del dimoni KWallet +Name[cs]=Modul démona KWallet +Name[csb]=Pòrtfel +Name[cy]=Modiwl Daemon KWaled +Name[da]=KWallet Dæmonmodul +Name[de]=Digitale Brieftasche +Name[el]=Άρθρωμα δαίμονα KWallet +Name[eo]=Sekreteja demono-modulo +Name[es]=Módulo de demonio KWallet +Name[et]=KWalleti deemoni moodul +Name[eu]=KWallet daemon modulua +Name[fa]=پیمانه شبح KWallet +Name[fi]=KWallet-palvelinmoduuli +Name[fr]=Module démon KWallet +Name[ga]=Modúl Deamhain KWallet +Name[gl]=Módulo do Demo KWallet +Name[he]=מודול תהליך הרקע של KWallet +Name[hi]=केवैलट डेमन मॉड्यूल +Name[hr]=Modul KWallet demona +Name[hu]=KWallet szolgáltatás +Name[id]=Modul Daemon KWallet +Name[is]=KWallet þjónseining +Name[it]=Modulo demone KWallet +Name[ja]=KWallet デーモンモジュール +Name[ka]=KWallet გუშაგის მოდული +Name[kk]=KWallet әмиян қызметтің модулі +Name[km]=ម៉ូឌុល Daemon KWallet +Name[ko]=K지갑 데몬 모듈 +Name[lb]=KWallet-Dämonmodul +Name[lt]=TDE slaptažodinių tarnybos modulis +Name[lv]=KWallet Dēmona Modulis +Name[mn]=KWallet Daemon Модул +Name[ms]=Modul Daemon KWallet +Name[nb]=KWallet nisseprogramtillegg +Name[nds]=KWallet-Dämoon +Name[ne]=KWallet डेइमन मोड्युल +Name[nl]=KWallet daemon-module +Name[nn]=KWallet-nissemodul +Name[pa]=KWallet ਪੇਸ਼ਕਾਰੀ ਮੈਡੀਊਲ +Name[pl]=Portfel +Name[pt]=Módulo do Servidor do KWallet +Name[pt_BR]=Módulo do Serviço do KWallet +Name[ro]=Modul demon KWallet +Name[ru]=Служба бумажника +Name[rw]=Igice Dayimoni KUruhago +Name[se]=KWallet-bálvámoduvla +Name[sk]=Modul démona KWallet +Name[sl]=Modul demona KListnica +Name[sq]=Demoni për Modulin KWallet +Name[sr]=KWallet демон модул +Name[sr@Latn]=KWallet demon modul +Name[sv]=Kwallet-demonmodul +Name[ta]=KWallet டெமான் பகுதி +Name[te]=కెవాలెట్ సూత్రధారి మాడ్యూల్ +Name[tg]=Модули Демон KWallet +Name[th]=โมดูลเดมอน KWallet +Name[tr]=KWallet Program Modülü +Name[tt]=KWallet Xezmäteneñ Modulı +Name[uk]=Модуль демону KWallet +Name[uz]=KWallet xizmatining moduli +Name[uz@cyrillic]=KWallet хизматининг модули +Name[vi]=Mô-đun trình nền KWallet +Name[zh_CN]=KWallet 守护进程模块 +Name[zh_HK]=KWAllet 伺服程式模組 +Name[zh_TW]=KWAllet 服務程式模組 +Comment=KWallet daemon module for KDED +Comment[af]=KBeursie bediener module vir KDED +Comment[be]=Модуль сервіса KWallet для KDED +Comment[bg]=Модул демон за системата Портфейл за KDED +Comment[bn]=KDED-র জন্য কে-ওয়ালেট ডিমন মডিউল +Comment[br]=Mollad an diaoul KWallet evit KDED +Comment[bs]=KWallet daemon modul za KDED +Comment[ca]=Mòdul del dimoni KWallet per a KDED +Comment[cs]=Modul démona KWallet pro KDED +Comment[csb]=Mòduł KWallet w KDED +Comment[da]=KWallet Dæmonmodul for KDED +Comment[de]=Unterstützung für die digitale Brieftasche "KWallet" +Comment[el]=Άρθρωμα δαίμονα KWallet για το KDED +Comment[eo]=Sekreteja demono-modulo por KDED +Comment[es]=Módulo de demonio KWallet para KDED +Comment[et]=KDED KWalleti deemoni moodul +Comment[eu]=KWallet daemon modulua KDEDrako +Comment[fa]=پیمانۀ شبح KWallet برای KDED +Comment[fi]=KWallet palvelinmoduuli KDED:lle +Comment[fr]=Module démon KWallet pour KDED +Comment[fy]=KWallet daemon module foar KDED +Comment[ga]=Modúl deamhain KWallet le haghaidh KDED +Comment[gl]=Demo de KWallet para KDED +Comment[he]=מודול תהליך רקע של KWallet עבור KDED +Comment[hi]=केडीईडी के लिए के-वॉलेट डेमन मॉड्यूल +Comment[hr]=KWallet demon modul za KDED +Comment[hu]=KWallet szolgáltatásmodul a KDED-hez +Comment[id]=Modul daemon KWallet untuk KDED +Comment[is]=KWallet þjónseining fyrir KDED +Comment[it]=Modulo demone KWallet per KDED +Comment[ja]=KDED 用の KWallet デーモンモジュール +Comment[ka]=KSSL მოდული TDE-სთვის +Comment[kk]=TDE KWallet әмиянін басқару қызметтің модулі +Comment[km]=ម៉ូឌុល daemon KWallet សម្រាប់ KDED +Comment[lb]=KWallet-Dämonmodul fir KDED +Comment[lt]=TDE slaptažodinių tarnybos modulis skirtas KDED +Comment[lv]=KWallet Dēmona Modulis priekš KDED +Comment[mk]=KWallet даемон модул за KDED +Comment[ms]=Modul Daemon KWallet untuk KDED +Comment[nb]=KWallet nissemodul for KDED +Comment[nds]=KWallet-Dämoonmoduul för KDED +Comment[ne]=KDED का लागि डेइमन मोड्युल KWallet +Comment[nl]=KWallet daemon-module voor KDED +Comment[nn]=KWallet-nissemodul for KDED +Comment[pa]=KDED ਲਈ KWallet ਪੇਸ਼ਕਾਰੀ ਮੈਡੀਊਲ +Comment[pl]=Moduł KWallet w KDED +Comment[pt]=Módulo servidor do KWallet para o KDED +Comment[pt_BR]=Módulo do serviço de carteira para o TDE +Comment[ro]=Modul demon KWallet pentru KDED +Comment[ru]=Управление бумажником TDE +Comment[rw]=Igice cya dayimoni KUruhago cya KDED +Comment[se]=KDED:a KWallet-bálvámoduvla +Comment[sk]=Modul démona KWallet pre KDED +Comment[sl]=Modul demona KListnica za KDED +Comment[sr]=KWallet демон модул за KDED +Comment[sr@Latn]=KWallet demon modul za KDED +Comment[sv]=Kwallet-demonmodul för KDED +Comment[ta]=KDEDக்கான KWallet Daemon தொகுதி +Comment[te]=కెడిఈడి కొరకు కెవాలెట్ సూత్రధారి మాడ్యూల్ +Comment[tg]=Модули Демон KWallet барои KDED +Comment[th]=โมดูลเดมอน KWallet สำหรับ KDED +Comment[tr]=KDED için KWallet program modülü +Comment[tt]=KDED öçen KWallet xezmäteneñ modulı +Comment[uk]=Модуль демону торбинок KWallet для KDED +Comment[uz]=KDED uchun KWallet xizmatining moduli +Comment[uz@cyrillic]=KDED учун KWallet хизматининг модули +Comment[vi]=Mô-đun trình nền KWallet cho KDED. +Comment[zh_CN]=KDED 的 KWallet 守护进程模块 +Comment[zh_HK]=KDED 的 KWallet 伺服程式模組 +Comment[zh_TW]=KDED 的 KWallet 服務程式模組 diff --git a/tdeio/misc/tdewalletd/tdewalletd.h b/tdeio/misc/tdewalletd/tdewalletd.h new file mode 100644 index 000000000..b3a315413 --- /dev/null +++ b/tdeio/misc/tdewalletd/tdewalletd.h @@ -0,0 +1,199 @@ +/* + This file is part of the KDE libraries + + Copyright (c) 2002-2004 George Staikos + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ +#ifndef _KWALLETD_H_ +#define _KWALLETD_H_ + +#include +#include +#include +#include +#include +#include +#include "tdewalletbackend.h" + +#include +#include + +class KDirWatch; +class KTimeout; + +// @Private +class KWalletTransaction; + +class KWalletD : public KDEDModule { + Q_OBJECT + K_DCOP + public: + KWalletD(const TQCString &name); + virtual ~KWalletD(); + + k_dcop: + // Is the wallet enabled? If not, all open() calls fail. + virtual bool isEnabled() const; + + // Open and unlock the wallet + virtual int open(const TQString& wallet, uint wId); + // Open and unlock the wallet + virtual int tryOpen(const TQString& wallet, const TQCString& passwd); + // Open and unlock the wallet with this path + + virtual int openPath(const TQString& path, uint wId); + + // Asynchronous open - must give the object to return the handle + // to. + virtual void openAsynchronous(const TQString& wallet, const TQCString& returnObject, uint wId); + + // Close and lock the wallet + // If force = true, will close it for all users. Behave. This + // can break applications, and is generally intended for use by + // the wallet manager app only. + virtual int close(const TQString& wallet, bool force); + virtual int close(int handle, bool force); + + // Save to disk but leave open + virtual ASYNC sync(int handle); + + // Physically deletes the wallet from disk. + virtual int deleteWallet(const TQString& wallet); + + // Returns true if the wallet is open + virtual bool isOpen(const TQString& wallet) const; + virtual bool isOpen(int handle); + + // List the users of this wallet + virtual TQStringList users(const TQString& wallet) const; + + // Change the password of this wallet + virtual void changePassword(const TQString& wallet, uint wId); + + // A list of all wallets + virtual TQStringList wallets() const; + + // A list of all folders in this wallet + virtual TQStringList folderList(int handle); + + // Does this wallet have this folder? + virtual bool hasFolder(int handle, const TQString& folder); + + // Create this folder + virtual bool createFolder(int handle, const TQString& folder); + + // Remove this folder + virtual bool removeFolder(int handle, const TQString& folder); + + // List of entries in this folder + virtual TQStringList entryList(int handle, const TQString& folder); + + // Read an entry. If the entry does not exist, it just + // returns an empty result. It is your responsibility to check + // hasEntry() first. + virtual TQByteArray readEntry(int handle, const TQString& folder, const TQString& key); + virtual TQByteArray readMap(int handle, const TQString& folder, const TQString& key); + virtual TQString readPassword(int handle, const TQString& folder, const TQString& key); + virtual TQMap readEntryList(int handle, const TQString& folder, const TQString& key); + virtual TQMap readMapList(int handle, const TQString& folder, const TQString& key); + virtual TQMap readPasswordList(int handle, const TQString& folder, const TQString& key); + + // Rename an entry. rc=0 on success. + virtual int renameEntry(int handle, const TQString& folder, const TQString& oldName, const TQString& newName); + + // Write an entry. rc=0 on success. + virtual int writeEntry(int handle, const TQString& folder, const TQString& key, const TQByteArray& value, int entryType); + virtual int writeEntry(int handle, const TQString& folder, const TQString& key, const TQByteArray& value); + virtual int writeMap(int handle, const TQString& folder, const TQString& key, const TQByteArray& value); + virtual int writePassword(int handle, const TQString& folder, const TQString& key, const TQString& value); + + // Does the entry exist? + virtual bool hasEntry(int handle, const TQString& folder, const TQString& key); + + // What type is the entry? + virtual int entryType(int handle, const TQString& folder, const TQString& key); + + // Remove an entry. rc=0 on success. + virtual int removeEntry(int handle, const TQString& folder, const TQString& key); + + // Disconnect an app from a wallet + virtual bool disconnectApplication(const TQString& wallet, const TQCString& application); + + virtual void reconfigure(); + + // Determine + virtual bool folderDoesNotExist(const TQString& wallet, const TQString& folder); + virtual bool keyDoesNotExist(const TQString& wallet, const TQString& folder, const TQString& key); + + virtual void closeAllWallets(); + + virtual TQString networkWallet(); + + virtual TQString localWallet(); + + private slots: + void slotAppUnregistered(const TQCString& app); + void emitWalletListDirty(); + void timedOut(int); + void notifyFailures(); + void processTransactions(); + + private: + int internalOpen(const TQCString& appid, const TQString& wallet, bool isPath = false, WId w = 0, bool modal = false); + bool isAuthorizedApp(const TQCString& appid, const TQString& wallet, WId w); + // This also validates the handle. May return NULL. + KWallet::Backend* getWallet(const TQCString& appid, int handle); + // Generate a new unique handle. + int generateHandle(); + // Invalidate a handle (remove it from the TQMap) + void invalidateHandle(int handle); + // Emit signals about closing wallets + void doCloseSignals(int,const TQString&); + void emitFolderUpdated(const TQString&, const TQString&); + // Internal - close this wallet. + int closeWallet(KWallet::Backend *w, int handle, bool force); + // Implicitly allow access for this application + bool implicitAllow(const TQString& wallet, const TQCString& app); + bool implicitDeny(const TQString& wallet, const TQCString& app); + TQCString friendlyDCOPPeerName(); + + void doTransactionChangePassword(const TQCString& appid, const TQString& wallet, uint wId); + int doTransactionOpen(const TQCString& appid, const TQString& wallet, uint wId, bool modal); + + void setupDialog( TQWidget* dialog, WId wId, const TQCString& appid, bool modal ); + void checkActiveDialog(); + + TQIntDict _wallets; + TQMap > _handles; + TQMap _passwords; + KDirWatch *_dw; + int _failed; + + bool _leaveOpen, _closeIdle, _launchManager, _enabled; + bool _openPrompt, _firstUse, _showingFailureNotify; + int _idleTime; + TQMap _implicitAllowMap, _implicitDenyMap; + KTimeout *_timeouts; + TQTimer _tryOpenBlocked; + + TQPtrList _transactions; + TQGuardedPtr< TQWidget > activeDialog; +}; + + +#endif diff --git a/tdeio/misc/tdewalletd/tdewalletwizard.ui b/tdeio/misc/tdewalletd/tdewalletwizard.ui new file mode 100644 index 000000000..aa3a1c09d --- /dev/null +++ b/tdeio/misc/tdewalletd/tdewalletwizard.ui @@ -0,0 +1,545 @@ + +KWalletWizard + + + KWalletWizard + + + + 0 + 0 + 556 + 385 + + + + KDE Wallet Wizard + + + + page1 + + + Introduction + + + + unnamed + + + + spacer3 + + + Vertical + + + Expanding + + + + 21 + 21 + + + + + + textLabel1 + + + + 20 + + + + <u>KWallet</u> - The KDE Wallet System + + + RichText + + + WordBreak|AlignCenter + + + + + textLabel2 + + + + 5 + 5 + 0 + 2 + + + + 26 + + + Welcome to KWallet, the KDE Wallet System. KWallet allows you to store your passwords and other personal information on disk in an encrypted file, preventing others from viewing the information. This wizard will tell you about KWallet and help you configure it for the first time. + + + RichText + + + WordBreak|AlignVCenter + + + + + buttonGroup1 + + + NoFrame + + + + + + + unnamed + + + 0 + + + + _basic + + + &Basic setup (recommended) + + + true + + + + + _advanced + + + &Advanced setup + + + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 140 + 21 + + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 140 + 31 + + + + + + + + page4 + + + Information + + + + unnamed + + + + textLabel2_3 + + + The KDE Wallet system stores your data in a <i>wallet</i> file on your local hard disk. The data is only written in encrypted form, presently using the blowfish algorithm with your password as the key. When a wallet is opened, the wallet manager application will launch and display an icon in the system tray. You can use this application to manage your wallets. It even permits you to drag wallets and wallet contents, allowing you to easily copy a wallet to a remote system. + + + RichText + + + + + + + page2 + + + Password Selection + + + + unnamed + + + + textLabel3 + + + Various applications may attempt to use the KDE wallet to store passwords or other information such as web form data and cookies. If you would like these applications to use the wallet, you must enable it now and choose a password. The password you choose <i>cannot</i> be recovered if it is lost, and will allow anyone who knows it to obtain all the information contained in the wallet. + + + RichText + + + + + layout7 + + + + unnamed + + + + layout5 + + + + unnamed + + + + textLabel1_2 + + + false + + + Enter a new password: + + + AlignVCenter|AlignRight + + + _pass1 + + + + + textLabel2_2 + + + false + + + Verify password: + + + AlignVCenter|AlignRight + + + _pass2 + + + + + + + layout4 + + + + unnamed + + + + _pass1 + + + false + + + Password + + + + + _pass2 + + + false + + + Password + + + + + + + + + _useWallet + + + Yes, I wish to use the KDE wallet to store my personal information. + + + + + spacer5 + + + Vertical + + + Expanding + + + + 21 + 51 + + + + + + spacer6 + + + Horizontal + + + Expanding + + + + 101 + 21 + + + + + + spacer7 + + + Horizontal + + + Expanding + + + + 111 + 31 + + + + + + spacer4 + + + Vertical + + + Expanding + + + + 21 + 70 + + + + + + _matchLabel + + + + + + WordBreak|AlignVCenter|AlignRight + + + + + + + page3 + + + Security Level + + + + unnamed + + + + textLabel1_3 + + + The KDE Wallet system allows you to control the level of security of your personal data. Some of these settings do impact usability. While the default settings are generally acceptable for most users, you may wish to change some of them. You may further tune these settings from the KWallet control module. + + + RichText + + + WordBreak|AlignVCenter + + + + + spacer8 + + + Vertical + + + Expanding + + + + 21 + 121 + + + + + + _networkWallet + + + Store network passwords and local passwords in separate wallet files + + + + + _closeIdle + + + Automatically close idle wallets + + + + + spacer9 + + + Vertical + + + Expanding + + + + 21 + 51 + + + + + + + + + _useWallet + toggled(bool) + textLabel1_2 + setEnabled(bool) + + + _useWallet + toggled(bool) + textLabel2_2 + setEnabled(bool) + + + _useWallet + toggled(bool) + _pass1 + setEnabled(bool) + + + _useWallet + toggled(bool) + _pass2 + setEnabled(bool) + + + _useWallet + clicked() + _pass1 + setFocus() + + + _useWallet + clicked() + KWalletWizard + passwordPageUpdate() + + + _pass1 + textChanged(const TQString&) + KWalletWizard + passwordPageUpdate() + + + _pass2 + textChanged(const TQString&) + KWalletWizard + passwordPageUpdate() + + + _advanced + clicked() + KWalletWizard + setAdvanced() + + + _basic + clicked() + KWalletWizard + setBasic() + + + + _basic + _advanced + _useWallet + _pass1 + _pass2 + + + tqcheckbox.h + klocale.h + tdewalletwizard.ui.h + + + passwordPageUpdate() + init() + setAdvanced() + setBasic() + destroy() + + + diff --git a/tdeio/misc/tdewalletd/tdewalletwizard.ui.h b/tdeio/misc/tdewalletd/tdewalletwizard.ui.h new file mode 100644 index 000000000..a42635e9b --- /dev/null +++ b/tdeio/misc/tdewalletd/tdewalletwizard.ui.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you wish to add, delete or rename functions or slots use +** Qt Designer which will update this file, preserving your code. Create an +** init() function in place of a constructor, and a destroy() function in +** place of a destructor. +*****************************************************************************/ + +void KWalletWizard::passwordPageUpdate() +{ + bool fe = !_useWallet->isChecked() || _pass1->text() == _pass2->text(); + if (_basic->isChecked()) { + setFinishEnabled(page2, fe); + } else { + setNextEnabled(page2, fe); + setFinishEnabled(page3, fe); + } + + if (_useWallet->isChecked()) { + if (_pass1->text() == _pass2->text()) { + if (_pass1->text().isEmpty()) { + _matchLabel->setText(i18n("Password is empty. (WARNING: Insecure)")); + } else { + _matchLabel->setText(i18n("Passwords match.")); + } + } else { + _matchLabel->setText(i18n("Passwords do not match.")); + } + } else { + _matchLabel->setText(TQString::null); + } + +} + + +void KWalletWizard::init() +{ + setHelpEnabled(page1, false); + setHelpEnabled(page2, false); + setHelpEnabled(page3, false); + setHelpEnabled(page4, false); + setAppropriate(page3, false); + setAppropriate(page4, false); + setFinishEnabled(page2, true); +} + + +void KWalletWizard::setAdvanced() +{ + setAppropriate(page3, true); + setAppropriate(page4, true); + bool fe = !_useWallet->isChecked() || _pass1->text() == _pass2->text(); + setFinishEnabled(page2, false); + setNextEnabled(page2, fe); + setFinishEnabled(page3, fe); +} + + +void KWalletWizard::setBasic() +{ + setAppropriate(page3, false); + setAppropriate(page4, false); + bool fe = !_useWallet->isChecked() || _pass1->text() == _pass2->text(); + setFinishEnabled(page3, false); + setFinishEnabled(page2, fe); +} + + +void KWalletWizard::destroy() +{ + _pass1->clear(); + _pass2->clear(); +} diff --git a/tdeio/misc/telnet.protocol b/tdeio/misc/telnet.protocol new file mode 100644 index 000000000..062fb1d4f --- /dev/null +++ b/tdeio/misc/telnet.protocol @@ -0,0 +1,13 @@ +[Protocol] +exec=tdetelnetservice %u +protocol=telnet +input=none +output=none +helper=true +listing= +reading=false +writing=false +makedir=false +deleting=false +DocPath=tdeioslave/telnet.html +Icon=konsole diff --git a/tdeio/misc/uiserver.cpp b/tdeio/misc/uiserver.cpp new file mode 100644 index 000000000..6ba92a6a2 --- /dev/null +++ b/tdeio/misc/uiserver.cpp @@ -0,0 +1,1413 @@ +/* This file is part of the KDE libraries + Copyright (C) 2000 Matej Koss + David Faure + 2001 George Staikos + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +// -*- mode: c++; c-basic-offset: 4 -*- + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "observer_stub.h" +#include "observer.h" // for static methods only +#include "tdeio/defaultprogress.h" +#include "tdeio/jobclasses.h" +#include "uiserver.h" +#include "passdlg.h" +#include "tdeio/renamedlg.h" +#include "tdeio/skipdlg.h" +#include "slavebase.h" // for QuestionYesNo etc. +#include +#include +#include +#include + + +// pointer for main instance of UIServer +UIServer* uiserver; + +// ToolBar field IDs +enum { TOOL_CANCEL, TOOL_CONFIGURE }; + +// StatusBar field IDs +enum { ID_TOTAL_FILES = 1, ID_TOTAL_SIZE, ID_TOTAL_TIME, ID_TOTAL_SPEED }; + +//static +int UIServer::s_jobId = 0; + +static const int defaultColumnWidth[] = { 70, // SIZE_OPERATION + 160, // LOCAL_FILENAME + 40, // RESUME + 60, // COUNT + 30, // PROGRESS + 65, // TOTAL + 70, // SPEED + 70, // REMAINING_TIME + 450 // URL +}; + +class UIServerSystemTray:public KSystemTray +{ + public: + UIServerSystemTray(UIServer* uis) + :KSystemTray(uis) + { + KPopupMenu* pop= contextMenu(); + pop->insertItem(i18n("Settings..."), uis, TQT_SLOT(slotConfigure())); + pop->insertItem(i18n("Remove"), uis, TQT_SLOT(slotRemoveSystemTrayIcon())); + setPixmap(loadIcon("filesave")); + //actionCollection()->action("file_quit")->setEnabled(true); + KStdAction::quit(TQT_TQOBJECT(uis), TQT_SLOT(slotQuit()), actionCollection()); + } +}; + +class ProgressConfigDialog:public KDialogBase +{ + public: + ProgressConfigDialog(TQWidget* parent); + ~ProgressConfigDialog() {} + void setChecked(int i, bool on); + bool isChecked(int i) const; + friend class UIServer; + private: + TQCheckBox *m_showSystemTrayCb; + TQCheckBox *m_keepOpenCb; + TQCheckBox *m_toolBarCb; + TQCheckBox *m_statusBarCb; + TQCheckBox *m_headerCb; + TQCheckBox *m_fixedWidthCb; + KListView *m_columns; + TQCheckListItem *(m_items[ListProgress::TB_MAX]); +}; + +ProgressConfigDialog::ProgressConfigDialog(TQWidget *parent) +:KDialogBase(KDialogBase::Plain,i18n("Configure Network Operation Window"),KDialogBase::Ok|KDialogBase::Apply|KDialogBase::Cancel, + KDialogBase::Ok, parent, "configprog", false) +{ + TQVBoxLayout *layout=new TQVBoxLayout(plainPage(),spacingHint()); + m_showSystemTrayCb=new TQCheckBox(i18n("Show system tray icon"), plainPage()); + m_keepOpenCb=new TQCheckBox(i18n("Keep network operation window always open"), plainPage()); + m_headerCb=new TQCheckBox(i18n("Show column headers"), plainPage()); + m_toolBarCb=new TQCheckBox(i18n("Show toolbar"), plainPage()); + m_statusBarCb=new TQCheckBox(i18n("Show statusbar"), plainPage()); + m_fixedWidthCb=new TQCheckBox(i18n("Column widths are user adjustable"), plainPage()); + TQLabel *label=new TQLabel(i18n("Show information:"), plainPage()); + m_columns=new KListView(plainPage()); + + m_columns->addColumn("info"); + m_columns->setSorting(-1); + m_columns->header()->hide(); + + m_items[ListProgress::TB_ADDRESS] =new TQCheckListItem(m_columns, i18n("URL"), TQCheckListItem::CheckBox); + m_items[ListProgress::TB_REMAINING_TIME] =new TQCheckListItem(m_columns, i18n("Remaining Time", "Rem. Time"), TQCheckListItem::CheckBox); + m_items[ListProgress::TB_SPEED] =new TQCheckListItem(m_columns, i18n("Speed"), TQCheckListItem::CheckBox); + m_items[ListProgress::TB_TOTAL] =new TQCheckListItem(m_columns, i18n("Size"), TQCheckListItem::CheckBox); + m_items[ListProgress::TB_PROGRESS] =new TQCheckListItem(m_columns, i18n("%"), TQCheckListItem::CheckBox); + m_items[ListProgress::TB_COUNT] =new TQCheckListItem(m_columns, i18n("Count"), TQCheckListItem::CheckBox); + m_items[ListProgress::TB_RESUME] =new TQCheckListItem(m_columns, i18n("Resume", "Res."), TQCheckListItem::CheckBox); + m_items[ListProgress::TB_LOCAL_FILENAME] =new TQCheckListItem(m_columns, i18n("Local Filename"), TQCheckListItem::CheckBox); + m_items[ListProgress::TB_OPERATION] =new TQCheckListItem(m_columns, i18n("Operation"), TQCheckListItem::CheckBox); + + layout->addWidget(m_showSystemTrayCb); + layout->addWidget(m_keepOpenCb); + layout->addWidget(m_headerCb); + layout->addWidget(m_toolBarCb); + layout->addWidget(m_statusBarCb); + layout->addWidget(m_fixedWidthCb); + layout->addWidget(label); + layout->addWidget(m_columns); +} + +void ProgressConfigDialog::setChecked(int i, bool on) +{ + if (i>=ListProgress::TB_MAX) + return; + m_items[i]->setOn(on); +} + +bool ProgressConfigDialog::isChecked(int i) const +{ + if (i>=ListProgress::TB_MAX) + return false; + return m_items[i]->isOn(); +} + +ProgressItem::ProgressItem( ListProgress* view, TQListViewItem *after, TQCString app_id, int job_id, + bool showDefault ) + : TQListViewItem( view, after ) { + + listProgress = view; + + m_iTotalSize = 0; + m_iTotalFiles = 0; + m_iProcessedSize = 0; + m_iProcessedFiles = 0; + m_iSpeed = 0; + + m_sAppId = app_id; + m_iJobId = job_id; + m_visible = true; + m_defaultProgressVisible = showDefault; + + // create dialog, but don't show it + defaultProgress = new TDEIO::DefaultProgress( false ); + defaultProgress->setOnlyClean( true ); + connect ( defaultProgress, TQT_SIGNAL( stopped() ), this, TQT_SLOT( slotCanceled() ) ); + connect ( &m_showTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT(slotShowDefaultProgress()) ); + + if ( showDefault ) { + m_showTimer.start( 500, true ); + } +} + +bool ProgressItem::keepOpen() const +{ + return defaultProgress->keepOpen(); +} + +void ProgressItem::finished() +{ + defaultProgress->finished(); +} + +ProgressItem::~ProgressItem() { + delete defaultProgress; +} + + +void ProgressItem::setTotalSize( TDEIO::filesize_t size ) { + m_iTotalSize = size; + + // It's already in the % column... + //setText( listProgress->lv_total, TDEIO::convertSize( m_iTotalSize ) ); + + defaultProgress->slotTotalSize( 0, m_iTotalSize ); +} + + +void ProgressItem::setTotalFiles( unsigned long files ) { + m_iTotalFiles = files; + + defaultProgress->slotTotalFiles( 0, m_iTotalFiles ); +} + + +void ProgressItem::setTotalDirs( unsigned long dirs ) { + defaultProgress->slotTotalDirs( 0, dirs ); +} + + +void ProgressItem::setProcessedSize( TDEIO::filesize_t size ) { + m_iProcessedSize = size; + + setText( ListProgress::TB_TOTAL, TDEIO::convertSize( size ) ); + + defaultProgress->slotProcessedSize( 0, size ); +} + + +void ProgressItem::setProcessedFiles( unsigned long files ) { + m_iProcessedFiles = files; + + TQString tmps = i18n("%1 / %2").arg( m_iProcessedFiles ).arg( m_iTotalFiles ); + setText( ListProgress::TB_COUNT, tmps ); + + defaultProgress->slotProcessedFiles( 0, m_iProcessedFiles ); +} + + +void ProgressItem::setProcessedDirs( unsigned long dirs ) { + defaultProgress->slotProcessedDirs( 0, dirs ); +} + + +void ProgressItem::setPercent( unsigned long percent ) { + const TQString tmps = TDEIO::DefaultProgress::makePercentString( percent, m_iTotalSize, m_iTotalFiles ); + setText( ListProgress::TB_PROGRESS, tmps ); + + defaultProgress->slotPercent( 0, percent ); +} + +void ProgressItem::setInfoMessage( const TQString & msg ) { + TQString plainTextMsg(msg); + plainTextMsg.replace( TQRegExp( "" ), TQString() ); + plainTextMsg.replace( TQRegExp( "" ), TQString() ); + setText( ListProgress::TB_PROGRESS, plainTextMsg ); + + defaultProgress->slotInfoMessage( 0, msg ); +} + +void ProgressItem::setSpeed( unsigned long bytes_per_second ) { + m_iSpeed = bytes_per_second; + m_remainingSeconds = TDEIO::calculateRemainingSeconds( m_iTotalSize, m_iProcessedSize, m_iSpeed ); + + TQString tmps, tmps2; + if ( m_iSpeed == 0 ) { + tmps = i18n( "Stalled"); + tmps2 = tmps; + } else { + tmps = i18n( "%1/s").arg( TDEIO::convertSize( m_iSpeed )); + tmps2 = TDEIO::convertSeconds( m_remainingSeconds ); + } + setText( ListProgress::TB_SPEED, tmps ); + setText( ListProgress::TB_REMAINING_TIME, tmps2 ); + + defaultProgress->slotSpeed( 0, m_iSpeed ); +} + + +void ProgressItem::setCopying( const KURL& from, const KURL& to ) { + setText( ListProgress::TB_OPERATION, i18n("Copying") ); + setText( ListProgress::TB_ADDRESS, from.url() ); + setText( ListProgress::TB_LOCAL_FILENAME, to.fileName() ); + + defaultProgress->slotCopying( 0, from, to ); +} + + +void ProgressItem::setMoving( const KURL& from, const KURL& to ) { + setText( ListProgress::TB_OPERATION, i18n("Moving") ); + setText( ListProgress::TB_ADDRESS, from.url() ); + setText( ListProgress::TB_LOCAL_FILENAME, to.fileName() ); + + defaultProgress->slotMoving( 0, from, to ); +} + + +void ProgressItem::setCreatingDir( const KURL& dir ) { + setText( ListProgress::TB_OPERATION, i18n("Creating") ); + setText( ListProgress::TB_ADDRESS, dir.url() ); + setText( ListProgress::TB_LOCAL_FILENAME, dir.fileName() ); + + defaultProgress->slotCreatingDir( 0, dir ); +} + + +void ProgressItem::setDeleting( const KURL& url ) { + setText( ListProgress::TB_OPERATION, i18n("Deleting") ); + setText( ListProgress::TB_ADDRESS, url.url() ); + setText( ListProgress::TB_LOCAL_FILENAME, url.fileName() ); + + defaultProgress->slotDeleting( 0, url ); +} + +void ProgressItem::setTransferring( const KURL& url ) { + setText( ListProgress::TB_OPERATION, i18n("Loading") ); + setText( ListProgress::TB_ADDRESS, url.url() ); + setText( ListProgress::TB_LOCAL_FILENAME, url.fileName() ); + + defaultProgress->slotTransferring( 0, url ); +} + +void ProgressItem::setText(ListProgress::ListProgressFields field, const TQString& text) +{ + if (listProgress->m_lpcc[field].enabled) + { + TQString t=text; + if ((field==ListProgress::TB_ADDRESS) && (listProgress->m_fixedColumnWidths)) +// if (((field==ListProgress::TB_LOCAL_FILENAME) || (field==ListProgress::TB_ADDRESS)) && (listProgress->m_fixedColumnWidths)) + { + m_fullLengthAddress=text; + listProgress->m_squeezer->resize(listProgress->columnWidth(listProgress->m_lpcc[field].index),50); + listProgress->m_squeezer->setText(t); + t=listProgress->m_squeezer->text(); + } + TQListViewItem::setText(listProgress->m_lpcc[field].index,t); + } +} + +void ProgressItem::setStating( const KURL& url ) { + setText( ListProgress::TB_OPERATION, i18n("Examining") ); + setText( ListProgress::TB_ADDRESS, url.url() ); + setText( ListProgress::TB_LOCAL_FILENAME, url.fileName() ); + + defaultProgress->slotStating( 0, url ); +} + +void ProgressItem::setMounting( const TQString& dev, const TQString & point ) { + setText( ListProgress::TB_OPERATION, i18n("Mounting") ); + setText( ListProgress::TB_ADDRESS, point ); // ? + setText( ListProgress::TB_LOCAL_FILENAME, dev ); // ? + + defaultProgress->slotMounting( 0, dev, point ); +} + +void ProgressItem::setUnmounting( const TQString & point ) { + setText( ListProgress::TB_OPERATION, i18n("Unmounting") ); + setText( ListProgress::TB_ADDRESS, point ); // ? + setText( ListProgress::TB_LOCAL_FILENAME, "" ); // ? + + defaultProgress->slotUnmounting( 0, point ); +} + +void ProgressItem::setCanResume( TDEIO::filesize_t offset ) { + /* + TQString tmps; + // set canResume + if ( _resume ) { + tmps = i18n("Yes"); + } else { + tmps = i18n("No"); + } + setText( listProgress->lv_resume, tmps ); + */ + defaultProgress->slotCanResume( 0, offset ); +} + + +void ProgressItem::slotCanceled() { + emit jobCanceled( this ); +} + +// Called 0.5s after the job has been started +void ProgressItem::slotShowDefaultProgress() { + if (defaultProgress) + { + if ( m_visible && m_defaultProgressVisible ) + defaultProgress->show(); + else + defaultProgress->hide(); + } +} + +void ProgressItem::slotToggleDefaultProgress() { + setDefaultProgressVisible( !m_defaultProgressVisible ); +} + +// Called when a rename or skip dialog pops up +// We want to prevent someone from killing the job in the uiserver then +void ProgressItem::setVisible( bool visible ) { + if ( m_visible != visible ) + { + m_visible = visible; + updateVisibility(); + } +} + +// Can be toggled by the user +void ProgressItem::setDefaultProgressVisible( bool visible ) { + if ( m_defaultProgressVisible != visible ) + { + m_defaultProgressVisible = visible; + updateVisibility(); + } +} + +// Update according to state +void ProgressItem::updateVisibility() +{ + if (defaultProgress) + { + if ( m_visible && m_defaultProgressVisible ) + { + m_showTimer.start(250, true); // Show delayed + } + else + { + m_showTimer.stop(); + defaultProgress->hide(); + } + } +} + + +//----------------------------------------------------------------------------- +ListProgress::ListProgress (TQWidget *parent, const char *name) +: KListView (parent, name) +{ + + // enable selection of more than one item + setMultiSelection( true ); + + setAllColumnsShowFocus( true ); + + m_lpcc[TB_OPERATION].title=i18n("Operation"); + m_lpcc[TB_LOCAL_FILENAME].title=i18n("Local Filename"); + m_lpcc[TB_RESUME].title=i18n("Resume", "Res."); + m_lpcc[TB_COUNT].title=i18n("Count"); + m_lpcc[TB_PROGRESS].title=i18n("%"); + m_lpcc[TB_TOTAL].title=i18n("Size"); + m_lpcc[TB_SPEED].title=i18n("Speed"); + m_lpcc[TB_REMAINING_TIME].title=i18n("Remaining Time", "Rem. Time"); + m_lpcc[TB_ADDRESS].title=i18n("URL"); + readSettings(); + + applySettings(); + + //used for squeezing the text in local file name and url + m_squeezer=new KSqueezedTextLabel(this); + m_squeezer->hide(); + connect(header(),TQT_SIGNAL(sizeChange(int,int,int)),this,TQT_SLOT(columnWidthChanged(int))); +} + + +ListProgress::~ListProgress() { +} + +void ListProgress::applySettings() +{ + int iEnabledCols=0; + + // Update listcolumns to show + for (int i=0; i columns() ) + m_lpcc[i].index=addColumn(m_lpcc[i].title, m_fixedColumnWidths?m_lpcc[i].width:-1); + else + { + m_lpcc[i].index = iEnabledCols - 1; + setColumnText(m_lpcc[i].index, m_lpcc[i].title); + } + + setColumnWidth(m_lpcc[i].index, m_lpcc[i].width); //yes, this is required here, alexxx + if (m_fixedColumnWidths) + setColumnWidthMode(m_lpcc[i].index, Manual); + } + + // Remove unused columns. However we must keep one column left + // Otherwise the listview will be emptied + while( iEnabledCols < columns() && columns() > 1 ) + removeColumn( columns() - 1 ); + + if ( columns() == 0 ) + addColumn( "" ); + + if ( !m_showHeader || iEnabledCols == 0 ) + header()->hide(); + else + header()->show(); +} + +void ListProgress::readSettings() { + TDEConfig config("uiserverrc"); + + // read listview geometry properties + config.setGroup( "ProgressList" ); + for ( int i = 0; i < TB_MAX; i++ ) { + TQString tmps="Col"+TQString::number(i); + m_lpcc[i].width=config.readNumEntry( tmps, 0); + if (m_lpcc[i].width==0) m_lpcc[i].width=defaultColumnWidth[i]; + + tmps="Enabled"+TQString::number(i); + m_lpcc[i].enabled=config.readBoolEntry(tmps,true); + } + m_showHeader=config.readBoolEntry("ShowListHeader",true); + m_fixedColumnWidths=config.readBoolEntry("FixedColumnWidths",false); + + m_lpcc[TB_RESUME].enabled=false; +} + +void ListProgress::columnWidthChanged(int column) +{ + //resqueeze if necessary + if ((m_lpcc[TB_ADDRESS].enabled) && (column==m_lpcc[TB_ADDRESS].index)) + { + for (TQListViewItem* lvi=firstChild(); lvi!=0; lvi=lvi->nextSibling()) + { + ProgressItem *pi=(ProgressItem*)lvi; + pi->setText(TB_ADDRESS,pi->fullLengthAddress()); + } + } + writeSettings(); +} + +void ListProgress::writeSettings() { + TDEConfig config("uiserverrc"); + + // write listview geometry properties + config.setGroup( "ProgressList" ); + for ( int i = 0; i < TB_MAX; i++ ) { + if (!m_lpcc[i].enabled) { + TQString tmps= "Enabled" + TQString::number(i); + config.writeEntry( tmps, false ); + continue; + } + m_lpcc[i].width=columnWidth(m_lpcc[i].index); + TQString tmps="Col"+TQString::number(i); + config.writeEntry( tmps, m_lpcc[i].width); + } + config.writeEntry("ShowListHeader", m_showHeader); + config.writeEntry("FixedColumnWidths", m_fixedColumnWidths); + config.sync(); +} + + +//------------------------------------------------------------ + + +UIServer::UIServer() +:KMainWindow(0, "") +,DCOPObject("UIServer") +,m_shuttingDown(false) +,m_configDialog(0) +,m_contextMenu(0) +,m_systemTray(0) +{ + + readSettings(); + + // setup toolbar + toolBar()->insertButton("editdelete", TOOL_CANCEL, + TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), + TQT_SLOT(slotCancelCurrent()), FALSE, i18n("Cancel")); + toolBar()->insertButton("configure", TOOL_CONFIGURE, + TQT_SIGNAL(clicked()), TQT_TQOBJECT(this), + TQT_SLOT(slotConfigure()), true, i18n("Settings...")); + + toolBar()->setBarPos( KToolBar::Left ); + + // setup statusbar + statusBar()->insertItem( i18n(" Files: %1 ").arg( 0 ), ID_TOTAL_FILES); + statusBar()->insertItem( i18n("Remaining Size", " Rem. Size: %1 kB ").arg( "0" ), ID_TOTAL_SIZE); + statusBar()->insertItem( i18n("Remaining Time", " Rem. Time: 00:00:00 "), ID_TOTAL_TIME); + statusBar()->insertItem( i18n(" %1 kB/s ").arg("0"), ID_TOTAL_SPEED); + + // setup listview + listProgress = new ListProgress( this, "progresslist" ); + + setCentralWidget( listProgress ); + + connect( listProgress, TQT_SIGNAL( selectionChanged() ), + TQT_SLOT( slotSelection() ) ); + connect( listProgress, TQT_SIGNAL( executed( TQListViewItem* ) ), + TQT_SLOT( slotToggleDefaultProgress( TQListViewItem* ) ) ); + connect( listProgress, TQT_SIGNAL( contextMenu( KListView*, TQListViewItem *, const TQPoint &)), + TQT_SLOT(slotShowContextMenu(KListView*, TQListViewItem *, const TQPoint&))); + + + // setup animation timer + updateTimer = new TQTimer( this ); + connect( updateTimer, TQT_SIGNAL( timeout() ), + TQT_SLOT( slotUpdate() ) ); + m_bUpdateNewJob=false; + + setCaption(i18n("Progress Dialog")); + setMinimumSize( 150, 50 ); + resize( m_initWidth, m_initHeight); + + applySettings(); + +/* if ((m_bShowList) && (m_keepListOpen)) + { + cerr<<"show() !"<stop(); +} + +void UIServer::applySettings() +{ + if ((m_showSystemTray) && (m_systemTray==0)) + { + m_systemTray=new UIServerSystemTray(this); + m_systemTray->show(); + } + else if ((m_showSystemTray==false) && (m_systemTray!=0)) + { + delete m_systemTray; + m_systemTray=0; + } + + if (m_showStatusBar==false) + statusBar()->hide(); + else + statusBar()->show(); + if (m_showToolBar==false) + toolBar()->hide(); + else + toolBar()->show(); +} + +void UIServer::slotShowContextMenu(KListView*, TQListViewItem* item, const TQPoint& pos) +{ + if (m_contextMenu==0) + { + m_contextMenu=new TQPopupMenu(this); + m_idCancelItem = m_contextMenu->insertItem(i18n("Cancel Job"), this, TQT_SLOT(slotCancelCurrent())); +// m_contextMenu->insertItem(i18n("Toggle Progress"), this, TQT_SLOT(slotToggleDefaultProgress())); + m_contextMenu->insertSeparator(); + m_contextMenu->insertItem(i18n("Settings..."), this, TQT_SLOT(slotConfigure())); + } + if ( item ) + item->setSelected( true ); + bool enabled = false; + TQListViewItemIterator it( listProgress ); + for ( ; it.current(); ++it ) { + if ( it.current()->isSelected() ) { + enabled = true; + break; + } + } + m_contextMenu->setItemEnabled( m_idCancelItem, enabled); + + m_contextMenu->popup(pos); +} + +void UIServer::slotRemoveSystemTrayIcon() +{ + m_showSystemTray=false; + applySettings(); + writeSettings(); +} + +void UIServer::slotConfigure() +{ + if (m_configDialog==0) + { + m_configDialog=new ProgressConfigDialog(0); +// connect(m_configDialog,TQT_SIGNAL(cancelClicked()), this, TQT_SLOT(slotCancelConfig())); + connect(m_configDialog,TQT_SIGNAL(okClicked()), this, TQT_SLOT(slotApplyConfig())); + connect(m_configDialog,TQT_SIGNAL(applyClicked()), this, TQT_SLOT(slotApplyConfig())); + } + m_configDialog->m_showSystemTrayCb->setChecked(m_showSystemTray); + m_configDialog->m_keepOpenCb->setChecked(m_keepListOpen); + m_configDialog->m_toolBarCb->setChecked(m_showToolBar); + m_configDialog->m_statusBarCb->setChecked(m_showStatusBar); + m_configDialog->m_headerCb->setChecked(listProgress->m_showHeader); + m_configDialog->m_fixedWidthCb->setChecked(listProgress->m_fixedColumnWidths); + for (int i=0; isetChecked(i, listProgress->m_lpcc[i].enabled); + } + m_configDialog->show(); +} + +void UIServer::slotApplyConfig() +{ + m_showSystemTray=m_configDialog->m_showSystemTrayCb->isChecked(); + m_keepListOpen=m_configDialog->m_keepOpenCb->isChecked(); + m_showToolBar=m_configDialog->m_toolBarCb->isChecked(); + m_showStatusBar=m_configDialog->m_statusBarCb->isChecked(); + listProgress->m_showHeader=m_configDialog->m_headerCb->isChecked(); + listProgress->m_fixedColumnWidths=m_configDialog->m_fixedWidthCb->isChecked(); + for (int i=0; im_lpcc[i].enabled=m_configDialog->isChecked(i); + + + applySettings(); + listProgress->applySettings(); + writeSettings(); + listProgress->writeSettings(); +} + +int UIServer::newJob( TQCString observerAppId, bool showProgress ) +{ + kdDebug(7024) << "UIServer::newJob observerAppId=" << observerAppId << ". " + << "Giving id=" << s_jobId+1 << endl; + + TQListViewItemIterator it( listProgress ); + for ( ; it.current(); ++it ) { + if ( it.current()->itemBelow() == 0L ) { // this will find the end of list + break; + } + } + + // increment counter + s_jobId++; + + bool show = !m_bShowList && showProgress; + + ProgressItem *item = new ProgressItem( listProgress, it.current(), observerAppId, s_jobId, show ); + connect( item, TQT_SIGNAL( jobCanceled( ProgressItem* ) ), + TQT_SLOT( slotJobCanceled( ProgressItem* ) ) ); + + if ( m_bShowList && !updateTimer->isActive() ) + updateTimer->start( 1000 ); + + m_bUpdateNewJob=true; + + return s_jobId; +} + + +ProgressItem* UIServer::findItem( int id ) +{ + TQListViewItemIterator it( listProgress ); + + ProgressItem *item; + + for ( ; it.current(); ++it ) { + item = (ProgressItem*) it.current(); + if ( item->jobId() == id ) { + return item; + } + } + + return 0L; +} + + +void UIServer::setItemVisible( ProgressItem * item, bool visible ) +{ + item->setVisible( visible ); + // Check if we were the last one to be visible + // or the first one -> hide/show the list in that case + // (Note that the user could have hidden the listview by hand yet, no time) + if ( m_bShowList ) { + m_bUpdateNewJob = true; + slotUpdate(); + } +} + +// Called by Observer when opening a skip or rename dialog +void UIServer::setJobVisible( int id, bool visible ) +{ + kdDebug(7024) << "UIServer::setJobVisible id=" << id << " visible=" << visible << endl; + ProgressItem *item = findItem( id ); + Q_ASSERT( item ); + if ( item ) + setItemVisible( item, visible ); +} + +void UIServer::jobFinished( int id ) +{ + kdDebug(7024) << "UIServer::jobFinished id=" << id << endl; + ProgressItem *item = findItem( id ); + + // remove item from the list and delete the corresponding defaultprogress + if ( item ) { + if ( item->keepOpen() ) + item->finished(); + else + delete item; + } +} + + +void UIServer::totalSize( int id, unsigned long size ) +{ totalSize64(id, size); } + +void UIServer::totalSize64( int id, TDEIO::filesize_t size ) +{ +// kdDebug(7024) << "UIServer::totalSize " << id << " " << TDEIO::number(size) << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setTotalSize( size ); + } +} + +void UIServer::totalFiles( int id, unsigned long files ) +{ + kdDebug(7024) << "UIServer::totalFiles " << id << " " << (unsigned int) files << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setTotalFiles( files ); + } +} + +void UIServer::totalDirs( int id, unsigned long dirs ) +{ + kdDebug(7024) << "UIServer::totalDirs " << id << " " << (unsigned int) dirs << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setTotalDirs( dirs ); + } +} + +void UIServer::processedSize( int id, unsigned long size ) +{ processedSize64(id, size); } + +void UIServer::processedSize64( int id, TDEIO::filesize_t size ) +{ + //kdDebug(7024) << "UIServer::processedSize " << id << " " << TDEIO::number(size) << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setProcessedSize( size ); + } +} + +void UIServer::processedFiles( int id, unsigned long files ) +{ + //kdDebug(7024) << "UIServer::processedFiles " << id << " " << (unsigned int) files << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setProcessedFiles( files ); + } +} + +void UIServer::processedDirs( int id, unsigned long dirs ) +{ + kdDebug(7024) << "UIServer::processedDirs " << id << " " << (unsigned int) dirs << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setProcessedDirs( dirs ); + } +} + +void UIServer::percent( int id, unsigned long ipercent ) +{ + //kdDebug(7024) << "UIServer::percent " << id << " " << (unsigned int) ipercent << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setPercent( ipercent ); + } +} + +void UIServer::speed( int id, unsigned long bytes_per_second ) +{ + //kdDebug(7024) << "UIServer::speed " << id << " " << (unsigned int) bytes_per_second << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setSpeed( bytes_per_second ); + } +} + +void UIServer::infoMessage( int id, const TQString & msg ) +{ + //kdDebug(7024) << "UIServer::infoMessage " << id << " " << msg << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setInfoMessage( msg ); + } +} + +void UIServer::canResume( int id, unsigned long offset ) +{ canResume64(id, offset); } + +void UIServer::canResume64( int id, TDEIO::filesize_t offset ) +{ + //kdDebug(7024) << "UIServer::canResume " << id << " " << offset << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setCanResume( offset ); + } +} + +void UIServer::copying( int id, KURL from, KURL to ) +{ + //kdDebug(7024) << "UIServer::copying " << id << " " << from.url() << " " << to.url() << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setCopying( from, to ); + } +} + +void UIServer::moving( int id, KURL from, KURL to ) +{ + //kdDebug(7024) << "UIServer::moving " << id << " " << from.url() << " " << to.url() << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setMoving( from, to ); + } +} + +void UIServer::deleting( int id, KURL url ) +{ + //kdDebug(7024) << "UIServer::deleting " << id << " " << url.url() << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setDeleting( url ); + } +} + +void UIServer::transferring( int id, KURL url ) +{ + //kdDebug(7024) << "UIServer::transferring " << id << " " << url.url() << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setTransferring( url ); + } +} + +void UIServer::creatingDir( int id, KURL dir ) +{ + kdDebug(7024) << "UIServer::creatingDir " << id << " " << dir.url() << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setCreatingDir( dir ); + } +} + +void UIServer::stating( int id, KURL url ) +{ + kdDebug(7024) << "UIServer::stating " << id << " " << url.url() << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setStating( url ); + } +} + +void UIServer::mounting( int id, TQString dev, TQString point ) +{ + kdDebug(7024) << "UIServer::mounting " << id << " " << dev << " " << point << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setMounting( dev, point ); + } +} + +void UIServer::unmounting( int id, TQString point ) +{ + kdDebug(7024) << "UIServer::unmounting " << id << " " << point << endl; + + ProgressItem *item = findItem( id ); + if ( item ) { + item->setUnmounting( point ); + } +} + +void UIServer::killJob( TQCString observerAppId, int progressId ) +{ + // Contact the object "TDEIO::Observer" in the application + Observer_stub observer( observerAppId, "TDEIO::Observer" ); + // Tell it to kill the job + observer.killJob( progressId ); +} + +void UIServer::slotJobCanceled( ProgressItem *item ) { + kdDebug(7024) << "UIServer::slotJobCanceled appid=" << item->appId() << " jobid=" << item->jobId() << endl; + // kill the corresponding job + killJob( item->appId(), item->jobId() ); + + // TDEIO::Job, when killed, should call back jobFinished(), but we can't + // really rely on that - the app may have crashed + delete item; +} + + +void UIServer::slotQuit() +{ + m_shuttingDown = true; + kapp->quit(); +} + +void UIServer::slotUpdate() { + // don't do anything if we don't have any inserted progress item + // or if they're all hidden + TQListViewItemIterator lvit( listProgress ); + bool visible = false; + for ( ; lvit.current(); ++lvit ) + if ( ((ProgressItem*)lvit.current())->isVisible() ) { + visible = true; + break; + } + + if ( !visible || !m_bShowList ) { + if (!m_keepListOpen) hide(); + updateTimer->stop(); + return; + } + + // Calling show() is conditional, so that users can close the window + // and it only pops up back when a new job is started + if (m_bUpdateNewJob) + { + m_bUpdateNewJob=false; + show(); + + // Make sure we'll be called back + if ( m_bShowList && !updateTimer->isActive() ) + updateTimer->start( 1000 ); + } + + int iTotalFiles = 0; + TDEIO::filesize_t iTotalSize = 0; + int iTotalSpeed = 0; + unsigned int totalRemTime = 0; // in seconds + + ProgressItem *item; + + // count totals for statusbar + TQListViewItemIterator it( listProgress ); + + for ( ; it.current(); ++it ) { + item = (ProgressItem*) it.current(); + if ( item->totalSize() != 0 ) { + iTotalSize += ( item->totalSize() - item->processedSize() ); + } + iTotalFiles += ( item->totalFiles() - item->processedFiles() ); + iTotalSpeed += item->speed(); + + if ( item->remainingSeconds() > totalRemTime ) { + totalRemTime = item->remainingSeconds(); + } + } + + // update statusbar + statusBar()->changeItem( i18n( " Files: %1 ").arg( iTotalFiles ), ID_TOTAL_FILES); + statusBar()->changeItem( i18n( "Remaining Size", " Rem. Size: %1 ").arg( TDEIO::convertSize( iTotalSize ) ), + ID_TOTAL_SIZE); + statusBar()->changeItem( i18n( "Remaining Time", " Rem. Time: %1 ").arg( TDEIO::convertSeconds( totalRemTime ) ), + ID_TOTAL_TIME); + statusBar()->changeItem( i18n( " %1/s ").arg( TDEIO::convertSize( iTotalSpeed ) ), + ID_TOTAL_SPEED); + +} + +void UIServer::setListMode( bool list ) +{ + m_bShowList = list; + TQListViewItemIterator it( listProgress ); + for ( ; it.current(); ++it ) { + // When going to list mode -> hide all progress dialogs + // When going back to separate dialogs -> show them all + ((ProgressItem*) it.current())->setDefaultProgressVisible( !list ); + } + + if (m_bShowList) + { + show(); + updateTimer->start( 1000 ); + } + else + { + hide(); + updateTimer->stop(); + } +} + +void UIServer::slotToggleDefaultProgress( TQListViewItem *item ) { + ((ProgressItem*) item )->slotToggleDefaultProgress(); +} + + +void UIServer::slotSelection() { + TQListViewItemIterator it( listProgress ); + + for ( ; it.current(); ++it ) { + if ( it.current()->isSelected() ) { + toolBar()->setItemEnabled( TOOL_CANCEL, TRUE); + return; + } + } + toolBar()->setItemEnabled( TOOL_CANCEL, FALSE); +} + +// This code is deprecated, slaves go to Observer::openPassDlg now, +// but this is kept for compat (DCOP calls to tdeio_uiserver). +TQByteArray UIServer::openPassDlg( const TDEIO::AuthInfo &info ) +{ + kdDebug(7024) << "UIServer::openPassDlg: User= " << info.username + << ", Msg= " << info.prompt << endl; + TDEIO::AuthInfo inf(info); + int result = TDEIO::PasswordDialog::getNameAndPassword( inf.username, inf.password, + &inf.keepPassword, inf.prompt, + inf.readOnly, inf.caption, + inf.comment, inf.commentLabel ); + TQByteArray data; + TQDataStream stream( data, IO_WriteOnly ); + if ( result == TQDialog::Accepted ) + inf.setModified( true ); + else + inf.setModified( false ); + stream << inf; + return data; +} + +int UIServer::messageBox( int progressId, int type, const TQString &text, const TQString &caption, const TQString &buttonYes, const TQString &buttonNo ) +{ + return Observer::messageBox( progressId, type, text, caption, buttonYes, buttonNo ); +} + +void UIServer::showSSLInfoDialog(const TQString &url, const TDEIO::MetaData &meta) +{ + return showSSLInfoDialog(url,meta,0); +} + +void UIServer::showSSLInfoDialog(const TQString &url, const TDEIO::MetaData &meta, int mainwindow) +{ + KSSLInfoDlg *kid = new KSSLInfoDlg(meta["ssl_in_use"].upper()=="TRUE", 0L /*parent?*/, 0L, true); + KSSLCertificate *x = KSSLCertificate::fromString(meta["ssl_peer_certificate"].local8Bit()); + if (x) { + // Set the chain back onto the certificate + TQStringList cl = + TQStringList::split(TQString("\n"), meta["ssl_peer_chain"]); + TQPtrList ncl; + + ncl.setAutoDelete(true); + for (TQStringList::Iterator it = cl.begin(); it != cl.end(); ++it) { + KSSLCertificate *y = KSSLCertificate::fromString((*it).local8Bit()); + if (y) ncl.append(y); + } + + if (ncl.count() > 0) + x->chain().setChain(ncl); + + kdDebug(7024) << "ssl_cert_errors=" << meta["ssl_cert_errors"] << endl; + kid->setCertState(meta["ssl_cert_errors"]); + TQString ip = meta.contains("ssl_proxied") ? "" : meta["ssl_peer_ip"]; + kid->setup( x, + ip, + url, // the URL + meta["ssl_cipher"], + meta["ssl_cipher_desc"], + meta["ssl_cipher_version"], + meta["ssl_cipher_used_bits"].toInt(), + meta["ssl_cipher_bits"].toInt(), + KSSLCertificate::KSSLValidation(meta["ssl_cert_state"].toInt())); + kdDebug(7024) << "Showing SSL Info dialog" << endl; +#ifndef Q_WS_WIN + if( mainwindow != 0 ) + KWin::setMainWindow( kid, mainwindow ); +#endif + kid->exec(); + delete x; + kdDebug(7024) << "SSL Info dialog closed" << endl; + } else { + KMessageBox::information( 0L, // parent ? + i18n("The peer SSL certificate appears to be corrupt."), i18n("SSL") ); + } + // Don't delete kid!! +} + +KSSLCertDlgRet UIServer::showSSLCertDialog(const TQString& host, const TQStringList& certList) +{ + return showSSLCertDialog( host, certList, 0 ); +} + +KSSLCertDlgRet UIServer::showSSLCertDialog(const TQString& host, const TQStringList& certList, int mainwindow) +{ + KSSLCertDlgRet rc; + rc.ok = false; + if (!certList.isEmpty()) { + KSSLCertDlg *kcd = new KSSLCertDlg(0L, 0L, true); + kcd->setupDialog(certList); + kcd->setHost(host); + kdDebug(7024) << "Showing SSL certificate dialog" << endl; +#ifndef Q_WS_WIN + if( mainwindow != 0 ) + KWin::setMainWindow( kcd, mainwindow ); +#endif + kcd->exec(); + rc.ok = true; + rc.choice = kcd->getChoice(); + rc.save = kcd->saveChoice(); + rc.send = kcd->wantsToSend(); + kdDebug(7024) << "SSL certificate dialog closed" << endl; + delete kcd; + } + return rc; +} + + +TQByteArray UIServer::open_RenameDlg( int id, + const TQString & caption, + const TQString& src, const TQString & dest, + int mode, + unsigned long sizeSrc, + unsigned long sizeDest, + unsigned long ctimeSrc, + unsigned long ctimeDest, + unsigned long mtimeSrc, + unsigned long mtimeDest + ) +{ return open_RenameDlg64(id, caption, src, dest, mode, sizeSrc, sizeDest, + ctimeSrc, ctimeDest, mtimeSrc, mtimeDest); } + + +TQByteArray UIServer::open_RenameDlg64( int id, + const TQString & caption, + const TQString& src, const TQString & dest, + int mode, + TDEIO::filesize_t sizeSrc, + TDEIO::filesize_t sizeDest, + unsigned long ctimeSrc, + unsigned long ctimeDest, + unsigned long mtimeSrc, + unsigned long mtimeDest + ) +{ + // Hide existing dialog box if any + ProgressItem *item = findItem( id ); + if ( item ) + setItemVisible( item, false ); + TQString newDest; + kdDebug(7024) << "Calling TDEIO::open_RenameDlg" << endl; + TDEIO::RenameDlg_Result result = TDEIO::open_RenameDlg( caption, src, dest, + (TDEIO::RenameDlg_Mode) mode, newDest, + sizeSrc, sizeDest, + (time_t)ctimeSrc, (time_t)ctimeDest, + (time_t)mtimeSrc, (time_t)mtimeDest ); + kdDebug(7024) << "TDEIO::open_RenameDlg done" << endl; + TQByteArray data; + TQDataStream stream( data, IO_WriteOnly ); + stream << TQ_UINT8(result) << newDest; + if ( item && result != TDEIO::R_CANCEL ) + setItemVisible( item, true ); + return data; +} + +int UIServer::open_SkipDlg( int id, + int /*bool*/ multi, + const TQString & error_text ) +{ + // Hide existing dialog box if any + ProgressItem *item = findItem( id ); + if ( item ) + setItemVisible( item, false ); + kdDebug(7024) << "Calling TDEIO::open_SkipDlg" << endl; + TDEIO::SkipDlg_Result result = TDEIO::open_SkipDlg( (bool)multi, error_text ); + if ( item && result != TDEIO::S_CANCEL ) + setItemVisible( item, true ); + return (TDEIO::SkipDlg_Result) result; +} + + +void UIServer::readSettings() { + TDEConfig config("uiserverrc"); + config.setGroup( "UIServer" ); + m_showStatusBar=config.readBoolEntry("ShowStatusBar",false); + m_showToolBar=config.readBoolEntry("ShowToolBar",true); + m_keepListOpen=config.readBoolEntry("KeepListOpen",false); + m_initWidth=config.readNumEntry("InitialWidth",460); + m_initHeight=config.readNumEntry("InitialHeight",150); + m_bShowList = config.readBoolEntry( "ShowList", false ); + m_showSystemTray=config.readBoolEntry("ShowSystemTray", false); +} + +void UIServer::writeSettings() { + TDEConfig config("uiserverrc"); + config.setGroup( "UIServer" ); + config.writeEntry("InitialWidth",width()); + config.writeEntry("InitialHeight",height()); + config.writeEntry("ShowStatusBar", m_showStatusBar); + config.writeEntry("ShowToolBar", m_showToolBar); + config.writeEntry("KeepListOpen", m_keepListOpen); + config.writeEntry("ShowList", m_bShowList); + config.writeEntry("ShowSystemTray", m_showSystemTray); +} + + +void UIServer::slotCancelCurrent() { + TQListViewItemIterator it( listProgress ); + ProgressItem *item; + + // kill selected jobs + for ( ; it.current() ; ++it ) + { + if ( it.current()->isSelected() ) { + item = (ProgressItem*) it.current(); + killJob( item->appId(), item->jobId() ); + return; + } + } +} + +void UIServer::resizeEvent(TQResizeEvent* e) +{ + KMainWindow::resizeEvent(e); + writeSettings(); +} + +bool UIServer::queryClose() +{ + if (( !m_shuttingDown ) && !kapp->sessionSaving()) { + hide(); + return false; + } + return true; +} + +UIServer* UIServer::createInstance() +{ + return new UIServer; +} + +//------------------------------------------------------------ + +extern "C" KDE_EXPORT int kdemain(int argc, char **argv) +{ + KLocale::setMainCatalogue("tdelibs"); + // GS 5/2001 - I changed the name to "TDE" to make it look better + // in the titles of dialogs which are displayed. + TDEAboutData aboutdata("tdeio_uiserver", I18N_NOOP("TDE"), + "0.8", I18N_NOOP("TDE Progress Information UI Server"), + TDEAboutData::License_GPL, "(C) 2000, David Faure & Matt Koss"); + // Who's the maintainer ? :) + aboutdata.addAuthor("David Faure",I18N_NOOP("Developer"),"faure@kde.org"); + aboutdata.addAuthor("Matej Koss",I18N_NOOP("Developer"),"koss@miesto.sk"); + + TDECmdLineArgs::init( argc, argv, &aboutdata ); + // TDECmdLineArgs::addCmdLineOptions( options ); + KUniqueApplication::addCmdLineOptions(); + + if (!KUniqueApplication::start()) + { + kdDebug(7024) << "tdeio_uiserver is already running!" << endl; + return (0); + } + + KUniqueApplication app; + + // This app is started automatically, no need for session management + app.disableSessionManagement(); + app.dcopClient()->setDaemonMode( true ); + + uiserver = UIServer::createInstance(); + +// app.setMainWidget( uiserver ); + + return app.exec(); +} + +#include "uiserver.moc" diff --git a/tdeio/misc/uiserver.h b/tdeio/misc/uiserver.h new file mode 100644 index 000000000..baf495dfe --- /dev/null +++ b/tdeio/misc/uiserver.h @@ -0,0 +1,430 @@ +/* This file is part of the KDE libraries + Copyright (C) 2000 Matej Koss + David Faure + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +#ifndef __tdeio_uiserver_h__ +#define __tdeio_uiserver_h__ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +class ListProgress; +class KSqueezedTextLabel; +class ProgressItem; +class UIServer; + +namespace TDEIO { + class Job; + class DefaultProgress; +} + + +struct ListProgressColumnConfig +{ + TQString title; + int index; + int width; + bool enabled; +}; + +/** +* List view in the UIServer. +* @internal +*/ +class TDEIO_EXPORT ListProgress : public KListView { + + Q_OBJECT + +public: + + ListProgress (TQWidget *parent = 0, const char *name = 0 ); + + virtual ~ListProgress(); + + /** + * Field constants + */ + enum ListProgressFields { + TB_OPERATION = 0, + TB_LOCAL_FILENAME = 1, + TB_RESUME = 2, + TB_COUNT = 3, //lv_count + TB_PROGRESS = 4, // lv_progress + TB_TOTAL = 5, + TB_SPEED = 6, + TB_REMAINING_TIME = 7, + TB_ADDRESS = 8, + TB_MAX = 9 + }; + + friend class ProgressItem; + friend class UIServer; +protected slots: + void columnWidthChanged(int column); +protected: + + void writeSettings(); + void readSettings(); + void applySettings(); + void createColumns(); + + bool m_showHeader; + bool m_fixedColumnWidths; + ListProgressColumnConfig m_lpcc[TB_MAX]; + //hack, alexxx + KSqueezedTextLabel *m_squeezer; +}; + +/** +* One item in the ListProgress +* @internal +*/ +class TDEIO_EXPORT ProgressItem : public TQObject, public TQListViewItem { + + Q_OBJECT + +public: + ProgressItem( ListProgress* view, TQListViewItem *after, TQCString app_id, int job_id, + bool showDefault = true ); + ~ProgressItem(); + + TQCString appId() { return m_sAppId; } + int jobId() { return m_iJobId; } + + bool keepOpen() const; + void finished(); + + void setVisible( bool visible ); + void setDefaultProgressVisible( bool visible ); + bool isVisible() const { return m_visible; } + + void setTotalSize( TDEIO::filesize_t bytes ); + void setTotalFiles( unsigned long files ); + void setTotalDirs( unsigned long dirs ); + + void setProcessedSize( TDEIO::filesize_t size ); + void setProcessedFiles( unsigned long files ); + void setProcessedDirs( unsigned long dirs ); + + void setPercent( unsigned long percent ); + void setSpeed( unsigned long bytes_per_second ); + void setInfoMessage( const TQString & msg ); + + void setCopying( const KURL& from, const KURL& to ); + void setMoving( const KURL& from, const KURL& to ); + void setDeleting( const KURL& url ); + void setTransferring( const KURL& url ); + void setCreatingDir( const KURL& dir ); + void setStating( const KURL& url ); + void setMounting( const TQString & dev, const TQString & point ); + void setUnmounting( const TQString & point ); + + void setCanResume( TDEIO::filesize_t offset ); + + TDEIO::filesize_t totalSize() { return m_iTotalSize; } + unsigned long totalFiles() { return m_iTotalFiles; } + TDEIO::filesize_t processedSize() { return m_iProcessedSize; } + unsigned long processedFiles() { return m_iProcessedFiles; } + unsigned long speed() { return m_iSpeed; } + unsigned int remainingSeconds() { return m_remainingSeconds; } + + const TQString& fullLengthAddress() const {return m_fullLengthAddress;} + void setText(ListProgress::ListProgressFields field, const TQString& text); +public slots: + void slotShowDefaultProgress(); + void slotToggleDefaultProgress(); + +protected slots: + void slotCanceled(); + +signals: + void jobCanceled( ProgressItem* ); + +protected: + void updateVisibility(); + + // ids that uniquely identify this progress item + TQCString m_sAppId; + int m_iJobId; + + // whether shown or not (it is hidden if a rename dialog pops up for the same job) + bool m_visible; + bool m_defaultProgressVisible; + + // parent listview + ListProgress *listProgress; + + // associated default progress dialog + TDEIO::DefaultProgress *defaultProgress; + + // we store these values for calculation of totals ( for statusbar ) + TDEIO::filesize_t m_iTotalSize; + unsigned long m_iTotalFiles; + TDEIO::filesize_t m_iProcessedSize; + unsigned long m_iProcessedFiles; + unsigned long m_iSpeed; + int m_remainingSeconds; + TQTimer m_showTimer; + TQString m_fullLengthAddress; +}; + +class TQResizeEvent; +class TQHideEvent; +class TQShowEvent; +class ProgressConfigDialog; +class TQPopupMenu; +class UIServerSystemTray; + +/** + * It's purpose is to show progress of IO operations. + * There is only one instance of this window for all jobs. + * + * All IO operations ( jobs ) are displayed in this window, one line per operation. + * User can cancel operations with Cancel button on toolbar. + * + * Double clicking an item in the list opens a small download window ( DefaultProgress ). + * + * @short Graphical server for progress information with an optional all-in-one progress window. + * @author David Faure + * @author Matej Koss + * + * @internal + */ +class TDEIO_EXPORT UIServer : public KMainWindow, public DCOPObject { + + K_DCOP + Q_OBJECT + + UIServer(); + virtual ~UIServer(); + +public: + static UIServer* createInstance(); + +k_dcop: + + /** + * Signal a new job + * @param appId the DCOP application id of the job's parent application + * @see TDEIO::Observer::newJob + * @param showProgress whether to popup the progress for the job. + * Usually true, but may be false when we use tdeio_uiserver for + * other things, like SSL dialogs. + * @return the job id + */ + int newJob( TQCString appId, bool showProgress ); + + ASYNC jobFinished( int id ); + + ASYNC totalSize( int id, unsigned long size ); + ASYNC totalSize64( int id, TDEIO::filesize_t size ); + ASYNC totalFiles( int id, unsigned long files ); + ASYNC totalDirs( int id, unsigned long dirs ); + + ASYNC processedSize( int id, unsigned long bytes ); + ASYNC processedSize64( int id, TDEIO::filesize_t bytes ); + ASYNC processedFiles( int id, unsigned long files ); + ASYNC processedDirs( int id, unsigned long dirs ); + + ASYNC percent( int id, unsigned long ipercent ); + ASYNC speed( int id, unsigned long bytes_per_second ); + ASYNC infoMessage( int id, const TQString & msg ); + + ASYNC copying( int id, KURL from, KURL to ); + ASYNC moving( int id, KURL from, KURL to ); + ASYNC deleting( int id, KURL url ); + ASYNC transferring( int id, KURL url ); + ASYNC creatingDir( int id, KURL dir ); + ASYNC stating( int id, KURL url ); + + ASYNC mounting( int id, TQString dev, TQString point ); + ASYNC unmounting( int id, TQString point ); + + ASYNC canResume( int id, unsigned long offset ); + ASYNC canResume64( int id, TDEIO::filesize_t offset ); + + /** + * @deprecated (it blocks other apps). + * Use TDEIO::PasswordDialog::getNameAndPassword instead. + * To be removed in KDE 4.0. + */ + TQByteArray openPassDlg( const TDEIO::AuthInfo &info ); + + /** + * Popup a message box. + * @param id The message identifier. + * @param type type of message box: QuestionYesNo, WarningYesNo, WarningContinueCancel... + * This enum is defined in slavebase.h, it currently is: + * QuestionYesNo = 1, WarningYesNo = 2, WarningContinueCancel = 3, + * WarningYesNoCancel = 4, Information = 5, SSLMessageBox = 6 + * @param text Message string. May contain newlines. + * @param caption Message box title. + * @param buttonYes The text for the first button. + * The default is i18n("&Yes"). + * @param buttonNo The text for the second button. + * The default is i18n("&No"). + * Note: for ContinueCancel, buttonYes is the continue button and buttonNo is unused. + * and for Information, none is used. + * @return a button code, as defined in KMessageBox, or 0 on communication error. + */ + int messageBox( int id, int type, const TQString &text, const TQString &caption, + const TQString &buttonYes, const TQString &buttonNo ); + + /** + * @deprecated (it blocks other apps). + * Use TDEIO::open_RenameDlg instead. + * To be removed in KDE 4.0. + */ + TQByteArray open_RenameDlg64( int id, + const TQString & caption, + const TQString& src, const TQString & dest, + int /* TDEIO::RenameDlg_Mode */ mode, + TDEIO::filesize_t sizeSrc, + TDEIO::filesize_t sizeDest, + unsigned long /* time_t */ ctimeSrc, + unsigned long /* time_t */ ctimeDest, + unsigned long /* time_t */ mtimeSrc, + unsigned long /* time_t */ mtimeDest + ); + /** + * @deprecated (it blocks other apps). + * Use TDEIO::open_RenameDlg instead. + * To be removed in KDE 4.0. + */ + TQByteArray open_RenameDlg( int id, + const TQString & caption, + const TQString& src, const TQString & dest, + int /* TDEIO::RenameDlg_Mode */ mode, + unsigned long sizeSrc, + unsigned long sizeDest, + unsigned long /* time_t */ ctimeSrc, + unsigned long /* time_t */ ctimeDest, + unsigned long /* time_t */ mtimeSrc, + unsigned long /* time_t */ mtimeDest + ); + + /** + * @deprecated (it blocks other apps). + * Use TDEIO::open_SkipDlg instead. + * To be removed in KDE 4.0. + */ + int open_SkipDlg( int id, + int /*bool*/ multi, + const TQString & error_text ); + + /** + * Switch to or from list mode - called by the kcontrol module + */ + void setListMode( bool list ); + + /** + * Hide or show a job. Typically, we hide a job while a "skip" or "rename" dialog + * is being shown for this job. This prevents killing it from the uiserver. + */ + void setJobVisible( int id, bool visible ); + + /** + * Show a SSL Information Dialog + */ + void showSSLInfoDialog(const TQString &url, const TDEIO::MetaData &data, int mainwindow); + + /** + * @deprecated + */ + void showSSLInfoDialog(const TQString &url, const TDEIO::MetaData &data); + + /* + * Show an SSL Certificate Selection Dialog + */ + KSSLCertDlgRet showSSLCertDialog(const TQString& host, const TQStringList& certList, int mainwindow); + + /* + * @deprecated + */ + KSSLCertDlgRet showSSLCertDialog(const TQString& host, const TQStringList& certList); + +public slots: + void slotConfigure(); + void slotRemoveSystemTrayIcon(); +protected slots: + + void slotUpdate(); + void slotQuit(); + + void slotCancelCurrent(); + + void slotToggleDefaultProgress( TQListViewItem * ); + void slotSelection(); + + void slotJobCanceled( ProgressItem * ); + void slotApplyConfig(); + void slotShowContextMenu(KListView*, TQListViewItem *item, const TQPoint& pos); + +protected: + + ProgressItem* findItem( int id ); + + virtual void resizeEvent(TQResizeEvent* e); + virtual bool queryClose(); + + void setItemVisible( ProgressItem * item, bool visible ); + + TQTimer* updateTimer; + ListProgress* listProgress; + + KToolBar::BarPosition toolbarPos; + TQString properties; + + void applySettings(); + void readSettings(); + void writeSettings(); +private: + + void killJob( TQCString observerAppId, int progressId ); + + int m_initWidth; + int m_initHeight; + int m_idCancelItem; + bool m_bShowList; + bool m_showStatusBar; + bool m_showToolBar; + bool m_keepListOpen; + bool m_showSystemTray; + bool m_shuttingDown; + + // true if there's a new job that hasn't been shown yet. + bool m_bUpdateNewJob; + ProgressConfigDialog *m_configDialog; + TQPopupMenu* m_contextMenu; + UIServerSystemTray *m_systemTray; + + static int s_jobId; + friend class no_bogus_warning_from_gcc; +}; + +// -*- mode: c++; c-basic-offset: 2 -*- +#endif -- cgit v1.2.1