From 464d6da8fb57fe3e60e4c2c3cae6069bdafff6a5 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 24 Aug 1999 07:40:45 +0000 Subject: [PATCH] initial checkin of signup server --- fs_signup/FS-SignupClient/Changes | 5 + fs_signup/FS-SignupClient/MANIFEST | 8 + fs_signup/FS-SignupClient/MANIFEST.SKIP | 1 + fs_signup/FS-SignupClient/Makefile.PL | 10 + fs_signup/FS-SignupClient/cgi/signup.cgi | 302 +++++++++++++++++++++++++++++ fs_signup/{ => FS-SignupClient}/fs_signupd | 28 ++- fs_signup/FS-SignupClient/test.pl | 20 ++ fs_signup/README | 18 ++ fs_signup/Signup.pm | 129 ------------ fs_signup/fs_signup_server | 61 ++++-- 10 files changed, 423 insertions(+), 159 deletions(-) create mode 100644 fs_signup/FS-SignupClient/Changes create mode 100644 fs_signup/FS-SignupClient/MANIFEST create mode 100644 fs_signup/FS-SignupClient/MANIFEST.SKIP create mode 100644 fs_signup/FS-SignupClient/Makefile.PL create mode 100755 fs_signup/FS-SignupClient/cgi/signup.cgi rename fs_signup/{ => FS-SignupClient}/fs_signupd (75%) create mode 100644 fs_signup/FS-SignupClient/test.pl create mode 100644 fs_signup/README delete mode 100755 fs_signup/Signup.pm diff --git a/fs_signup/FS-SignupClient/Changes b/fs_signup/FS-SignupClient/Changes new file mode 100644 index 000000000..e750a82bc --- /dev/null +++ b/fs_signup/FS-SignupClient/Changes @@ -0,0 +1,5 @@ +Revision history for Perl extension FS::SignupClient. + +0.01 Mon Aug 23 01:12:46 1999 + - original version; created by h2xs 1.19 + diff --git a/fs_signup/FS-SignupClient/MANIFEST b/fs_signup/FS-SignupClient/MANIFEST new file mode 100644 index 000000000..b4a9900c8 --- /dev/null +++ b/fs_signup/FS-SignupClient/MANIFEST @@ -0,0 +1,8 @@ +Changes +MANIFEST +MANIFEST.SKIP +Makefile.PL +SignupClient.pm +test.pl +fs_signupd +cgi/signup.cgi diff --git a/fs_signup/FS-SignupClient/MANIFEST.SKIP b/fs_signup/FS-SignupClient/MANIFEST.SKIP new file mode 100644 index 000000000..ae335e78a --- /dev/null +++ b/fs_signup/FS-SignupClient/MANIFEST.SKIP @@ -0,0 +1 @@ +CVS/ diff --git a/fs_signup/FS-SignupClient/Makefile.PL b/fs_signup/FS-SignupClient/Makefile.PL new file mode 100644 index 000000000..859d757c3 --- /dev/null +++ b/fs_signup/FS-SignupClient/Makefile.PL @@ -0,0 +1,10 @@ +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + 'NAME' => 'FS::SignupClient', + 'VERSION_FROM' => 'SignupClient.pm', # finds $VERSION + 'EXE_FILES' => [ 'fs_signupd' ], + 'INSTALLSCRIPT' => '/usr/local/sbin', + 'PERM_RWX' => '750', +); diff --git a/fs_signup/FS-SignupClient/cgi/signup.cgi b/fs_signup/FS-SignupClient/cgi/signup.cgi new file mode 100755 index 000000000..7131ad2e8 --- /dev/null +++ b/fs_signup/FS-SignupClient/cgi/signup.cgi @@ -0,0 +1,302 @@ +#!/usr/bin/perl -Tw +# +# $Id: signup.cgi,v 1.1 1999-08-24 07:40:45 ivan Exp $ + +use strict; +use vars qw( @payby $cgi $locales $packages $pops $r $error + $last $first $ss $company $address1 $address2 $city $state $county + $country $zip $daytime $night $fax $invoicing_list $payby $payinfo + $paydate $payname $pkgpart $username $password $popnum ); +use subs qw( print_form print_okay expselect ); + +use CGI; +use CGI::Carp qw(fatalsToBrowser); +use FS::SignupClient qw( signup_info new_customer ); + +#@payby = qw( CARD BILL COMP ); +#@payby = qw( CARD BILL ); +@payby = qw( CARD ); + +( $locales, $packages, $pops ) = signup_info(); + +$cgi = new CGI; + +if ( defined $cgi->param('magic') ) { + if ( $cgi->param('magic') eq 'process' ) { + + $cgi->param('state') =~ /^(\w*)( \(([\w ]+)\))? ?\/ ?(\w+)$/ + or die "Oops, illegal \"state\" param: ". $cgi->param('state'); + $state = $1; + $county = $3 || ''; + $country = $4; + + $payby = $cgi->param('payby'); + $payinfo = $cgi->param( $payby. '_payinfo' ); + $paydate = + $cgi->param( $payby. '_month' ). '-'. $cgi->param( $payby. '_year' ); + $payname = $cgi->param( $payby. '_payname' ); + + if ( $invoicing_list = $cgi->param('invoicing_list') ) { + $invoicing_list .= ', POST' if $cgi->param('invoicing_list_POST'); + } else { + $invoicing_list = 'POST'; + } + + ( $error = new_customer ( { + 'last' => $last = $cgi->param('last'), + 'first' => $first = $cgi->param('first'), + 'ss' => $ss = $cgi->param('ss'), + 'company' => $company = $cgi->param('company'), + 'address1' => $address1 = $cgi->param('address1'), + 'address2' => $address2 = $cgi->param('address2'), + 'city' => $city = $cgi->param('city'), + 'county' => $county, + 'state' => $state, + 'zip' => $zip = $cgi->param('zip'), + 'country' => $country, + 'daytime' => $daytime = $cgi->param('daytime'), + 'night' => $night = $cgi->param('night'), + 'fax' => $fax = $cgi->param('fax'), + 'payby' => $payby, + 'payinfo' => $payinfo, + 'paydate' => $paydate, + 'payname' => $payname, + 'invoicing_list' => $invoicing_list, + 'pkgpart' => $pkgpart = $cgi->param('pkgpart'), + 'username' => $username = $cgi->param('username'), + '_password' => $password = $cgi->param('_password'), + 'popnum' => $popnum = $cgi->param('popnum'), + } ) ) + ? print_form() + : print_okay(); + } else { + die "unrecognized magic: ". $cgi->param('magic'); + } +} else { + $error = ''; + $last = ''; + $first = ''; + $ss = ''; + $company = ''; + $address1 = ''; + $address2 = ''; + $city = ''; + $state = ''; + $county = ''; + $country = ''; + $zip = ''; + $daytime = ''; + $night = ''; + $fax = ''; + $invoicing_list = ''; + $payby = ''; + $payinfo = ''; + $paydate = ''; + $payname = ''; + $pkgpart = ''; + $username = ''; + $password = ''; + $popnum = ''; + + print_form; +} + +sub print_form { + + my $r = qq!*!; + my $self_url = $cgi->self_url; + + print $cgi->header( '-expires' => 'now' ), <ISP Signup form +ISP Signup form

+END + + print qq!Error: $error! if $error; + + print < + +Contact Information + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
${r}Contact name
(last, first)
, + SS#
Company
${r}Address
 
${r}City${r}State/Country${r}Zip
Day Phone
Night Phone
Fax
$r required fields
+
Billing information +!; + + print <
+END + + print qq!Postal mail invoice
Email invoice ', + qq!
Billing type
+ + +END + + my %payby = ( + 'CARD' => qq!Credit card
${r}
${r}Exp !. expselect("CARD"). qq!
${r}Name on card
!, + 'BILL' => qq!Billing
P.O.
${r}Exp !. expselect("BILL", "12-2037"). qq!
${r}Attention
!, + 'COMP' => qq!Complimentary
${r}Approved by
${r}Exp !. expselect("COMP"), + ); + + my %paybychecked = ( + 'CARD' => qq!Credit card
${r}
${r}Exp !. expselect("CARD", $paydate). qq!
${r}Name on card
!, + 'BILL' => qq!Billing
P.O.
${r}Exp !. expselect("BILL", $paydate). qq!
${r}Attention
!, + 'COMP' => qq!Complimentary
${r}Approved by
${r}Exp !. expselect("COMP", $paydate), + ); + + for (@payby) { + print qq!!; + } else { + print qq!> $payby{$_}!; + } + } + + print <
$paybychecked{$_}
$r required fields for each billing type +

First package + + + + + + + + + + + + + + + + +
Username
Password + (blank to generate)
POP
+

+ +END + +} + +sub print_okay { + print $cgi->header( '-expires' => 'now' ), <Signup successful +Signup successful

+blah blah blah + + +END +} + +sub expselect { + my $prefix = shift; + my $date = shift || ''; + my( $m, $y ) = ( 0, 0 ); + if ( $date =~ /^(\d{4})-(\d{2})-\d{2}$/ ) { #PostgreSQL date format + ( $m, $y ) = ( $2, $1 ); + } elsif ( $date =~ /^(\d{1,2})-(\d{1,2}-)?(\d{4}$)/ ) { + ( $m, $y ) = ( $1, $3 ); + } + my $return = qq!!; + for ( 1999 .. 2037 ) { + $return .= " ); my @cust_main_county = map { chomp( my $taxnum = ); @@ -33,6 +38,7 @@ my @cust_main_county = map { }; } ( 1 .. $n_cust_main_county ); +warn "[fs_signupd] Reading package definitions...\n" if $Debug; chomp( my $n_part_pkg = ); my @part_pkg = map { chomp( my $pkgpart = ); @@ -43,6 +49,7 @@ my @part_pkg = map { }; } ( 1 .. $n_part_pkg ); +warn "[fs_signupd] Reading POPs...\n" if $Debug; chomp( my $n_svc_acct_pop = ); my @svc_acct_pop = map { chomp( my $popnum = ); @@ -59,22 +66,22 @@ my @svc_acct_pop = map { }; } ( 1 .. $n_svc_acct_pop ); -my $uaddr = sockaddr_un($fs_passwdd_socket); +warn "[fs_signupd] Creating $fs_signupd_socket\n" if $Debug; +my $uaddr = sockaddr_un($fs_signupd_socket); my $proto = getprotobyname('tcp'); - socket(Server,PF_UNIX,SOCK_STREAM,0) or die "socket: $!"; -unlink($fs_passwdd_socket); +unlink($fs_signupd_socket); bind(Server, $uaddr) or die "bind: $!"; listen(Server,SOMAXCONN) or die "listen: $!"; +warn "[fs_signupd] Entering main loop...\n" if $Debug; my $paddr; - for ( ; $paddr = accept(Client,Server); close Client) { chop( my $command = ); if ( $command eq "signup_info" ) { - + warn "[fs_signupd] sending signup info...\n" if $Debug; print Client join("\n", $n_cust_main_county, map { $_->{taxnum}, @@ -101,15 +108,16 @@ for ( ; $paddr = accept(Client,Server); close Client) { } @svc_acct_pop ), "\n"; - } elsif ( $operation eq "new_customer" ) { - + } elsif ( $command eq "new_customer" ) { + warn "[fs_signupd] reading customer signup...\n" if $Debug; my( $first, $last, $ss, $company, $address1, $address2, $city, $county, $state, $zip, $country, $daytime, $night, $fax, $payby, $payinfo, $paydate, $payname, $invoicing_list, $pkgpart, $username, $password, $popnum, - ) = ; + ) = map { scalar() } ( 1 .. 23 ); + warn "[fs_signupd] sending customer data to remote server...\n" if $Debug; print $first, $last, $ss, $company, $address1, $address2, $city, $county, $state, $zip, $country, $daytime, $night, $fax, $payby, $payinfo, @@ -117,8 +125,10 @@ for ( ; $paddr = accept(Client,Server); close Client) { $popnum, ; + warn "[fs_signupd] reading error from remote server...\n" if $Debug; my $error = ; + warn "[fs_signupd] sending error to local client...\n" if $Debug; print Client $error; } else { diff --git a/fs_signup/FS-SignupClient/test.pl b/fs_signup/FS-SignupClient/test.pl new file mode 100644 index 000000000..690f5840e --- /dev/null +++ b/fs_signup/FS-SignupClient/test.pl @@ -0,0 +1,20 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### We start with some black magic to print on failure. + +# Change 1..1 below to 1..last_test_to_print . +# (It may become useful if the test is moved to ./t subdirectory.) + +BEGIN { $| = 1; print "1..1\n"; } +END {print "not ok 1\n" unless $loaded;} +use FS::SignupClient; +$loaded = 1; +print "ok 1\n"; + +######################### End of black magic. + +# Insert your test code below (better if it prints "ok 13" +# (correspondingly "not ok 13") depending on the success of chunk 13 +# of the test code): + diff --git a/fs_signup/README b/fs_signup/README new file mode 100644 index 000000000..631c22364 --- /dev/null +++ b/fs_signup/README @@ -0,0 +1,18 @@ +this should become better docs soon + +on client machine (public webserver): + +install perl, ssh, CGI.pm +cd FS-SignupClient; perl Makefile.PL; make; su; make install +copy or symlink FS-SignupClient/cgi/signup.cgi into the web server's view +use suExec or setuid to run cgi/signup.cgi as the freeside user +(chmod /usr/local/freeside/fs_signupd_socket 600, chown freeside) + +on server machine (Freeside machine): + +run fs_signup_server user machine agentnum refnum + + user is a freeside user from mapsecrets + machine is the client machine + agentnum and refnum are the fixed values for this signup server + diff --git a/fs_signup/Signup.pm b/fs_signup/Signup.pm deleted file mode 100755 index bcf09f1fe..000000000 --- a/fs_signup/Signup.pm +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/perl -Tw -# -# fs_passwd -# -# portions of this script are copied from the `passwd' script in the original -# (perl 4) camel book, now archived at -# http://www.perl.com/CPAN/scripts/nutshell/ch6/passwd -# -# ivan@sisd.com 98-mar-8 -# -# password lengths 0,255 instead of 6,8 - we'll let the server process -# check the data ivan@sisd.com 98-jul-17 - -use strict; -use Getopt::Std; -use Socket; -use IO::Handle; -use vars qw($opt_f $opt_s); - -my($fs_passwdd_socket)="/usr/local/freeside/fs_passwdd_socket"; -my($freeside_uid)=scalar(getpwnam('freeside')); - -$ENV{'PATH'} ='/usr/bin:/usr/ucb:/bin'; -$ENV{'SHELL'} = '/bin/sh'; -$ENV{'IFS'} = " \t\n"; -$ENV{'CDPATH'} = ''; -$ENV{'ENV'} = ''; -$ENV{'BASH_ENV'} = ''; - -$SIG{__DIE__}= sub { system '/bin/stty', 'echo'; }; - -die "passwd program isn't running setuid to freeside\n" if $> != $freeside_uid; - -unshift @ARGV, "-f" if $0 =~ /chfn$/; -unshift @ARGV, "-s" if $0 =~ /chsh$/; - -getopts('fs'); - -my($me)=''; -if ( $_ = shift(@ARGV) ) { - /^(\w{2,8})$/; - $me = $1; -} -die "You can't change the password for $me." if $me && $<; -$me = (getpwuid($<))[0] unless $me; - -my($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell)= - getpwnam $me; - -my($old_password,$new_password,$new_gecos,$new_shell); - -if ( $opt_f || $opt_s ) { - system '/bin/stty', '-echo'; - print "Password:"; - $old_password=; - system '/bin/stty', 'echo'; - chop($old_password); - #$old_password =~ /^(.{6,8})$/ or die "\nIllegal password.\n"; - $old_password =~ /^(.{0,255})$/ or die "\nIllegal password.\n"; - $old_password = $1; - - $new_password = ''; - - if ( $opt_f ) { - print "\nChanging gecos for $me.\n"; - print "Gecos [", $gcos, "]: "; - $new_gecos=; - chop($new_gecos); - $new_gecos ||= $gcos; - $new_gecos =~ /^(.{0,255})$/ or die "\nIllegal gecos.\n"; - } else { - $new_gecos = ''; - } - - if ( $opt_s ) { - print "\nChanging shell for $me.\n"; - print "Shell [", $shell, "]: "; - $new_shell=; - chop($new_shell); - $new_shell ||= $shell; - $new_shell =~ /^(.{0,255})$/ or die "\nIllegal shell.\n"; - } else { - $new_shell = ''; - } - -} else { - - print "Changing password for $me.\n"; - print "Old password:"; - system '/bin/stty', '-echo'; - $old_password=; - chop $old_password; - #$old_password =~ /^(.{6,8})$/ or die "\nIllegal password.\n"; - $old_password =~ /^(.{0,255})$/ or die "\nIllegal password.\n"; - $old_password = $1; - print "\nEnter the new password (minimum of 6, maximum of 8 characters)\n"; - print "Please use a combination of upper and lowercase letters and numbers.\n"; - print "New password:"; - $new_password=; - chop($new_password); - #$new_password =~ /^(.{6,8})$/ or die "\nIllegal password.\n"; - $new_password =~ /^(.{0,255})$/ or die "\nIllegal password.\n"; - $new_password = $1; - print "\nRe-enter new password:"; - my($check_new_password); - $check_new_password=; - chop($check_new_password); - die "\nThey don't match; try again.\n" unless $check_new_password eq $new_password; - - $new_gecos=''; - $new_shell=''; -} -print "\n"; - -system '/bin/stty', 'echo'; - -socket(SOCK, PF_UNIX, SOCK_STREAM, 0) or die "socket: $!"; -connect(SOCK, sockaddr_un($fs_passwdd_socket)) or die "connect: $!"; -print SOCK join("\n",$me,$old_password,$new_password,$new_gecos,$new_shell),"\n"; -SOCK->flush; -my($error); -$error = ; -chop $error; - -if ($error) { - print "\nUpdate error: $error\n"; -} else { - print "\nUpdate sucessful.\n"; -} diff --git a/fs_signup/fs_signup_server b/fs_signup/fs_signup_server index cf2519ec0..e1c9b3517 100755 --- a/fs_signup/fs_signup_server +++ b/fs_signup/fs_signup_server @@ -7,14 +7,18 @@ use strict; use IO::Handle; use FS::SSH qw(sshopen2); use FS::UID qw(adminsuidsetup); -use FS::Record qw(qsearchs); +use FS::Record qw( qsearch qsearchs ); use FS::cust_main_county; use FS::cust_main; -use vars qw( $opt ); +use vars qw( $opt $Debug ); + +$Debug = 0; + +my @payby = qw(CARD); my $user = shift or die &usage; -adminsuidsetup $user; +&adminsuidsetup( $user ); my $machine = shift or die &usage; @@ -31,12 +35,15 @@ my($fs_signupd)="/usr/local/sbin/fs_signupd"; while (1) { my($reader,$writer)=(new IO::Handle, new IO::Handle); $writer->autoflush(1); - sshopen2($shellmachine,$reader,$writer,$fs_signupd); + warn "[fs_signup_server] Connecting to $machine...\n" if $Debug; + sshopen2($machine,$reader,$writer,$fs_signupd); + + my $data; - #send fs_signupd state/county/country - @my cust_main_county = qsearch('cust_main_county', {} ); - print $writer join("\n", - scalar(@cust_main_county) || die "no tax rates (cust_main_county records)", + warn "[fs_signup_server] Sending locales...\n" if $Debug; + my @cust_main_county = qsearch('cust_main_county', {} ); + print $writer $data = join("\n", + ( scalar(@cust_main_county) || die "no tax rates (cust_main_county records)" ), map { $_->taxnum, $_->state, @@ -44,22 +51,24 @@ while (1) { $_->country, } @cust_main_county ),"\n"; + warn "[fs_signup_server] $data\n" if $Debug > 2; - #send fs_signupd package definitions + warn "[fs_signup_server] Sending package definitions...\n" if $Debug; my @part_pkg = grep { $_->svcpart('svc_acct') && $pkgpart->{ $_->pkgpart } } qsearch( 'part_pkg', {} ); - print $writer join("\n", - scalar(@part_pkg) || die "no usable package definitions, agent $agentnum", + print $writer $data = join("\n", + ( scalar(@part_pkg) || die "no usable package definitions, agent $agentnum" ), map { $_->pkgpart, $_->pkg, } @part_pkg ), "\n"; + warn "[fs_signup_server] $data\n" if $Debug > 2; - #send fs_signupd POPs + warn "[fs_signup_server] Sending POPs...\n" if $Debug; my @svc_acct_pop = qsearch ('svc_acct_pop',{} ); - print $writer join("\n", - scalar(@svc_acct_pop) || die "No points of presence (svc_acct_pop records)", + print $writer $data = join("\n", + ( scalar(@svc_acct_pop) || die "No points of presence (svc_acct_pop records)" ), map { $_->popnum, $_->city, @@ -68,14 +77,19 @@ while (1) { $_->exch, } @svc_acct_pop ), "\n"; + warn "[fs_signup_server] $data\n" if $Debug > 2; + warn "[fs_signup_server] Entering main loop...\n" if $Debug; while (1) { + warn "[fs_signup_server] Reading (waiting for) signup data...\n" if $Debug; chop( my( $first, $last, $ss, $company, $address1, $address2, $city, $county, $state, $zip, $country, $daytime, $night, $fax, $payby, $payinfo, $paydate, $payname, $invoicing_list, $pkgpart, $username, $password, $popnum, - ) = <$reader> ); + ) = map { scalar(<$reader>) } ( 1 .. 23 ) ); + + warn "[fs_signup_server] Processing signup...\n" if $Debug; my $error = ''; @@ -105,17 +119,21 @@ while (1) { 'payname' => $payname, } ); + $error = "Illegal payment type" unless grep { $_ eq $payby } @payby; + my @invoicing_list = split( /\s*\,\s*/, $invoicing_list ); $error ||= $cust_main->check_invoicing_list( \@invoicing_list ); my $part_pkg = qsearchs( 'part_pkg', { 'pkgpart' => $pkgpart } ) - or die "unknown pkgpart $pkgpart"; + or $error ||= "WARNING: unknown pkgpart $pkgpart"; my $svcpart = $part_pkg->svcpart; # this should wind up in FS::cust_pkg! - die "agent $agentnum can't purchase pkgpart $pkgpart" - unless $pkgpart->{ $pkgpart }; + my $agent = qsearchs( 'agent', { 'agentnum' => $agentnum } ); + my $pkgpart_href = $agent->pkgpart_hashref; + $error ||= "WARNING: agent $agentnum can't purchase pkgpart $pkgpart" + unless $pkgpart_href->{ $pkgpart }; my $cust_pkg = new FS::cust_pkg ( { #later#'custnum' => $custnum, @@ -123,7 +141,7 @@ while (1) { } ); $error ||= $cust_pkg->check; - $svc_acct = new FS::svc_acct ( { + my $svc_acct = new FS::svc_acct ( { 'svcpart' => $svcpart, 'username' => $username, '_password' => $password, @@ -143,7 +161,7 @@ while (1) { $error ||= $cust_main->insert; if ( $cust_pkg && ! $error ) { #in this case, $cust_pkg should always #be definied, but.... - $cust_pkg->custnum( $new->custnum ); + $cust_pkg->custnum( $cust_main->custnum ); $error ||= $cust_pkg->insert; warn "WARNING: $error on pre-checked cust_pkg record!" if $error; $svc_acct->pkgnum( $cust_pkg->pkgnum ); @@ -151,6 +169,7 @@ while (1) { warn "WARNING: $error on pre-checked svc_acct record!" if $error; } + warn "[fs_signup_server] Sending results...\n" if $Debug; print $writer $error, "\n"; $cust_main->invoicing_list( \@invoicing_list ) unless $error; @@ -158,7 +177,7 @@ while (1) { } close $writer; close $reader; - warn "connection to $shellmachine lost! waiting 60 seconds...\n"; + warn "connection to $machine lost! waiting 60 seconds...\n"; sleep 60; warn "reconnecting...\n"; } -- 2.11.0