pptp-client/0040755000567100000120000000000007701233275013007 5ustar jcameronwheelpptp-client/images/0040775000567100000120000000000007701233300014243 5ustar jcameronwheelpptp-client/images/icon.gif0100664000567100000120000000245407701233271015673 0ustar jcameronwheelGIF89a00vvv^^^֢~~~nnnrrrjjjbbb666fffZZZNNN:::zzzVVVBBBJJJ¦FFFҾRRR222>>>ⶶRRV... ***FFN"""&&&???,00     ʼ  ك˔ !" #ۏ$ JQi"`"]"@"0tTz@ DܹۘZ So^ M`0!!vN`A`0TČl1(X06n#`h&tL:"ab yqcÇn9!%QÇ;&vK¹&ȱC63,3rPt!iH̀˙o(?rd`2'A ȓ4@ҫ_ϾPA~og;~hϿIȇmig闃z4 ; W`}݇_'ć (\Be]hg; (#$^2_f8@ r(d`&r:fȢ@ 1 9bzͶm֢?eRN D\vea~H$ps[FLfD`>ǥ^0A{I$ %?'`&%P<D CvzhZDB ÝB !K$0pz- Dg혙PDρ6 O k-A\Т:#XnzG$HF׬k/I4 oX-[/0 kZ E4!4DE<_!EEﺅ&@ R(zK#U EP ꝫkOν'"Kv|-7t D}n ;pptp-client/images/tunnel.gif0100664000567100000120000000226207701233274016250 0ustar jcameronwheelGIF89a00>>>VVVvvv..."""fffJJJ222 򚚚&&&666BBBjjj^^^RRR***:::nnnzzzFFFNNNbbbrrr~~~ZZZFFNRRV,009@ E(@=)3A:2<8B<8>6'=+)>61A+<) 4*B%2. 4%2>"E0CUañN 8-i!?IyGq)'ىM$ * !$1 tCH |`AA /0-2&k£$hPYea`1!zB&*-(P`Ѡcph al`CApud {XW,882>><<<:::888666222000...,,,***(((&&&"""ggi  ,3HAr*<('‚ @C`Ç%)pA82\|G-_@hH_pr2%1(!?<8∈`f9&$Ą3kS@<\t-\˜Q󦎠G/ND V$W=|I9`A & BK4\Jb"C|DaGSQHLKfD)F3~7r6RDg 7pHb D7ڋt =n/lCǍE2 t7p;*AC )h $E +AV`&Giȃ+p(PC( ^ @x pRcn\сO@!x ! $OTAdPdM6^d ;pptp-client/secrets-lib.pl0100664000567100000120000000313307701233274015556 0ustar jcameronwheel# secrets-lib.pl # Common functions for editing a PPP users file # list_secrets() sub list_secrets { local(@rv, $line, $_); open(SEC, $config{'pap_file'}); $line = 0; while() { chop; s/^#.*$//g; @w = &split_words($_); if (@w >= 3) { local(%sec, @ips); $sec{'client'} = $w[0]; $sec{'server'} = $w[1]; $sec{'secret'} = $w[2]; @ips = @w[3..$#w]; $sec{'ips'} = \@ips; $sec{'line'} = $line; $sec{'index'} = scalar(@rv); push(@rv, \%sec); } $line++; } close(SEC); return @rv; } # create_secret(&secret) sub create_secret { open(SEC, ">>$config{'pap_file'}"); print SEC &join_words($_[0]->{'client'}, $_[0]->{'server'}, $_[0]->{'secret'}, @{$_[0]->{'ips'}}),"\n"; close(SEC); } # change_secret(&secret) sub change_secret { &replace_file_line($config{'pap_file'}, $_[0]->{'line'}, &join_words($_[0]->{'client'}, $_[0]->{'server'}, $_[0]->{'secret'}, @{$_[0]->{'ips'}})."\n"); } # delete_secret(&secret) sub delete_secret { &replace_file_line($config{'pap_file'}, $_[0]->{'line'}); } # split_words(string) sub split_words { local($s, @w); $s = $_[0]; while($s =~ /^\s*([^"\s]+|"([^"]*)")(.*)$/) { push(@w, defined($2) ? $2 : $1); $s = $3; } return @w; } sub join_words { local(@w, $w); foreach $w (@_) { if ($w =~ /^\S+$/) { push(@w, $w); } else { push(@w, "\"$w\""); } } return join(" ", @w); } # opt_crypt(password) # Returns the given password, crypted if the user has configured it sub opt_crypt { if ($config{'encrypt_pass'}) { local($salt); srand(time()); $salt = chr(int(rand(26))+65).chr(int(rand(26))+65); return crypt($_[0], $salt); } return $_[0]; } pptp-client/pptp-client-lib.pl0100664000567100000120000001411407701233275016347 0ustar jcameronwheel# pptp-client-lib.pl # XXX help page do '../web-lib.pl'; &init_config(); do 'secrets-lib.pl'; # list_tunnels() # Returns a list of the details of configured tunnels, in the format used # by the pptp-command script sub list_tunnels { local ($f, @rv); opendir(DIR, $config{'peers_dir'}); while($f = readdir(DIR)) { next if ($f =~ /^\./ || $f eq "__default"); local @opts = &parse_ppp_options("$config{'peers_dir'}/$f"); local ($pptp) = grep { $_->{'comment'} =~ /^PPTP/ } @opts; if ($pptp) { # Is a tunnel config .. add it push(@rv, { 'name' => $f, 'file' => "$config{'peers_dir'}/$f", 'opts' => \@opts }); } } closedir(DIR); return @rv; } # parse_ppp_options(file) sub parse_ppp_options { local @rv; local $lnum = 0; open(OPTS, $_[0]); while() { s/\r|\n//g; if (/^#\s*(.*)/) { # A comment, used to store meta-information push(@rv, { 'comment' => $1, 'file' => $_[0], 'line' => $lnum, 'index' => scalar(@rv) }); } elsif (/^([0-9\.]+):([0-9\.]+)/) { # A local/remote IP specification push(@rv, { 'local' => $1, 'remote' => $2, 'file' => $_[0], 'line' => $lnum, 'index' => scalar(@rv) }); } elsif (/^([^# ]*)\s*([^#]*)/) { # A PPP options directive push(@rv, { 'name' => $1, 'value' => $2, 'file' => $_[0], 'line' => $lnum, 'index' => scalar(@rv) }); } $lnum++; } close(OPTS); return @rv; } # find(name, &config) sub find { local @rv = grep { lc($_->{'name'}) eq lc($_[0]) } @{$_[1]}; return wantarray ? @rv : $rv[0]; } # save_ppp_option(&config, file, &old|name, &new) sub save_ppp_option { local $ol = ref($_[2]) || !defined($_[2]) ? $_[2] : &find($_[2], $_[0]); local $nw = $_[3]; local $lref = &read_file_lines($_[1]); local $line; if ($nw) { if ($nw->{'local'}) { $line = $nw->{'local'}.":".$nw->{'remote'}; } elsif ($nw->{'comment'}) { $line = "# ".$nw->{'comment'}; } else { $line = $nw->{'name'}; $line .= " $nw->{'value'}" if ($nw->{'value'} ne ""); } } if ($ol && $nw) { $lref->[$ol->{'line'}] = $line; } elsif ($ol) { splice(@$lref, $ol->{'line'}, 1); local $c; foreach $c (@{$_[0]}) { $c->{'line'}-- if ($c->{'line'} > $ol->{'line'}); } } elsif ($nw) { push(@$lref, $line); } } # list_connected() # Returns a list of the names of tunnels that appear to be active. May include # other ppp calls as well sub list_connected { &foreign_require("proc", "proc-lib.pl"); local @rv; foreach $p (&proc::list_processes()) { if ($p->{'args'} =~ /pppd\s.*call\s+(.*\S+)/) { push(@rv, [ $1, $p->{'pid'} ]); } } return @rv; } # parse_comments(&tunnel) sub parse_comments { foreach $c (@{$_[0]->{'opts'}}) { if ($c->{'comment'} =~ /Server IP: (\S+)/) { $_[0]->{'server'} = $1; $_[0]->{'server_c'} = $c; } elsif ($c->{'comment'} =~ /Route: (.*)/) { push(@{$_[0]->{'routes'}}, $1); push(@{$_[0]->{'routes_c'}}, $c); } } } @old_mppe = ( 'mppe-40', 'mppe-128', 'mppe-stateless' ); @new_mppe = ( [ 'mppe', 0 ], [ 'mppe-40', 1 ], [ 'mppe-128', 1 ], [ 'mppe-stateful', 0 ] ); # mppe_options_form(&opts) # Show a form for editing MPPE-related PPP options sub mppe_options_form { # Get the PPPd version. Only those above 2.4.2 have built-in MPPE support local $out = `pppd --help 2>&1`; local $mppe_mode = &mppe_support(); print "\n"; local $opts = $_[0]; if ($mppe_mode) { # Show new MPPE options local $o; foreach $o (@new_mppe) { local $o0 = &find("require-".$o->[0], $opts); local $o1 = &find("no".$o->[0], $opts); local $mode = $o0 ? 2 : $o1 ? 0 : 1; print " ",$text{'mppe_'.$o->[0]},"\n"; print "\n"; printf " %s\n", $o->[0], $mode == 2 ? "checked" : "", $text{'mppe_m2'}; printf " %s (%s)\n", $o->[0], $mode == 1 ? "checked" : "", $text{'default'}, $o->[1] ? $text{'mppe_d1'} : $text{'mppe_d0'}; printf " %s\n", $o->[0], $mode == 0 ? "checked" : "", $text{'mppe_m0'}; print " \n"; } local @anyold = grep { &find($_, $opts) } @old_mppe; if (@anyold) { print " ",&text('mppe_old', "".join(" ", @anyold)."")," \n"; } } else { # Show old MPPE options $i = 0; foreach $o (@old_mppe) { print "\n" if ($i%2 == 0); local $v = &find($o, $opts); print "",$text{'mppe_'.$o}," \n"; printf " %s\n", $v ? "checked" : "", $text{'yes'}; printf " %s\n", $v ? "" : "checked", $text{'no'}; print "\n" if ($i%2 == 1); $i++; } local @anynew = grep { &find($_, $opts) } ( map { 'require-'.$_->[0] } @new_mppe ), ( map { 'no'.$_->[0] } @new_mppe ); if (@anynew) { print " ",&text('mppe_new', "".join(" ", @anynew)."")," \n"; } print "\n"; } } # parse_mppe_options(&config, file) sub parse_mppe_options { local $o; if ($in{'mppe_mode'}) { # Parse new-style options foreach $o (map { $_->[0] } @new_mppe) { if ($in{$o} == 2) { &save_ppp_option($_[0], $_[1], "require-$o", { 'name' => "require-$o" }); &save_ppp_option($_[0], $_[1], "no$o", undef); } elsif ($in{$o} == 1) { &save_ppp_option($_[0], $_[1], "require-$o", undef); &save_ppp_option($_[0], $_[1], "no$o", undef); } else { &save_ppp_option($_[0], $_[1], "require-$o", undef); &save_ppp_option($_[0], $_[1], "no$o", { 'name' => "no$o" }); } } } else { # Parse old-style options foreach $o (@old_mppe) { &save_ppp_option($_[0], $_[1], $o, $in{$o} ? { 'name' => $o } : undef); } } } # mppe_support() # Returns 1 if the PPP daemon supports new-style MPPE options (version 2.4.2+, # 0 if might only support the old options) sub mppe_support { local $out = `pppd --help 2>&1`; local $vers; if ($out =~ /version\s+(\S+)/i) { $vers = $1; } if ($vers =~ /^(\d+)/ && $1 > 2 || $vers =~ /^(\d+)\.(\d+)/ && $1 == 2 && $2 > 4 || $vers =~ /^(\d+)\.(\d+)\.(\d+)/ && $1 == 2 && $2 == 4 && $3 >= 2) { return 1; } return 0; } 1; pptp-client/lang/0040775000567100000120000000000007701233275013732 5ustar jcameronwheelpptp-client/lang/ca0100755000567100000120000001256707701233275014251 0ustar jcameronwheelindex_title=Client VPN PPTP index_epptp=No s'ha trobat al sistema el programa client PPTP $1. Pot ser que no estigui installat, o b que la configuraci del mdul sigui incorrecta. index_eppp=El programa servidor PPP $1 no est installat al sistema. PPTP en depn per poder operar. index_eoptions=El fitxer d'opcions globals PPP de PPTP $1 no existeix. Crea'l o b canvia la configuraci del mdul per fer servir un fitxer diferent o cap en absolut. index_header=Tnels Definits index_none=Encara no s'ha definit cap tnel PPTP. index_tunnel=Tnel $1 index_add=Afegeix un nou tnel VPN PPTP. index_conn=Connecta't a: index_conndesc=Fes clic sobre aquest bot per connectar amb el tnel VPN PPTP seleccionat utilitzant la seva configuraci actual. index_disc=Desconnecta't de: index_discdesc=Fes clic sobre aquest bot per desconnectar el tnel VPN PPTP actiu seleccionat i treure totes les rutes que hi passen. index_return=a la llista de PPTP tunnel list index_opts=Edita les Opcions Globals PPP index_optsdesc=Fes clic sobre aquest bot per editar les opcions PPP que s'apliquen a tots els tnelsVPN PPTP. index_version=PPPd versi $1 disc_err=No he pogut desconnectar el tnel disc_egone=Ja no est actiu disc_ekill=No he pogut matar el procs conn_err=No he pogut connectar amb el tnel conn_egone=El tnel ja no existeix cone_ealready=Aa est connectat conn_einvalid=Hi falta l'adrea IP del servidor al fitxer de configuraci conn_title=Connexi al Tnel conn_cmd=Establint una connexi PPTP amb l'ordre $1... conn_ok=...connexi activada amb xit utilitzant la interfcie $1. La teva adrea local s $2, i l'adrea remota s $3. conn_timeout=...la connexi ha fallat! Mira els missatges de registre ms avall per saber-ne el perqu. conn_routes=Afegint rutes amb ordres... conn_mppe=El protocol MPPE per a xifratge VPN necessita el dimoni PPP i suport del kernel. No obstant, l'error de ms amunt suggereix que un dels dos o tots dos no estan disponibles al sistema. SI el servidorPPTP no exigeix MPPE, prova de desactivar totes les opcions relacionades a la pgina d'Opcions Globals PPP page. edit_title1=Addici de Tnel PPTP edit_title2=Edici de Tnel PPTP edit_header=Opcions del tnel VPN PPTP edit_name=Nom del tnel edit_server=Connecta't al servidor edit_login=Entra com a usuari edit_same=Nom de host del sistema edit_pass=Entra amb la contrasenya edit_remote=Nom del servidor edit_auto=Automtic edit_adddef=Afegeix ruta per defect edit_def1=A travs d'un altre lloc edit_def2=A travs del portal edit_deldef=Suprimeix la ruta per defecte anterior edit_routes=Rutes a afegir desprs de connectar edit_type=Tipus edit_type0=  edit_type1=Xarxa edit_type2=Host edit_net=Xarxa o host edit_mask=Mscara de subxarxa edit_gw=A travs del portal edit_gw_def=Un altre lloc edit_unknown=Altres ordres route edit_file=Fitxer d'opcions PPP edit_none=Cap edit_global=Fitxer global estndard edit_ofile=Un altre fitxer... save_err=No he pogut desar el nom del tnel save_ename=Hi falta tunnel name save_eserver=Hi falta el servidor a connectar o b s invlid save_elogin=Hi falta el nom d'usuari o b s invlid save_eremote=Hi falta el nom del servidor remot o b s invlid save_edef=Hi falta el portal de la ruta per defecte o b s invlid save_enet=Adrea de xarxa invlida a la ruta $1 save_emask=Mscara de subxarxa invlida a la ruta $1 save_egw=Portal invlid per a la xarxa a la ruta $1 save_ehost=Adrea IP del host invlida a la ruta $1 save_emask2=No cal mscara per a la ruta del host $1 save_egw2=Portal del host invlid a la ruta $1 save_erename=No he pogut renomenar el fitxer del tnel save_eclash=Ja existeix un tnel o un peer PPP amb el mateix nom save_efile=Hi falta el fitxer d'opcions PPP o b s invlid opts_title=Opcions Globals del PPP opts_desc=Els valors de sota es prenen de $1, i s'aplicaran a tots els tnels que es configurin per a fer servir el fitxer estndard'opcions globals del PPP. opts_header=Opcions PPP per a tots els tnels opts_mtu=Mida mxima dels paquets enviats opts_mru=Mida mxima dels paquets opts_err=No he pogut desar les opcions globals del PPP opts_emtu=Hi falta la mida mxima dels paquets enviats o b s invlida opts_emru=Hi falta la mida mxima dels paquets rebuts o b s invlida opts_msdesc=Les opcions de sota activen el xifratge MPPE, utilitzat pels servidors VPN de Windows. No obstant, MPPE necessita suport tant al dimoni PPP com al kernel del sistema operatiu. mppe_mppe-40=Fes servir xifratge MPPE de 40 bits mppe_mppe-128=Fes servir xifratge MPPE de 128 bits mppe_mppe-stateless=Activa el mode MPPE snse estat mppe_mppe=Activa el xifratge MPPE mppe_m2=Cal utilitzar-lo mppe_m0=No es pot utilitzar mppe_d0=Desactivat mppe_d1=Perms mppe_mppe-stateful=Activa el mode MPPE amb estat mppe_old=Atenci - S'han trobat les directives MPPE d'estil antic $1 al fitxer de configuraci, tot i que el dimoni PPP suporta les directives d'estil nou. mppe_new=Atenci - S'han trobat les directives MPPE d'estil nou $1 al fitxer de configuraci, tot i que el dimoni PPP noms suporta les directives d'estil antic. log_create=He creat el tnel PPTP $1 log_update=He modificat el tnel PPTP $1 log_delete=He suprimit el tnel PPTP $1 log_conn=He connectat el tnel $1 log_conn_l=He connectat el tnel $1 amb l'adrea local $2 log_failed=No he pogut connectar el tnel $1 log_disc=He desconnectat el tnel $1 log_opts=He editat les opcions globals del PPP pptp-client/lang/en0100664000567100000120000001150207701233275014253 0ustar jcameronwheelindex_title=PPTP VPN Client index_epptp=The PPTP client program $1 was not found on your system. Maybe it is not installed, or your module configuration is incorrect. index_eppp=The PPP server program $1 is not installed on your system. The PPTP depends upon it to operate. index_eoptions=The global PPTP PPP options file $1 does not exist. Either create it, or adjust the module configuration to use a different file, or none at all. index_header=Defined Tunnels index_none=No PPTP tunnels have been defined yet. index_tunnel=Tunnel $1 index_add=Add a new PPTP VPN tunnel. index_conn=Connect to: index_conndesc=Click this button to connect the selected PPTP VPN tunnel using its current configuration. index_disc=Disconnect from: index_discdesc=Click this button to disconnect the selected currently active PPTP VPN tunnel and remove all routes through it. index_return=PPTP tunnel list index_opts=Edit Global PPP Options index_optsdesc=Click this button to edit the PPP options that apply to all PPTP VPN tunnels. index_version=PPPd version $1 disc_err=Failed to disconnect tunnel disc_egone=No longer active disc_ekill=Failed to kill pppd process conn_err=Failed to connect tunnel conn_egone=Tunnel no longer exists cone_ealready=Already connected conn_einvalid=Missing server IP address in configuration file conn_title=Connecting Tunnel conn_cmd=Establishing a PPTP connection with the command $1 .. conn_ok=.. connection successfully activated using interface $1. Your local address is $2, and the remote address is $3. conn_timeout=.. connection failed! Check the log messages below for information why. conn_routes=Adding routes with commands .. conn_mppe=The MPPE protocol for VPN encryption requires PPP daemon and kernel support. However, the errors above suggest that one or both are not available on your system. If the PPTP server does not require MPPE, try turning off all options related to it on the global PPP options page. edit_title1=Add PPTP Tunnel edit_title2=Edit PPTP Tunnel edit_header=PPTP VPN tunnel options edit_name=Tunnel name edit_server=Connect to server edit_login=Login as user edit_same=System hostname edit_pass=Login with password edit_remote=Server's name edit_auto=Automatic edit_adddef=Add default route? edit_def1=Via other end edit_def2=Via gateway .. edit_deldef=Delete old default route? edit_routes=Routes to add after connecting edit_type=Type edit_type0=  edit_type1=Network edit_type2=Single host edit_net=Network or host edit_mask=Netmask edit_gw=Via gateway edit_gw_def=Other end edit_unknown=Other route commands edit_file=PPP options file edit_none=None edit_global=Standard global file edit_ofile=Other file .. save_err=Failed to save tunnel save_ename=Missing tunnel name save_eserver=Missing or invalid server to connect to save_elogin=Missing or invalid login name save_eremote=Missing or invalid remote server's name save_edef=Missing or invalid default route gateway save_enet=Invalid network address in route $1 save_emask=Invalid netmask in route $1 save_egw=Invalid gateway for network in route $1 save_ehost=Invalid host IP address in route $1 save_emask2=No netmask needed for host route $1 save_egw2=Invalid gateway for host in route $1 save_erename=Failed to re-name tunnel file save_eclash=A tunnel or PPP peer with the same name already exists save_efile=Missing or invalid PPP options file opts_title=Global PPP Options opts_desc=The settings below are taken from $1, and will apply to all tunnels that are set to use standard global PPP options file. opts_header=PPP options for all tunnels opts_mtu=Maximum sending packet size opts_mru=Maximum receiving packet size opts_err=Failed to save global PPP options opts_emtu=Missing or invalid maximum sending packet size opts_emru=Missing or invalid maximum receiving packet size opts_msdesc=The options below enable MPPE encryption, used by by Windows VPN servers. However, MPPE requires support in both the PPP daemon and operating system kernel. mppe_mppe-40=Use 40-bit MPPE encryption? mppe_mppe-128=Use 128-bit MPPE encryption? mppe_mppe-stateless=Enable stateless MPPE mode? mppe_mppe=Enable MPPE encryption? mppe_m2=Must be used mppe_m0=Cannot be used mppe_d0=Disabled mppe_d1=Allowed mppe_mppe-stateful=Enable stateful MPPE mode? mppe_old=Warning - The old-style MPPE directives $1 were found in your configuration file, even though your PPP daemon supports the new-style directives. mppe_new=Warning - The new-style MPPE directives $1 were found in your configuration file, even though your PPP daemon only supports the old-style directives. log_create=Created PPTP tunnel $1 log_update=Modified PPTP tunnel $1 log_delete=Deleted PPTP tunnel $1 log_conn=Connected tunnel $1 log_conn_l=Connected tunnel $1 with local address $2 log_failed=Failed to connect tunnel $1 log_disc=Disconnected tunnel $1 log_opts=Edited global PPP options pptp-client/help/0040775000567100000120000000000007701233275013741 5ustar jcameronwheelpptp-client/help/intro.ca.html0100755000567100000120000000265607701233275016353 0ustar jcameronwheel
Client VPN PPTP
Aquest mdul permet crear connexions VPN amb altres servidors que utilitzin el protocol PPTP. El mdul empra el programa client PPTP estndard de Linux i el dimoni PPP. Els servidors remots han d'estar executant un dimoni PPTP, que es pot configurar amb el mdul Servidor VPN PPTP de Webmin.

Es poden definir mltiples tnels, cadascun dels quals ha de tenir un servidor remot per connectar-hi, un nom d'usuari i una contrasenya. Un tnel tamb pot tenir rutes esttiques associades per activar-les quan es fa la connexi. Per defecte, noms es crea una ruta cap al servidor de l'altre extrem del tnel quan s'activa la connexi.

Un cop s'ha creat un tnel, es pot activar fent servir el bot Connecta't a del peu de la pgina principal. Pot haver-hi qualsevol nombre de tnels activats en qualsevol moment, i els que estan actius es poden tancar amb el bot Desconnectat de.

A la pgina principal tamb hi ha el bot Edita les Opcions Globals PPP per editar els valors que s'apliquen a tots els tnels. Els ms importants sn aquells relacionats amb MPPE, un protocol de xifratge utilitzat pels servidors VPN de Microsoft per assegurar les connexions PPTP. No obstant, per tal que MPPE funcioni, cal suport tant al dimoni PPP com al kernel del sistema. Les versions de PPPd 2.4.2 en amunt suporten MPPE nativament, i tamb hi ha un peda per a versions ms velles.


pptp-client/help/intro.html0100664000567100000120000000247007701233275015762 0ustar jcameronwheel
PPTP VPN Client
This module allows you to create VPN connections to other servers using the PPTP protocol. The module makes use of the standard Linux PPTP client program, and the PPP daemon. Remote servers must be running a PPTP daemon, which can be configured using Webmin's PPTP VPN Server module.

Multiple tunnels may be defined, each of which must have a remote server to connect to, a login name and a password. A tunnel can also have several associated static routes, to be brought up when it is connected. By default, only a route to the server at the other end of the tunnel is created when it is activated.

Once a tunnel has been created, it can be activated using the Connect to button at the bottom of the main page. Multiple tunnels can be active at any one time, and those that are active can be shut down with the Disconnect from button.

Also on the main page is the Edit Global PPP Options button for editing settings that apply to all tunnels. The most important are those related to MPPE, an encryption protocol using by Microsoft VPN servers to secure PPTP connections. However, support in both the PPP daemon and the kernel is needed for MPPE to work. PPPd versions 2.4.2 and above support MPPE natively, and a patch exists for older versions as well.


pptp-client/config.info0100664000567100000120000000042207701233275015126 0ustar jcameronwheelline1=Configurable options,11 timeout=Time to wait for tunnel to connect,0,5 line2=System configuration,11 pptp=Full path to PPTP client program,0 peers_dir=Directory containing PPP connection files,0 pap_file=PPP accounts file,0 pptp_options=Global PPTP PPP options file,0 pptp-client/config0100664000567100000120000000016007701233275014173 0ustar jcameronwheeltimeout=30 pptp=pptp peers_dir=/etc/ppp/peers pap_file=/etc/ppp/chap-secrets pptp_options=/etc/ppp/options.pptp pptp-client/index.cgi0100775000567100000120000000522707701233275014612 0ustar jcameronwheel#!/usr/local/bin/perl # index.cgi # Display icons for defined PPTP tunnels require './pptp-client-lib.pl'; # Get PPPd version $out = `pppd --help 2>&1`; if ($out =~ /version\s+(\S+)/i) { $vers = $1; } &header($text{'index_title'}, undef, "intro", 1, 1, 0, undef, undef, undef, $vers ? &text('index_version', $vers) : undef); print "
\n"; # Create the PPTP options file if non-existent. This ensures that it can be # used in the peer scripts, even if it is empty if (!-r $config{'pptp_options'}) { open(OPTS, ">>$config{'pptp_options'}"); close(OPTS); } if (!&has_command($config{'pptp'})) { # The PPTP command is not installed print "

",&text('index_epptp', "$config{'pptp'}", "$gconfig{'webprefix'}/config.cgi?$module_name"),"

\n"; } elsif (!$vers) { # The PPP daemon is not installed print "

",&text('index_epppd', "pppd"),"

\n"; } else { # Show icons @tunnels = &list_tunnels(); %tunnels = map { $_->{'name'}, 1 } @tunnels; #print "

$text{'index_header'}

\n"; if (@tunnels) { @links = map { "edit.cgi?tunnel=$_->{'name'}" } @tunnels; @titles = map { $_->{'name'} } @tunnels; @icons = map { "images/tunnel.gif" } @tunnels; &icons_table(\@links, \@titles, \@icons); } else { print "$text{'index_none'}

\n"; } print "$text{'index_add'}

\n"; print "


\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "\n"; @conns = grep { $tunnels{$_->[0]} } &list_connected(); %conns = map { @$_ } @conns; @notconns = grep { !$conns{$_->{'name'}} } @tunnels; if (@notconns) { # Show connect button, if any are disconnected print "\n"; print "\n"; } if (@conns) { # If any tunnels appear to be active, show disconnect button print "\n"; print "\n"; } print "
$text{'index_optsdesc'}
\n"; print "\n"; print "$text{'index_conndesc'}
\n"; print "\n"; print "$text{'index_discdesc'}
\n"; } print "
\n"; &footer("/", $text{'index'}); pptp-client/module.info0100664000567100000120000000033107701233277015147 0ustar jcameronwheelcategory=net longdesc=Configure and establish connections to a VPN server using the PPTP protocol. os_support=*-linux desc=PPTP VPN Client name=PPTP depends=net proc syslog 1.100 version=1.100 desc_ca=Client VPN PPTP pptp-client/edit_opts.cgi0100775000567100000120000000270607701233275015474 0ustar jcameronwheel#!/usr/local/bin/perl # edit_opts.cgi # Display PPP options for all connections require './pptp-client-lib.pl'; &header($text{'opts_title'}, ""); print "
\n"; print &text('opts_desc', "$config{'pptp_options'}"),"
\n"; @opts = &parse_ppp_options($config{'pptp_options'}); print "
\n"; print "\n"; print "\n"; print "
$text{'opts_header'}
\n"; $mtu = &find("mtu", \@opts); printf "\n"; $mru = &find("mru", \@opts); printf "\n"; print "\n"; print "\n"; # Show MPPE options &mppe_options_form(\@opts); print "
$text{'opts_mtu'} \n"; printf " %s\n", $mtu ? "" : "checked", $text{'default'}; printf "\n", $mtu ? "checked" : ""; print " bytes$text{'opts_mru'} \n"; printf " %s\n", $mru ? "" : "checked", $text{'default'}; printf "\n", $mru ? "checked" : ""; print " bytes

$text{'opts_msdesc'}
\n"; print "
\n"; print "
\n"; &footer("", $text{'index_return'}); pptp-client/disc.cgi0100775000567100000120000000060707701233275014422 0ustar jcameronwheel#!/usr/local/bin/perl # disc.cgi # Shut down a PPTP tunnel require './pptp-client-lib.pl'; &ReadParse(); &error_setup($text{'disc_err'}); @conns = &list_connected(); ($conn) = grep { $_->[0] eq $in{'tunnel'} } @conns; $conn || &error($text{'disc_egone'}); &kill_logged('HUP', $conn->[1]) || &error($text{'disc_ekill'}); &webmin_log("disc", undef, $in{'tunnel'}); sleep(3); &redirect(""); pptp-client/conn.cgi0100775000567100000120000000621007701233275014431 0ustar jcameronwheel#!/usr/local/bin/perl # conn.cgi # Open a PPTP connection and add its routes require './pptp-client-lib.pl'; &foreign_require("net", "net-lib.pl"); &error_setup($text{'conn_err'}); &ReadParse(); # Get tunnel details @tunnels = &list_tunnels(); ($tunnel) = grep { $_->{'name'} eq $in{'tunnel'} } @tunnels; $tunnel || &error($text{'conn_egone'}); &parse_comments($tunnel); $tunnel->{'server'} || &error($text{'conn_einvalid'}); # Check if it is already active @conns = &list_connected(); ($conn) = grep { $_->[0] eq $in{'tunnel'} } @conns; $conn && &error($text{'conn_ealready'}); $theme_no_table++; $| = 1; &header($text{'conn_title'}, ""); print "
\n"; print "

",&text('conn_cmd', "$config{'pptp'} $tunnel->{'server'} ". "call $in{'tunnel'}"),"

\n"; # Run the PPTP command, and wait for a new pppN interface to come up %sifaces = map { $_->{'fullname'}, $_->{'address'} } &get_ppp_ifaces(); $start = time(); &system_logged("modprobe ip_gre >/dev/null 2>&1"); &system_logged("$config{'pptp'} ".quotemeta($tunnel->{'server'})." call ". quotemeta($in{'tunnel'})." >/dev/null 2>&1 {'fullname'}}) { $newiface = $i; last LOOP; } } } # Find out if we were connected, or if it failed if ($newiface) { # It worked! Tell the user, and add the routes print "",&text('conn_ok', "$newiface->{'fullname'}", "$newiface->{'address'}", "$newiface->{'ptp'}"),"

\n"; if (@{$tunnel->{'routes'}}) { @routes = &net::list_routes(); ($defroute) = grep { $_->{'dest'} eq '0.0.0.0' } @routes; $oldgw = $defroute->{'gateway'} if ($defroute); print "$text{'conn_routes'}

\n";
		foreach $r (@{$tunnel->{'routes'}}) {
			$cmd = "route $r";
			$cmd =~ s/TUNNEL_DEV/$newiface->{'fullname'}/g;
			$cmd =~ s/DEF_GW/$oldgw/g;
			$cmd =~ s/GW/$newiface->{'ptp'}/g;
			print $cmd,"\n";
			$out = &backquote_logged("$cmd 2>&1 $out";
			}
		print "
\n"; } } else { # Must have timed out due to a failure print "$text{'conn_timeout'}

\n"; &foreign_require("syslog", "syslog-lib.pl"); $sysconf = &syslog::get_config(); foreach $c (@$sysconf) { next if ($c->{'tag'} || !$c->{'file'} || !-f $c->{'file'}); local @st = stat($c->{'file'}); if ($st[9] > $start) { # Was modified since start .. but by ppp or pptp? $tail = `tail -10 '$c->{'file'}'`; if ($tail =~ /ppp|pptp/) { $logs = $tail; last; } } } print "

$logs
\n"; if ($logs =~ /mppe/) { print "",&text('conn_mppe', "edit_opts.cgi"),"

\n"; } } # Save tunnel as default &lock_file("$module_config_directory/config"); $config{'tunnel'} = $in{'tunnel'}; &write_file("$module_config_directory/config", \%config); &unlock_file("$module_config_directory/config"); &webmin_log("conn", undef, $in{'tunnel'}, $newiface); print "


\n"; &footer("", $text{'index_return'}); sub get_ppp_ifaces { return grep { $_->{'fullname'} =~ /^ppp(\d+)$/ && $_->{'up'} && $_->{'address'} } &net::active_interfaces(); } pptp-client/edit.cgi0100775000567100000120000001512107701233275014422 0ustar jcameronwheel#!/usr/local/bin/perl # edit.cgi # Display a form for editing tunnel details require './pptp-client-lib.pl'; &ReadParse(); if ($in{'new'}) { &header($text{'edit_title1'}, ""); } else { &header($text{'edit_title2'}, ""); ($tunnel) = grep { $_->{'name'} eq $in{'tunnel'} } &list_tunnels(); &parse_comments($tunnel); $login = &find("name", $tunnel->{'opts'}); $sn = $login ? $login->{'value'} : &get_system_hostname(1); @secs = &list_secrets(); ($sec) = grep { $_->{'client'} eq $sn } @secs; } print "
\n"; print "
\n"; print "\n"; print "\n"; print "\n"; print "\n"; print "
$text{'edit_header'}
\n"; print "\n"; printf "\n", $tunnel->{'name'}; print "\n"; printf "\n", $tunnel->{'server'}; print "\n"; printf "\n", $login->{'value'}; print "\n"; printf "\n", $sec->{'secret'}; $remote = &find("remotename", $tunnel->{'opts'}); print "\n"; printf "\n", $remote->{'value'}; print "\n"; # Show PPP include file $file = &find("file", $tunnel->{'opts'}); $fmode = $in{'new'} ? 1 : !$file ? 0 : $file->{'value'} eq $config{'pptp_options'} ? 1 : 2; print "\n", $fmode == 2 ? $file->{'value'} : "", &file_chooser_button("file"); print "\n"; # Parse all route comments foreach $r (@{$tunnel->{'routes'}}) { if ($r =~ /^\s*add\s+-net\s+(\S+)\s+netmask\s+(\S+)\s+gw\s+(\S+)\s*$/) { # Net route to specific gateway push(@kroutes, [ 1, $1, $2, $3 ]); } elsif ($r =~ /^\s*add\s+-net\s+(\S+)\s+gw\s+(\S+)\s+netmask\s+(\S+)\s*$/) { # Net route to specific gateway push(@kroutes, [ 1, $1, $3, $2 ]); } elsif ($r =~ /^\s*add\s+-net\s+(\S+)\s+netmask\s+(\S+)\s+dev\s+(TUNNEL_DEV)\s*$/) { # Net route to other end push(@kroutes, [ 1, $1, $2, 'GW' ]); } elsif ($r =~ /^\s*add\s+-net\s+(\S+)\s+dev\s+(TUNNEL_DEV)\s+netmask\s+(\S+)\s*$/) { # Net route to other end push(@kroutes, [ 1, $1, $3, 'GW' ]); } elsif ($r =~ /^\s*add\s+-host\s+(\S+)\s+gw\s+(\S+)\s*$/) { # Host route to specific gateway push(@kroutes, [ 2, $1, undef, $2 ]); } elsif ($r =~ /^\s*add\s+-host\s+(\S+)\s+dev\s+(TUNNEL_DEV)\s*$/) { # Host route to specific gateway push(@kroutes, [ 2, $1, undef, 'GW' ]); } elsif ($r =~ /^\s*add\s+default\s+gw\s+(\S+)\s*$/) { # Default route to specific gateway $adddef = $1; } elsif ($r =~ /^\s*add\s+default\s+dev\s+(TUNNEL_DEV)\s*$/) { # Default route to other end $adddef = 'GW'; } elsif ($r =~ /^\s*delete\s+default\s*$/) { # Deleting old default route $deldef = 1; } else { push(@uroutes, $r); } } # Show default route options print "\n"; print "\n"; printf "\n", $deldef ? "" : "checked", $text{'no'}; # Show editable routes print "\n"; print "\n"; # Show other route commands print "\n"; print "\n"; print "\n"; # Show MPPE options print "\n"; &mppe_options_form($tunnel->{'opts'}); print "
$text{'edit_name'}$text{'edit_server'}
$text{'edit_login'} %s\n", $login ? "" : "checked", $text{'edit_same'}; printf "\n", $login ? "checked" : ""; printf "$text{'edit_pass'}
$text{'edit_remote'} %s\n", $remote ? "" : "checked", $text{'edit_auto'}; printf "\n", $remote ? "checked" : ""; printf "
$text{'edit_file'} \n"; printf " %s\n", $fmode == 0 ? "checked" : "", $text{'edit_none'}; printf " %s\n", $fmode == 1 ? "checked" : "", $text{'edit_global'}; printf " %s\n", $fmode == 2 ? "checked" : "", $text{'edit_ofile'}; printf " %s

$text{'edit_adddef'} \n"; printf " %s\n", $adddef eq "GW" ? "checked" : "", $text{'edit_def1'}; printf " %s\n", $adddef && $adddef ne "GW" ? "checked" : "", $text{'edit_def2'}; printf "\n", $adddef eq "GW" ? "" : $adddef; printf " %s\n", $adddef ? "" : "checked", $text{'no'}; print "
$text{'edit_deldef'} %s\n", $deldef ? "checked" : "", $text{'yes'}; printf " %s
$text{'edit_routes'}\n"; print " ", " ", " ", "\n"; $i = 0; foreach $r (@kroutes, [ 0, undef, undef, 'GW' ]) { print "\n"; print "\n"; print "\n"; print "\n"; printf "\n", $r->[3] eq 'GW' ? "" : $r->[3]; print "\n"; $i++; } print "
$text{'edit_type'}$text{'edit_net'}$text{'edit_mask'}$text{'edit_gw'}
%s\n", $r->[3] eq 'GW' ? "checked" : "", $text{'edit_gw_def'}; printf "\n", $r->[3] eq 'GW' ? "" : "checked"; printf "
$text{'edit_unknown'}

$text{'opts_msdesc'}
\n"; print "\n"; if ($in{'new'}) { print "\n"; } else { print "\n"; print "\n"; } print "
\n"; print "
\n"; &footer("", $text{'index_return'}); pptp-client/save.cgi0100775000567100000120000001334507701233275014441 0ustar jcameronwheel#!/usr/local/bin/perl # save.cgi # Create, update or delete a PPTP tunnel require './pptp-client-lib.pl'; &ReadParse(); @tunnels = &list_tunnels(); @secs = &list_secrets(); if (!$in{'new'}) { ($tunnel) = grep { $_->{'name'} eq $in{'old'} } @tunnels; &parse_comments($tunnel); $name = &find("name", $tunnel->{'opts'}); $remote = &find("remotename", $tunnel->{'opts'}); $sec = &find_secret($name ? $name->{'value'} : &get_system_hostname(1), $remote ? $remote->{'value'} : undef); &lock_file($tunnel->{'file'}); } else { $tunnel = { 'opts' => [ ] }; } &error_setup($text{'save_err'}); &lock_file($config{'pap_file'}); if ($in{'delete'}) { # Just delete this tunnel and it's secret (if not used by any other) unlink($tunnel->{'file'}); } else { # Validate inputs $in{'tunnel'} =~ /\S/ || &error($text{'save_ename'}); gethostbyname($in{'server'}) || &error($text{'save_eserver'}); $in{'login_def'} || $in{'login'} =~ /^\S+$/ || &error($text{'save_elogin'}); $in{'remote_def'} || $in{'remote'} =~ /^\S+$/ || &error($text{'save_eremote'}); $in{'file_def'} < 2 || -r $in{'file'} || &error($text{'save_efile'}); # Add default route changes if ($in{'deldef'}) { push(@routes, "delete default"); } if ($in{'adddef'} == 1) { push(@routes, "add default dev TUNNEL_DEV"); } elsif ($in{'adddef'} == 2) { gethostbyname($in{'def'}) || &error($text{'save_edef'}); push(@routes, "add default gw ".$in{'def'}); } # Parse and add extra route commands $in{'unknown'} =~ s/\r//g; push(@routes, grep { /\S/ } split(/\n/, $in{'unknown'})); # Parse and add static routes for($i=0; defined($t = $in{"type_$i"}); $i++) { next if (!$t); if ($t == 1) { &check_ipaddress($in{"net_$i"}) || &error(&text('save_enet', $i+1)); &check_ipaddress($in{"mask_$i"}) || &error(&text('save_emask', $i+1)); $in{"gw_def_$i"} || &check_ipaddress($in{"gw_$i"}) || &error(&text('save_egw', $i+1)); if ($in{"gw_def_$i"}) { push(@routes, sprintf("add -net %s dev %s netmask %s", $in{"net_$i"}, 'TUNNEL_DEV', $in{"mask_$i"})); } else { push(@routes, sprintf("add -net %s gw %s netmask %s", $in{"net_$i"}, $in{"gw_$i"}, $in{"mask_$i"})); } } else { &check_ipaddress($in{"net_$i"}) || &error(&text('save_ehost', $i+1)); $in{"mask_$i"} && &error(&text('save_emask2', $i+1)); $in{"gw_def_$i"} || &check_ipaddress($in{"gw_$i"}) || &error(&text('save_egw2', $i+1)); if ($in{"gw_def_$i"}) { push(@routes, sprintf("add -host %s dev %s", $in{"net_$i"}, 'TUNNEL_DEV')); } else { push(@routes, sprintf("add -host %s gw %s", $in{"net_$i"}, $in{"gw_$i"})); } } } mkdir($config{'peers_dir'}, 0755); if ($in{'new'}) { &check_clash(); # Create file and set default options $tunnel->{'name'} = $in{'tunnel'}; $tunnel->{'file'} = "$config{'peers_dir'}/$in{'tunnel'}"; &lock_file($tunnel->{'file'}); &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, undef, { 'comment' => "PPTP Tunnel configuration for tunnel $in{'tunnel'}" }); } else { # Check for a re-name if ($in{'tunnel'} ne $tunnel->{'name'}) { &check_clash(); $tunnel->{'name'} = $in{'tunnel'}; $nf = "$config{'peers_dir'}/$in{'tunnel'}"; rename($tunnel->{'file'}, $nf) || &error($text{'save_erename'}); $tunnel->{'file'} = $nf; } } # Save server IP &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, $tunnel->{'server_c'}, { 'comment' => "Server IP: $in{'server'}" } ); # Save all routes @or = @{$tunnel->{'routes_c'}}; for($i=0; $i<@routes || $i<@or; $i++) { &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, $or[$i], $routes[$i] ? { 'comment' => "Route: $routes[$i]" } : undef); } # Save PPP options &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, "name", $in{'login_def'} ? undef : { 'name' => 'name', 'value' => $in{'login'} } ); &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, "remotename", $in{'remote_def'} ? undef : { 'name' => 'remotename','value' => $in{'remote'} } ); &save_ppp_option($tunnel->{'opts'}, $tunnel->{'file'}, "file", $in{'file_def'} == 0 ? undef : $in{'file_def'} == 1 ? { 'name' => 'file', 'value' => $config{'pptp_options'} } : { 'name' => 'file', 'value' => $in{'file'} }); &parse_mppe_options($tunnel->{'opts'}, $tunnel->{'file'}); # Update or add to the secrets file $newname = $in{'login_def'} ? &get_system_hostname(1) : $in{'login'}; $newremote = $in{'remote_def'} ? "*" : $in{'remote'}; if (!$sec) { # No old secret was found, so look for one matching the new # details $sec = &find_secret($newname, $newremote); } if ($sec) { # Just update the secret for our login name with the new login # and password. This can happen when re-naming, or if a secret # for the name already exists $sec->{'client'} = $newname; if ($sec->{'server'} ne '*' && $newremote ne '*') { $sec->{'server'} = $newremote; } $sec->{'secret'} = $in{'pass'}; &change_secret($sec); } else { # Need to create a new secret $sec = { 'client' => $newname, 'secret' => $in{'pass'}, 'server' => $newremote }; &create_secret($sec); } &flush_file_lines(); } &unlock_file($tunnel->{'file'}); &unlock_file($config{'pap_file'}); &webmin_log($in{'new'} ? "create" : $in{'delete'} ? "delete" : "update", "tunnel", $tunnel->{'name'}); &redirect(""); sub check_clash { -r "$config{'peers_dir'}/$in{'tunnel'}" && &error($text{'save_eclash'}); } # find_secret(client, server) # Returns the best matching secret with the given details sub find_secret { local ($exact) = grep { $_->{'client'} eq $_[0] && $_->{'server'} eq $_[1] } @secs; return $exact if ($exact); local ($client) = grep { $_->{'client'} eq $_[0] } @secs; return $client; } pptp-client/log_parser.pl0100644000567100000120000000133507701233275015500 0ustar jcameronwheel# log_parser.pl # Functions for parsing this module's logs do 'pptp-client-lib.pl'; # parse_webmin_log(user, script, action, type, object, ¶ms) # Converts logged information from this module into human-readable form sub parse_webmin_log { local ($user, $script, $action, $type, $object, $p, $long) = @_; $object = "". &html_escape($object).""; if ($type eq 'tunnel') { return &text('log_'.$action, $object); } elsif ($action eq 'conn') { if ($p->{'address'}) { return &text($long ? 'log_conn_l' : 'log_conn', $object, $p->{'address'}); } else { return &text('log_failed', $object); } } elsif ($action eq 'disc') { return &text('log_disc', $object); } else { return $text{'log_'.$action}; } } pptp-client/save_opts.cgi0100775000567100000120000000162407701233275015503 0ustar jcameronwheel#!/usr/local/bin/perl # save_opts.cgi # Save global PPTP PPP options require './pptp-client-lib.pl'; &ReadParse(); &error_setup($text{'opts_err'}); &lock_file($config{'pptp_options'}); @opts = &parse_ppp_options($config{'pptp_options'}); if ($in{'mtu_def'}) { &save_ppp_option(\@opts, $config{'pptp_options'}, "mtu", undef); } else { $in{'mtu'} =~ /^\d+$/ || &error($text{'opts_emtu'}); &save_ppp_option(\@opts, $config{'pptp_options'}, "mtu", { 'name' => 'mtu', 'value' => $in{'mtu'} }); } if ($in{'mru_def'}) { &save_ppp_option(\@opts, $config{'pptp_options'}, "mru", undef); } else { $in{'mru'} =~ /^\d+$/ || &error($text{'opts_emru'}); &save_ppp_option(\@opts, $config{'pptp_options'}, "mru", { 'name' => 'mru', 'value' => $in{'mru'} }); } &parse_mppe_options(\@opts, $config{'pptp_options'}); &flush_file_lines(); &unlock_file($config{'pptp_options'}); &webmin_log("opts"); &redirect(""); pptp-client/config.info.ca0100755000567100000120000000046107701233275015514 0ustar jcameronwheelline1=Opcions configurables,11 timeout=Temps d'espera del tnel per a connectar,0,5 line2=Configuraci del sistema,11 pptp=Cam complet del programa client PPTP,0 peers_dir=Directori que cont els fitxers de connexi PPP,0 pap_file=Fitxer de comptes PPP,0 pptp_options=Fitxer d'opcions globals PPP PPTP,0