#! /usr/local/bin/perl ################################################################ ### ### impwagent ### ### Author: Internet Message Group ### Created: Sep 13, 1997 ### Revised: Mar 8, 2005 ### BEGIN { use lib '/usr/local/lib'; use lib '/mnt/gmirror/ports/mail/im/work/im-148'; ###DELETE-ON-INSTALL### }; $Prog = 'impwagent'; my $VERSION_DATE = "20050308"; my $VERSION_NUMBER = "148"; my $VERSION = "${Prog} version ${VERSION_DATE}(IM${VERSION_NUMBER})"; my $VERSION_INFORMATION = "${Prog} (IM ${VERSION_NUMBER}) ${VERSION_DATE} Copyright (C) 1999 IM developing team This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. "; ## ## Require packages ## require 5.003; use Socket; use IM::Config; use IM::GetPass; use IM::Util; ## ## Main ## @OptConfig = (); init_opt(\@OptConfig); read_cfg(); # server termination if ($ARGV[0] =~ /stop|quit/i) { $res = &connect_agent(1); $res = &talk_agent("QUIT\n") if ($res ne ''); if ($res eq '') { print "$Prog: server is not running\n"; } else { print "$Prog: exit message: $res\n"; } exit $EXIT_SUCCESS; } # clear password cache if ($ARGV[0] =~ /clear/i) { $res = &connect_agent(1); $res = &talk_agent("CLEAR\n") if ($res ne ''); if ($res eq '') { print "$Prog: server is not running\n"; } else { print "$Prog: exit message: $res\n"; } exit $EXIT_SUCCESS; } if ($ARGV[0] =~ /--version/i) { print("${VERSION_INFORMATION}") && exit $EXIT_SUCCESS; } # display help if ($ARGV[0] !~ /start/i && @ARGV > 0) { print < EOF exit $EXIT_SUCCESS; } # duplicate check $res = &connect_agent(1); $res = &talk_agent("PING\n") if ($res ne ''); if ($res eq 'PONG') { print STDERR "$Prog: already running.\n"; exit $EXIT_ERROR; } # preparing socket directory my $realuser = im_getlogin(); unless ($realuser) { print STDERR "$Prog: can not get login name.\n"; exit $EXIT_ERROR; } my $dir = &pwagent_tmp_path() . "-$realuser"; my $port = &pwagentport(); if ($port > 0) { rmdir $dir; unless (mkdir($dir, 0700)) { print STDERR "$Prog: can not create directory: $dir.\n"; exit $EXIT_ERROR; } unless (socket(SOCK, &AF_INET, &SOCK_STREAM, 0)) { print STDERR "$Prog: socket: $!\n"; exit $EXIT_ERROR; } my $sin = sockaddr_in($port, inet_aton('127.0.0.1')); unless (bind(SOCK, $sin)) { print STDERR "$Prog: bind: $!\n"; exit $EXIT_ERROR; } } else { $sockname = "$dir/pw"; # be sure the dir is not a link unlink $sockname; rmdir $dir; unless (mkdir($dir, 0700)) { print STDERR "$Prog: can not create directory: $dir.\n"; exit $EXIT_ERROR; } unless (socket(SOCK, &AF_UNIX, &SOCK_STREAM, 0)) { print STDERR "$Prog: socket: $!\n"; exit $EXIT_ERROR; } my $sun = sockaddr_un($sockname); unless (bind(SOCK, $sun)) { print STDERR "$Prog: bind: $!\n"; exit $EXIT_ERROR; } chmod(0600, $sockname); } listen(SOCK, 5); select(SOCK); $| = 1; select(STDOUT); $SIG{'ALRM'} = \&alarm_func; #my $ppid = getppid(); my $id = fork(); if ($id < 0) { print STDERR "$Prog: can not fork: $!\n"; exit $EXIT_ERROR; } if ($id) { print STDERR "$Prog: started (pid: $id)\n"; exit $EXIT_SUCCESS; } chdir($dir); @_ = unpack('C2', pack('L', rand(time * $$))); foreach (@_) { $_ |= 0x20 if ($_ < 0x20); } my $key = pack('C2', @_); for (;;) { unless (accept(REQ, SOCK)) { print STDERR "$Prog: accept: $!\n"; exit $EXIT_ERROR; } if ($port > 0) { my $sa = getpeername(REQ); my($fa, $po, $ad) = sockaddr_in($sa); next if ($ad != inet_aton('127.0.0.1')); } select(REQ); $| = 1; select(STDOUT); print REQ "$key\n"; alarm(3); $_ = ; alarm(0); chomp; if (/^PING$/) { print REQ "PONG\n"; } elsif (/^CLEAR$/) { undef %pwcache; print REQ "CLEARED\n"; } elsif (/^SAVE\t(.*)/) { my $param = $1; alarm(3); $_ = ; alarm(0); chomp; if (/^PASS\t/) { # decode from HEX string $pwcache{$param} = pack('H*', substr($_, 5)); print REQ "OK\n"; } else { print REQ "ERROR\n"; } } elsif (/^LOAD\t(.*)/) { # encode to HEX string $_ = "PASS\t" . unpack('H*', $pwcache{$1}) . "\n"; print REQ $_; } else { # protocol error (including QUIT) print REQ "BYE\n"; shutdown(REQ, 2); close(REQ); close(SOCK); unlink($sockname) if ($sockname); rmdir $dir; exit $EXIT_ERROR; } substr($_, 0, length($_)) = '0123456789abcdef'; shutdown(REQ, 2); close(REQ); } sub alarm_func { # no operation } __END__ =head1 NAME impwagent - hold passwords for IM =head1 SYNOPSIS B [OPTIONS] =head1 DESCRIPTION The I command holds passwords to reuse on later sessions for IM. If you wish to use the feature supplied by impwagent, put UsePwAgent=yes in your Config file, and start impwagent manually before using im* commands which require passwords. This command is provided by IM (Internet Message). =head1 OPTIONS =over 5 =item I Start impwagent. This is the default behavior. =item I, I Terminate impwagent. =item I Clear passwords held by impwagent. =item I Display help message and exit. =item I<--version> Output version information and exit. =back =head1 COPYRIGHT IM (Internet Message) is copyrighted by IM developing team. You can redistribute it and/or modify it under the modified BSD license. See the copyright file for more details. =cut ### Copyright (C) 1997, 1998, 1999 IM developing team ### All rights reserved. ### ### Redistribution and use in source and binary forms, with or without ### modification, are permitted provided that the following conditions ### are met: ### ### 1. Redistributions of source code must retain the above copyright ### notice, this list of conditions and the following disclaimer. ### 2. Redistributions in binary form must reproduce the above copyright ### notice, this list of conditions and the following disclaimer in the ### documentation and/or other materials provided with the distribution. ### 3. Neither the name of the team nor the names of its contributors ### may be used to endorse or promote products derived from this software ### without specific prior written permission. ### ### THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS'' AND ### ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ### IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR ### PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TEAM OR CONTRIBUTORS BE ### LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ### CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ### SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ### BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, ### WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE ### OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN ### IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ### Local Variables: ### mode: perl ### End: