mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-06-04 10:48:17 +02:00
We no longer add these. If you use Emacs, configure it yourself.
Also, due to our "smart-tab" usage the editor anyway does a subpar
job handling our tabs. However, on the upside every user can choose
whatever tab-width he/she prefers. If "smart-tabs" are used properly
(like we do), every tab-width will work.
No manual changes, just ran commands:
F=($(git grep -l -e '-\*-'))
sed '1 { /\/\* *-\*- *[mM]ode.*\*\/$/d }' -i "${F[@]}"
sed '1,4 { /^\(#\|--\|dnl\) *-\*- [mM]ode/d }' -i "${F[@]}"
Check remaining lines with:
git grep -e '-\*-'
The ultimate purpose of this is to cleanup our files and eventually use
SPDX license identifiers. For that, first get rid of the boilerplate lines.
557 lines
20 KiB
Lua
Executable file
557 lines
20 KiB
Lua
Executable file
#!/usr/bin/env lua
|
|
-- vim: ft=lua ts=2 sts=2 sw=2 et ai
|
|
--
|
|
-- 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; if not, write to the Free Software Foundation, Inc.,
|
|
-- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
--
|
|
-- Copyright 2015 Red Hat, Inc.
|
|
--
|
|
--
|
|
-- Script for importing/converting OpenVPN configuration files for NetworkManager
|
|
-- In general, the implementation follows the logic of import() from
|
|
-- https://git.gnome.org/browse/network-manager-openvpn/tree/properties/import-export.c
|
|
--
|
|
|
|
----------------------
|
|
-- Helper functions --
|
|
----------------------
|
|
function read_all(in_file)
|
|
local f, msg = io.open(in_file, "r")
|
|
if not f then return nil, msg; end
|
|
local content = f:read("*all")
|
|
f:close()
|
|
return content
|
|
end
|
|
|
|
function uuid()
|
|
math.randomseed(os.time())
|
|
local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
|
|
local uuid = string.gsub(template, '[xy]', function (c)
|
|
local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb)
|
|
return string.format('%x', v)
|
|
end)
|
|
return uuid
|
|
end
|
|
|
|
function unquote(str)
|
|
return (string.gsub(str, "^([\"\'])(.*)%1$", "%2"))
|
|
end
|
|
|
|
function parse_ipv4_to_bytes(ip_addr)
|
|
local b1,b2,b3,b4 = ip_addr:match("^(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)$")
|
|
b1 = tonumber(b1)
|
|
b2 = tonumber(b2)
|
|
b3 = tonumber(b3)
|
|
b4 = tonumber(b4)
|
|
return b1, b2, b3, b4
|
|
end
|
|
|
|
function is_ipv4(ip_addr)
|
|
local b1,b2,b3,b4 = parse_ipv4_to_bytes(ip_addr)
|
|
if not b1 or (b1 > 255) then return false end
|
|
if not b2 or (b2 > 255) then return false end
|
|
if not b3 or (b3 > 255) then return false end
|
|
if not b4 or (b4 > 255) then return false end
|
|
return true
|
|
end
|
|
|
|
function ip_mask_to_prefix(mask)
|
|
local b, prefix
|
|
local b1,b2,b3,b4 = parse_ipv4_to_bytes(mask)
|
|
|
|
if b4 ~= 0 then
|
|
prefix = 24
|
|
b = b4
|
|
elseif b3 ~= 0 then
|
|
prefix = 16
|
|
b = b3
|
|
elseif b2 ~= 0 then
|
|
prefix = 8
|
|
b = b2
|
|
else
|
|
prefix = 0
|
|
b = b1
|
|
end
|
|
while b ~= 0 do
|
|
prefix = prefix + 1
|
|
b = bit32.band(0x000000FF, bit32.lshift(b, 1))
|
|
end
|
|
return prefix
|
|
end
|
|
|
|
function vpn_settings_to_text(vpn_settings)
|
|
local t = {}
|
|
for k,v in pairs(vpn_settings) do
|
|
t[#t+1] = k.."="..v
|
|
end
|
|
return table.concat(t, "\n")
|
|
end
|
|
|
|
function usage()
|
|
local basename = string.match(arg[0], '[^/\\]+$') or arg[0]
|
|
print(basename .. " - convert/import OpenVPN configuration to NetworkManager")
|
|
print("Usage:")
|
|
print(" " .. basename .. " <input-file> <output-file>")
|
|
print(" - converts OpenVPN config to NetworkManager keyfile")
|
|
print("")
|
|
print(" " .. basename .. " --import <input-file1> <input-file2> ...")
|
|
print(" - imports OpenVPN config(s) to NetworkManager")
|
|
os.exit(1)
|
|
end
|
|
|
|
|
|
-------------------------------------------
|
|
-- Functions for VPN options translation --
|
|
-------------------------------------------
|
|
function set_bool(t, option, value)
|
|
g_switches[option] = true
|
|
end
|
|
function handle_yes(t, option, value)
|
|
t[option] = "yes"
|
|
end
|
|
function handle_generic(t, option, value)
|
|
if not value[2] then io.stderr:write(string.format("Warning: ignoring invalid option '%s'\n", value[1])) return end
|
|
t[option] = value[2]
|
|
end
|
|
function handle_generic_unquote(t, option, value)
|
|
if not value[2] then io.stderr:write(string.format("Warning: ignoring invalid option '%s'\n", value[1])) return end
|
|
t[option] = unquote(value[2])
|
|
end
|
|
function handle_number(t, option, value)
|
|
if not value[2] then io.stderr:write(string.format("Warning: ignoring invalid option '%s'\n", value[1])) return end
|
|
if not tonumber(value[2]) then
|
|
io.stderr:write(string.format("Warning: ignoring not numeric value '%s' for option '%s'\n", value[2], value[1]))
|
|
return
|
|
end
|
|
t[option] = value[2]
|
|
end
|
|
function handle_proto(t, option, value)
|
|
if not value[2] then io.stderr:write("Warning: ignoring invalid option 'proto'\n") end
|
|
if value[2] == "tcp" or value[3] == "tcp-client" or value[2] == "tcp-server" then
|
|
t[option] = "yes"
|
|
end
|
|
end
|
|
function handle_comp_lzo(t, option, value)
|
|
value[2] = value[2] or "adaptive"
|
|
if value[2] == "no" then
|
|
value[2] = "no-by-default"
|
|
elseif value[2] ~= "yes" and value[2] ~= "adaptive" then
|
|
io.stderr:write(string.format("Warning: ignoring invalid argument '%s' in option 'comp-lzo'\n", value[2]))
|
|
return
|
|
end
|
|
t[option] = value[2]
|
|
end
|
|
function handle_dev_type(t, option, value)
|
|
if value[2] ~= "tun" and value[2] ~= "tap" then
|
|
io.stderr:write(string.format("Warning: ignoring invalid option '%s'\n", value[1]))
|
|
end
|
|
t[option] = value[2]
|
|
end
|
|
function handle_remote(t, option, value)
|
|
local rem
|
|
if not value[2] then io.stderr:write("Warning: ignoring invalid option 'remote'\n") return end
|
|
rem = value[2]
|
|
if tonumber(value[3]) then
|
|
rem = rem .. ":" .. value[3]
|
|
end
|
|
if value[4] == "udp" or value[4] == "tcp" then
|
|
rem = rem .. ":" .. value[4]
|
|
end
|
|
if t[option] then
|
|
t[option] = t[option] .. " " .. rem
|
|
else
|
|
t[option] = rem
|
|
end
|
|
g_switches[value[1]] = true
|
|
end
|
|
function handle_port(t, option, value)
|
|
if tonumber(value[2]) then
|
|
t[option] = value[2]
|
|
end
|
|
end
|
|
function handle_proxy(t, option, value)
|
|
if not value[2] then io.stderr:write(string.format("Warning: ignoring invalid option '%s'\n", value[1])) return end
|
|
if value[4] then io.stderr:write(string.format("Warning: the third argument of '%s' is not supported yet\n", value[1])) end
|
|
t[option[1]] = string.gsub(value[1], "-proxy", "")
|
|
t[option[2]] = value[2]
|
|
t[option[3]] = value[3]
|
|
end
|
|
function handle_ifconfig(t, option, value)
|
|
if not (value[2] and value[3]) then io.stderr:write("Warning: ignoring invalid option 'ifconfig'\n") return end
|
|
t[option[1]] = value[2]
|
|
t[option[2]] = value[3]
|
|
end
|
|
function handle_keepalive(t, option, value)
|
|
if (not (value[2] and value[3])) or (not tonumber(value[2]) or not tonumber(value[3])) then
|
|
io.stderr:write("Warning: ignoring invalid option 'keepalive'; two numbers required\n")
|
|
return
|
|
end
|
|
t[option[1]] = value[2]
|
|
t[option[2]] = value[3]
|
|
end
|
|
function handle_path(t, option, value)
|
|
if value[1] == "pkcs12" then
|
|
t["ca"] = value[2]
|
|
t["cert"] = value[2]
|
|
t["key"] = value[2]
|
|
else
|
|
t[option] = value[2]
|
|
end
|
|
end
|
|
function handle_secret(t, option, value)
|
|
t[option[1]] = value[2]
|
|
t[option[2]] = value[3]
|
|
g_switches[value[1]]= true
|
|
end
|
|
function handle_remote_cert_tls(t, option, value)
|
|
if value[2] ~= "client" and value[2] ~= "server" then
|
|
io.stderr:write(string.format("Warning: ignoring invalid option '%s'\n", value[1]))
|
|
return
|
|
end
|
|
t[option] = value[2]
|
|
end
|
|
function handle_routes(t, option, value)
|
|
if not value[2] then io.stderr:write("Warning: invalid option 'route'\n") return end
|
|
netmask = (value[3] and value[3] ~= "default") and value[3] or "255.255.255.255"
|
|
gateway = (value[4] and value[4] ~= "default") and value[4] or "0.0.0.0"
|
|
metric = (value[5] and value[5] ~= "default") and value[5] or "0"
|
|
|
|
if not is_ipv4(value[2]) then
|
|
if value[2] == "vpn_gateway" or value[2] == "net_gateway" or value[2] == "remote_host" then
|
|
io.stderr:write(string.format("Warning: sorry, the '%s' keyword is not supported by NetworkManager in option '%s'\n",
|
|
value[2], value[1]))
|
|
else
|
|
io.stderr:write(string.format("Warning: '%s' is not a valid IPv4 address in option '%s'\n", value[2], value[1]))
|
|
end
|
|
return
|
|
end
|
|
if not is_ipv4(netmask) then
|
|
io.stderr:write(string.format("Warning: '%s' is not a valid IPv4 netmask in option '%s'\n", netmask, value[1]))
|
|
return
|
|
end
|
|
if not is_ipv4(gateway) then
|
|
if gateway == "vpn_gateway" or gateway == "net_gateway" or gateway == "remote_host" then
|
|
io.stderr:write(string.format("Warning: sorry, the '%s' keyword is not supported by NetworkManager in option '%s'\n",
|
|
gateway, value[1]))
|
|
else
|
|
io.stderr:write(string.format("Warning: '%s' is not a valid IPv4 gateway in option '%s'\n", gateway, value[1]))
|
|
end
|
|
return
|
|
end
|
|
if not tonumber(metric) then
|
|
io.stderr:write(string.format("Warning: '%s' is not a valid metric in option '%s'\n", metric, value[1]))
|
|
return
|
|
end
|
|
|
|
if not t[option] then t[option] = {} end
|
|
t[option][#t[option]+1] = {value[2], netmask, gateway, metric}
|
|
end
|
|
function handle_verify_x509_name(t, option, value)
|
|
if not value[2] then io.stderr:write("Warning: missing argument in option 'verify-x509-name'\n") return end
|
|
value[2] = unquote(value[2])
|
|
value[3] = value[3] or "subject"
|
|
if value[3] ~= "subject" and value[3] ~= "name" and value[3] ~= "name-prefix" then
|
|
io.stderr:write(string.format("Warning: ignoring invalid value '%s' for type in option '%s'\n", value[3], value[1]))
|
|
return
|
|
end
|
|
t[option] = value[3] .. ":" .. value[2]
|
|
end
|
|
|
|
-- global variables
|
|
g_vpn_data = {}
|
|
g_ip4_data = {}
|
|
g_switches = {}
|
|
|
|
vpn2nm = {
|
|
["auth"] = { nm_opt="auth", func=handle_generic, tbl=g_vpn_data },
|
|
["auth-user-pass"] = { nm_opt="auth-user-pass", func=set_bool, tbl={} },
|
|
["ca"] = { nm_opt="ca", func=handle_path, tbl=g_vpn_data },
|
|
["cert"] = { nm_opt="cert", func=handle_path, tbl=g_vpn_data },
|
|
["cipher"] = { nm_opt="cipher", func=handle_generic, tbl=g_vpn_data },
|
|
["client"] = { nm_opt="client", func=set_bool, tbl={} },
|
|
["comp-lzo"] = { nm_opt="comp-lzo", func=handle_comp_lzo, tbl=g_vpn_data },
|
|
["dev"] = { nm_opt="dev", func=handle_generic, tbl=g_vpn_data },
|
|
["dev-type"] = { nm_opt="dev-type", func=handle_dev_type, tbl=g_vpn_data },
|
|
["float"] = { nm_opt="float", func=handle_yes, tbl=g_vpn_data },
|
|
["fragment"] = { nm_opt="fragment-size", func=handle_generic, tbl=g_vpn_data },
|
|
["http-proxy"] = { nm_opt={"proxy-type", "proxy-server", "proxy-port"}, func=handle_proxy, tbl=g_vpn_data },
|
|
["http-proxy-retry"] = { nm_opt="proxy-retry", func=handle_yes, tbl=g_vpn_data },
|
|
["ifconfig"] = { nm_opt={"local-ip", "remote-ip"}, func=handle_ifconfig, tbl=g_vpn_data },
|
|
["keepalive"] = { nm_opt={"ping", "ping-restart"}, func=handle_keepalive, tbl=g_vpn_data },
|
|
["key"] = { nm_opt="key", func=handle_path, tbl=g_vpn_data },
|
|
["keysize"] = { nm_opt="keysize", func=handle_generic, tbl=g_vpn_data },
|
|
["max-routes"] = { nm_opt="max-routes", func=handle_number, tbl=g_vpn_data },
|
|
["mssfix"] = { nm_opt="mssfix", func=handle_yes, tbl=g_vpn_data },
|
|
["ns-cert-type"] = { nm_opt="ns-cert-type", func=handle_remote_cert_tls, tbl=g_vpn_data },
|
|
["ping"] = { nm_opt="ping", func=handle_number, tbl=g_vpn_data },
|
|
["ping-exit"] = { nm_opt="ping-exit", func=handle_number, tbl=g_vpn_data },
|
|
["ping-restart"] = { nm_opt="ping-restart", func=handle_number, tbl=g_vpn_data },
|
|
["pkcs12"] = { nm_opt="client", func=handle_path, tbl=g_vpn_data },
|
|
["port"] = { nm_opt="port", func=handle_port, tbl=g_vpn_data },
|
|
["proto"] = { nm_opt="proto-tcp", func=handle_proto, tbl=g_vpn_data },
|
|
["remote"] = { nm_opt="remote", func=handle_remote, tbl=g_vpn_data },
|
|
["remote-cert-tls"] = { nm_opt="remote-cert-tls", func=handle_remote_cert_tls, tbl=g_vpn_data },
|
|
["remote-random"] = { nm_opt="remote-random", func=handle_yes, tbl=g_vpn_data },
|
|
["reneg-sec"] = { nm_opt="reneg-seconds", func=handle_generic, tbl=g_vpn_data },
|
|
["route"] = { nm_opt="routes", func=handle_routes, tbl=g_ip4_data },
|
|
["rport"] = { nm_opt="port", func=handle_port, tbl=g_vpn_data },
|
|
["secret"] = { nm_opt={"static-key", "static-key-direction"}, func=handle_secret, tbl=g_vpn_data },
|
|
["socks-proxy"] = { nm_opt={"proxy-type", "proxy-server", "proxy-port"}, func=handle_proxy, tbl=g_vpn_data },
|
|
["socks-proxy-retry"] = { nm_opt="proxy-retry", func=handle_yes, tbl=g_vpn_data },
|
|
["tls-auth"] = { nm_opt={"ta", "ta-dir"}, func=handle_secret, tbl=g_vpn_data },
|
|
["tls-cipher"] = { nm_opt="tls-cipher", func=handle_generic_unquote, tbl=g_vpn_data },
|
|
["tls-client"] = { nm_opt="client", func=set_bool, tbl={} },
|
|
["tls-remote"] = { nm_opt="tls-remote", func=handle_generic_unquote, tbl=g_vpn_data },
|
|
["tun-ipv6"] = { nm_opt="tun-ipv6", func=handle_yes, tbl=g_vpn_data },
|
|
["tun-mtu"] = { nm_opt="tunnel-mtu", func=handle_generic, tbl=g_vpn_data },
|
|
["verify-x509-name"] = { nm_opt="verify-x509-name", func=handle_verify_x509_name,tbl=g_vpn_data },
|
|
}
|
|
|
|
------------------------------------------------------------
|
|
-- Read and convert the config into the global g_vpn_data --
|
|
-----------------------------------------------------------
|
|
function read_and_convert(in_file)
|
|
local function line_split(line)
|
|
local t={}
|
|
local i, idx = 1, 1
|
|
local delim = "\""
|
|
while true do
|
|
local a,b = line:find("%S+", idx)
|
|
if not a then break end
|
|
|
|
local str = line:sub(a,b)
|
|
local quote = nil
|
|
if str:sub(1,1) == delim and str:sub(#str,#str) ~= delim then
|
|
quote = (line.." "):find(delim.."%s", b + 1)
|
|
end
|
|
|
|
if quote then
|
|
t[i] = line:sub(a, quote)
|
|
idx = quote + 1
|
|
else
|
|
t[i] = str
|
|
idx = b + 1
|
|
end
|
|
i = i + 1
|
|
end
|
|
return t
|
|
end
|
|
|
|
in_text, msg = read_all(in_file)
|
|
if not in_text then return false, msg end
|
|
|
|
-- loop through the config and convert it
|
|
for line in in_text:gmatch("[^\r\n]+") do
|
|
repeat
|
|
-- skip comments and empty lines
|
|
if line:find("^%s*[#;]") or line:find("^%s*$") then break end
|
|
-- trim leading and trailing spaces
|
|
line = line:find("^%s*$") and "" or line:match("^%s*(.*%S)")
|
|
|
|
local words = line_split(line)
|
|
local val = vpn2nm[words[1]]
|
|
if val then
|
|
if type(val) == "table" then val.func(val.tbl, val.nm_opt, words)
|
|
else print(string.format("debug: '%s' : val=%s"..val)) end
|
|
end
|
|
until true
|
|
end
|
|
|
|
-- check some inter-option dependencies
|
|
if not g_switches["client"] and not g_switches["secret"] then
|
|
local msg = in_file .. ": Not a valid OpenVPN client configuration"
|
|
return false, msg
|
|
end
|
|
if not g_switches["remote"] then
|
|
local msg = in_file .. ": Not a valid OpenVPN configuration (no remote)"
|
|
return false, msg
|
|
end
|
|
|
|
-- set 'connection-type'
|
|
g_vpn_data["connection-type"] = "tls"
|
|
have_sk = g_switches["secret"] ~= nil
|
|
have_ca = g_vpn_data["ca"] ~= nil
|
|
have_certs = ve_ca and g_vpn_data["cert"] and g_vpn_data["key"]
|
|
if g_switches["auth-user-pass"] then
|
|
if have_certs then
|
|
g_vpn_data["connection-type"] = "password-tls"
|
|
elseif have_ca then
|
|
g_vpn_data["connection-type"] = "tls"
|
|
end
|
|
elseif have_certs then g_vpn_data["connection-type"] = "tls"
|
|
elseif have_sk then g_vpn_data["connection-type"] = "static-key"
|
|
end
|
|
return true
|
|
end
|
|
|
|
|
|
--------------------------------------------------------
|
|
-- Create and write connection file in keyfile format --
|
|
--------------------------------------------------------
|
|
function write_vpn_to_keyfile(in_file, out_file)
|
|
connection = [[
|
|
[connection]
|
|
id=__NAME_PLACEHOLDER__
|
|
uuid=__UUID_PLACEHOLDER__
|
|
type=vpn
|
|
autoconnect=no
|
|
|
|
[ipv4]
|
|
method=auto
|
|
never-default=true
|
|
__ROUTES_PLACEHOLDER__
|
|
|
|
[ipv6]
|
|
method=auto
|
|
|
|
[vpn]
|
|
service-type=org.freedesktop.NetworkManager.openvpn
|
|
]]
|
|
connection = connection .. vpn_settings_to_text(g_vpn_data)
|
|
|
|
local routes = ""
|
|
for idx, r in ipairs(g_ip4_data["routes"] or {}) do
|
|
routes = routes .. string.format("routes%d=%s/%s,%s,%s\n",
|
|
idx, r[1], ip_mask_to_prefix(r[2]), r[3], r[4])
|
|
end
|
|
|
|
connection = string.gsub(connection, "__NAME_PLACEHOLDER__", (out_file:gsub(".*/", "")))
|
|
connection = string.gsub(connection, "__UUID_PLACEHOLDER__", uuid())
|
|
connection = string.gsub(connection, "__ROUTES_PLACEHOLDER__\n", routes)
|
|
|
|
-- write output file
|
|
local f, err = io.open(out_file, "w")
|
|
if not f then io.stderr:write(err) return false end
|
|
f:write(connection)
|
|
f:close()
|
|
|
|
local ofname = out_file:gsub(".*/", "")
|
|
io.stderr:write("Successfully converted VPN configuration: " .. in_file .. " => " .. out_file .. "\n")
|
|
io.stderr:write("To use the connection, do:\n")
|
|
io.stderr:write("# cp " .. out_file .. " /etc/NetworkManager/system-connections\n")
|
|
io.stderr:write("# chmod 600 /etc/NetworkManager/system-connections/" .. ofname .. "\n")
|
|
io.stderr:write("# nmcli con load /etc/NetworkManager/system-connections/" .. ofname .. "\n")
|
|
return true
|
|
end
|
|
|
|
---------------------------------------------
|
|
-- Import VPN connection to NetworkManager --
|
|
---------------------------------------------
|
|
function import_vpn_to_NM(filename)
|
|
local lgi = require 'lgi'
|
|
local GLib = lgi.GLib
|
|
local NM = lgi.NM
|
|
|
|
-- function creating NMConnection
|
|
local function create_profile(name)
|
|
local profile = NM.SimpleConnection.new()
|
|
|
|
s_con = NM.SettingConnection.new()
|
|
s_ip4 = NM.SettingIP4Config.new()
|
|
s_vpn = NM.SettingVpn.new()
|
|
s_con[NM.SETTING_CONNECTION_ID] = name
|
|
s_con[NM.SETTING_CONNECTION_UUID] = uuid()
|
|
s_ip4[NM.SETTING_IP_CONFIG_METHOD] = NM.SETTING_IP4_CONFIG_METHOD_AUTO
|
|
s_con[NM.SETTING_CONNECTION_TYPE] = "vpn"
|
|
s_vpn[NM.SETTING_VPN_SERVICE_TYPE] = "org.freedesktop.NetworkManager.openvpn"
|
|
|
|
-- add routes
|
|
local AF_INET = 2
|
|
for _, r in ipairs(g_ip4_data["routes"] or {}) do
|
|
route = NM.IPRoute.new(AF_INET, r[1], ip_mask_to_prefix(r[2]), r[3], r[4])
|
|
s_ip4:add_route(route)
|
|
end
|
|
|
|
-- add vpn data
|
|
for k,v in pairs(g_vpn_data) do
|
|
s_vpn:add_data_item(k, v)
|
|
end
|
|
|
|
profile:add_setting(s_con)
|
|
profile:add_setting(s_vpn)
|
|
profile:add_setting(s_ip4)
|
|
return profile
|
|
end
|
|
|
|
-- callback function for add_connection()
|
|
local function added_cb(client, result, data)
|
|
local con,err,code = client:add_connection_finish(result)
|
|
if con then
|
|
print(string.format("%s: Imported to NetworkManager: %s - %s",
|
|
filename, con:get_uuid(), con:get_id()))
|
|
else
|
|
io.stderr:write(code .. ": " .. err .. "\n");
|
|
return false
|
|
end
|
|
main_loop:quit()
|
|
end
|
|
|
|
local profile_name = string.match(filename, '[^/\\]+$') or filename
|
|
main_loop = GLib.MainLoop(nil, false)
|
|
local con = create_profile(profile_name)
|
|
local client = NM.Client.new()
|
|
|
|
-- send the connection to NetworkManager
|
|
client:add_connection_async(con, true, nil, added_cb, nil)
|
|
|
|
-- run main loop so that the callback could be called
|
|
main_loop:run()
|
|
return true
|
|
end
|
|
|
|
|
|
---------------------------
|
|
-- Main code starts here --
|
|
---------------------------
|
|
local import_mode = false
|
|
local infile, outfile
|
|
|
|
-- parse command-line arguments
|
|
if not arg[1] or arg[1] == "--help" or arg[1] == "-h" then usage() end
|
|
if arg[1] == "--import" or arg[1] == "-i" then
|
|
infile = arg[2]
|
|
if not infile then usage() end
|
|
import_mode = true
|
|
else
|
|
infile = arg[1]
|
|
outfile = arg[2]
|
|
if not infile or not outfile then usage() end
|
|
if arg[3] then usage() end
|
|
end
|
|
|
|
if import_mode then
|
|
-- check if lgi is available
|
|
local success,msg = pcall(require, 'lgi')
|
|
if not success then
|
|
io.stderr:write("Lua lgi module is not available, please install it (usually lua-lgi package)\n")
|
|
-- print(msg)
|
|
os.exit(1)
|
|
end
|
|
-- read configs, convert them and import to NM
|
|
for i = 2, #arg do
|
|
ok, err_msg = read_and_convert(arg[i])
|
|
if ok then import_vpn_to_NM(arg[i])
|
|
else io.stderr:write(err_msg .. "\n") end
|
|
-- reset global vars
|
|
g_vpn_data = {}
|
|
g_ip4_data = {}
|
|
g_switches = {}
|
|
end
|
|
else
|
|
-- read configs, convert them and write as NM keyfile connection
|
|
ok, err_msg = read_and_convert(infile)
|
|
if ok then write_vpn_to_keyfile(infile, outfile)
|
|
else io.stderr:write(err_msg .. "\n") end
|
|
end
|
|
|