]> Cypherpunks.ru repositories - govpn.git/blob - src/cypherpunks.ru/govpn/action.go
Split too long lines
[govpn.git] / src / cypherpunks.ru / govpn / action.go
1 /*
2 GoVPN -- simple secure free software virtual private network daemon
3 Copyright (C) 2014-2017 Sergey Matveev <stargrave@stargrave.org>
4               2016-2017 Bruno Clermont <bruno@robotinfra.com>
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package govpn
21
22 import (
23         "os"
24         "os/exec"
25
26         "github.com/pkg/errors"
27 )
28
29 // PeerContext holds info about a peer that connect or disconnect
30 // used for Up, PreUp and Down
31 type PeerContext struct {
32         RemoteAddress string
33         Protocol      Protocol
34         Config        PeerConf
35 }
36
37 // TunnelAction is an action for either client or server that is
38 // executed when tunnel goes down
39 type TunnelAction func(PeerContext) error
40
41 // TunnelPreUpAction is an action for client or server that is executed
42 // after user is authenticated
43 type TunnelPreUpAction func(PeerContext) (*TAP, error)
44
45 // RunScriptAction converts the path to a script into a TunnelAction
46 func RunScriptAction(path *string) TunnelAction {
47         if path == nil {
48                 return nil
49         }
50         return func(ctx PeerContext) error {
51                 _, err := ScriptCall(*path, ctx.Config.Iface, ctx.RemoteAddress)
52                 return errors.Wrapf(
53                         err,
54                         "ScriptCall path=%q interface=%q remote=%q",
55                         *path,
56                         ctx.Config.Iface,
57                         ctx.RemoteAddress,
58                 )
59         }
60 }
61
62 // ScriptCall calls external program/script.
63 // You have to specify path to it and (inteface name as a rule) something
64 // that will be the first argument when calling it. Function will return
65 // it's output and possible error.
66 func ScriptCall(path, ifaceName, remoteAddr string) ([]byte, error) {
67         if path == "" {
68                 return nil, nil
69         }
70         if _, err := os.Stat(path); err != nil && os.IsNotExist(err) {
71                 return nil, errors.Wrap(err, "os.Path")
72         }
73         cmd := exec.Command(path)
74         cmd.Env = append(cmd.Env, environmentKeyInterface+"="+ifaceName)
75         cmd.Env = append(cmd.Env, environmentKeyRemote+"="+remoteAddr)
76         out, err := cmd.CombinedOutput()
77         return out, errors.Wrap(err, "cmd.CombinedOutput")
78 }