luci-base: update Japanese translation
[oweals/luci.git] / applications / luci-app-openvpn / luasrc / model / cbi / openvpn-advanced.lua
1 -- Copyright 2008 Steven Barth <steven@midlink.org>
2 -- Licensed to the public under the Apache License 2.0.
3
4 local fs = require("nixio.fs")
5
6 local knownParams = {
7         --
8         --Widget
9         --      Name
10         --      Default(s)
11         --      Description
12         --      Option(s)
13
14         { "Service", {
15         -- initialisation and daemon options
16                 { ListValue,
17                         "verb",
18                         { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
19                         translate("Set output verbosity") },
20                 { Flag,
21                         "mlock",
22                         0,
23                         translate("Disable Paging") },
24                 { Flag,
25                         "disable_occ",
26                         0,
27                         translate("Disable options consistency check") },
28         --      { Value,
29         --              "user",
30         --              "root",
31         --              translate("Set UID to user") },
32         --      { Value,
33         --              "group",
34         --              "root",
35         --              translate("Set GID to group") },
36                 { Value,
37                         "cd",
38                         "/etc/openvpn",
39                         translate("Change to directory before initialization") },
40                 { Value,
41                         "chroot",
42                         "/var/run",
43                         translate("Chroot to directory after initialization") },
44         --      { Value,
45         --              "daemon",
46         --              "Instance-Name",
47         --              translate("Daemonize after initialization") },
48         --      { Value,
49         --              "syslog",
50         --              "Instance-Name",
51         --              translate("Output to syslog and do not daemonize") },
52                 { Flag,
53                         "passtos",
54                         0,
55                         translate("TOS passthrough (applies to IPv4 only)") },
56         --      { Value,
57         --              "inetd",
58         --              "nowait Instance-Name",
59         --              translate("Run as an inetd or xinetd server") },
60                 { Value,
61                         "log",
62                         "/var/log/openvpn.log",
63                         translate("Write log to file") },
64                 { Value,
65                         "log_append",
66                         "/var/log/openvpn.log",
67                         translate("Append log to file") },
68                 { Flag,
69                         "suppress_timestamps",
70                         0,
71                         translate("Don't log timestamps") },
72         --      { Value,
73         --              "writepid",
74         --              "/var/run/openvpn.pid",
75         --              translate("Write process ID to file") },
76                 { Value,
77                         "nice",
78                         0,
79                         translate("Change process priority") },
80                 { Flag,
81                         "fast_io",
82                         0,
83                         translate("Optimize TUN/TAP/UDP writes") },
84                 { Value,
85                         "echo",
86                         "some params echoed to log",
87                         translate("Echo parameters to log") },
88                 { ListValue,
89                         "remap_usr1",
90                         { "SIGHUP", "SIGTERM" },
91                         translate("Remap SIGUSR1 signals") },
92                 { Value,
93                         "status",
94                         "/var/run/openvpn.status 5",
95                         translate("Write status to file every n seconds") },
96                 { Value,
97                         "status_version",
98                         { 1, 2 },
99                         translate("Status file format version") },      -- status
100                 { Value,
101                         "mute",
102                         5,
103                         translate("Limit repeated log messages") },
104                 { Value,
105                         "up",
106                         "/usr/bin/ovpn-up",
107                         translate("Shell cmd to execute after tun device open") },
108                 { Value,
109                         "up_delay",
110                         5,
111                         translate("Delay tun/tap open and up script execution") },
112                 { Value,
113                         "down",
114                         "/usr/bin/ovpn-down",
115                         translate("Shell cmd to run after tun device close") },
116                 { Flag,
117                         "down_pre",
118                         0,
119                         translate("Call down cmd/script before TUN/TAP close") },
120                 { Flag,
121                         "up_restart",
122                         0,
123                         translate("Run up/down scripts for all restarts") },
124                 { Value,
125                         "route_up",
126                         "/usr/bin/ovpn-routeup",
127                         translate("Execute shell cmd after routes are added") },
128                 { Value,
129                         "ipchange",
130                         "/usr/bin/ovpn-ipchange",
131                         translate("Execute shell command on remote ip change"),
132                         { mode="p2p" } },
133                 { DynamicList,
134                         "setenv",
135                         { "VAR1 value1", "VAR2 value2" },
136                         translate("Pass environment variables to script") },
137                 { Value,
138                         "tls_verify",
139                         "/usr/bin/ovpn-tlsverify",
140                         translate("Shell command to verify X509 name") },
141                 { Value,
142                         "client_connect",
143                         "/usr/bin/ovpn-clientconnect",
144                         translate("Run script cmd on client connection") },
145                 { Flag,
146                         "client_disconnect",
147                         0,
148                         translate("Run script cmd on client disconnection") },
149                 { Value,
150                         "learn_address",
151                         "/usr/bin/ovpn-learnaddress",
152                         translate("Executed in server mode whenever an IPv4 address/route or MAC address is added to OpenVPN's internal routing table") },
153                 { Value,
154                         "auth_user_pass_verify",
155                         "/usr/bin/ovpn-userpass via-env",
156                         translate("Executed in server mode on new client connections, when the client is still untrusted") },
157                 { ListValue,
158                         "script_security",
159                         { 0, 1, 2, 3 },
160                         translate("Policy level over usage of external programs and scripts") },
161                 { Value,
162                         "config",
163                         "/etc/openvpn/ovpn-file.ovpn",
164                         translate("Local OVPN configuration file") },
165         } },
166
167         { "Networking", {
168         -- socket config
169                 { ListValue,
170                         "mode",
171                         { "p2p", "server" },
172                         translate("Major mode") },
173                 { Value,
174                         "local",
175                         "0.0.0.0",
176                         translate("Local host name or ip address") },
177                 { Value,
178                         "port",
179                         1194,
180                         translate("TCP/UDP port # for both local and remote") },
181                 { Value,
182                         "lport",
183                         1194,
184                         translate("TCP/UDP port # for local (default=1194)") },
185                 { Value,
186                         "rport",
187                         1194,
188                         translate("TCP/UDP port # for remote (default=1194)") },
189                 { Flag,
190                         "float",
191                         0,
192                         translate("Allow remote to change its IP or port") },
193                 { Flag,
194                         "nobind",
195                         0,
196                         translate("Do not bind to local address and port") },
197                 { Value,
198                         "dev",
199                         "tun0",
200                         translate("tun/tap device") },
201                 { ListValue,
202                         "dev_type",
203                         { "tun", "tap" },
204                         translate("Type of used device") },
205                 { Value,
206                         "dev_node",
207                         "/dev/net/tun",
208                         translate("Use tun/tap device node") },
209                 { Value,
210                         "ifconfig",
211                         "10.200.200.3 10.200.200.1",
212                         translate("Set tun/tap adapter parameters") },
213                 { Flag,
214                         "ifconfig_noexec",
215                         0,
216                         translate("Don't actually execute ifconfig") },
217                 { Flag,
218                         "ifconfig_nowarn",
219                         0,
220                         translate("Don't warn on ifconfig inconsistencies") },
221                 { DynamicList,
222                         "route",
223                         "10.123.0.0 255.255.0.0",
224                         translate("Add route after establishing connection") },
225                 { Value,
226                         "route_gateway",
227                         "10.234.1.1",
228                         translate("Specify a default gateway for routes") },
229                 { Value,
230                         "route_delay",
231                         0,
232                         translate("Delay n seconds after connection") },
233                 { Flag,
234                         "route_noexec",
235                         0,
236                         translate("Don't add routes automatically") },
237                 { Flag,
238                         "route_nopull",
239                         0,
240                         translate("Don't pull routes automatically") },
241                 { ListValue,
242                         "mtu_disc",
243                         { "yes", "maybe", "no" },
244                         translate("Enable Path MTU discovery") },
245                 { Flag,
246                         "mtu_test",
247                         0,
248                         translate("Empirically measure MTU") },
249                 { Value,
250                         "link_mtu",
251                         1500,
252                         translate("Set TCP/UDP MTU") },
253                 { Value,
254                         "tun_mtu",
255                         1500,
256                         translate("Set tun/tap device MTU") },
257                 { Value,
258                         "tun_mtu_extra",
259                         1500,
260                         translate("Set tun/tap device overhead") },
261                 { Value,
262                         "fragment",
263                         1500,
264                         translate("Enable internal datagram fragmentation"),
265                         { proto="udp" } },
266                 { Value,
267                         "mssfix",
268                         1500,
269                         translate("Set upper bound on TCP MSS"),
270                         { proto="udp" } },
271                 { Value,
272                         "sndbuf",
273                         65536,
274                         translate("Set the TCP/UDP send buffer size") },
275                 { Value,
276                         "rcvbuf",
277                         65536,
278                         translate("Set the TCP/UDP receive buffer size") },
279                 { Value,
280                         "txqueuelen",
281                         100,
282                         translate("Set tun/tap TX queue length") },
283                 { Value,
284                         "shaper",
285                         10240,
286                         translate("Shaping for peer bandwidth") },
287                 { Value,
288                         "inactive",
289                         240,
290                         translate("tun/tap inactivity timeout") },
291                 { Value,
292                         "keepalive",
293                         "10 60",
294                         translate("Helper directive to simplify the expression of --ping and --ping-restart in server mode configurations") },
295                 { Value,
296                         "ping",
297                         30,
298                         translate("Ping remote every n seconds over TCP/UDP port") },
299                 { Value,
300                         "ping_exit",
301                         120,
302                         translate("Remote ping timeout") },
303                 { Value,
304                         "ping_restart",
305                         60,
306                         translate("Restart after remote ping timeout") },
307                 { Flag,
308                         "ping_timer_rem",
309                         0,
310                         translate("Only process ping timeouts if routes exist") },
311                 { Flag,
312                         "persist_tun",
313                         0,
314                         translate("Keep tun/tap device open on restart") },
315                 { Flag,
316                         "persist_key",
317                         0,
318                         translate("Don't re-read key on restart") },
319                 { Flag,
320                         "persist_local_ip",
321                         0,
322                         translate("Keep local IP address on restart") },
323                 { Flag,
324                         "persist_remote_ip",
325                         0,
326                         translate("Keep remote IP address on restart") },
327         -- management channel
328                 { Value,
329                         "management",
330                         "127.0.0.1 31194 /etc/openvpn/mngmt-pwds",
331                         translate("Enable management interface on <em>IP</em> <em>port</em>") },
332         -- management
333                 { Flag,
334                         "management_query_passwords",
335                         0,
336                         translate("Query management channel for private key") },
337         -- management
338                 { Flag,
339                         "management_hold",
340                         0,
341                         translate("Start OpenVPN in a hibernating state") },
342         -- management
343                 { Value,
344                         "management_log_cache",
345                         100,
346                         translate("Number of lines for log file history") },
347                 { ListValue,
348                         "topology",
349                         { "net30", "p2p", "subnet" },
350                         translate("'net30', 'p2p', or 'subnet'"),
351                         {dev_type="tun" } },
352         } },
353
354         { "VPN", {
355                 { Value,
356                         "server",
357                         "10.200.200.0 255.255.255.0",
358                         translate("Configure server mode"),
359                         { client="0" }, { client="" } },
360                 { Value,
361                         "server_bridge",
362                         "10.200.200.1 255.255.255.0 10.200.200.200 10.200.200.250",
363                         translate("Configure server bridge"),
364                         { client="0" }, { client="" } },
365                 { DynamicList,
366                         "push",
367                         { "redirect-gateway" },
368                         translate("Push options to peer"),
369                         { client="0" }, { client="" } },
370                 { Flag,
371                         "push_reset",
372                         0,
373                         translate("Don't inherit global push options"),
374                         { client="0" }, { client="" } },
375                 { Flag,
376                         "disable",
377                         0,
378                         translate("Client is disabled"),
379                         { client="0" }, { client="" } },
380                 { Value,
381                         "ifconfig_pool",
382                         "10.200.200.100 10.200.200.150 255.255.255.0",
383                         translate("Set aside a pool of subnets"),
384                         { client="0" }, { client="" } },
385                 { Value,
386                         "ifconfig_pool_persist",
387                         "/etc/openvpn/ipp.txt 600",
388                         translate("Persist/unpersist ifconfig-pool"),
389                         { client="0" }, { client="" } },
390                 { Value,
391                         "ifconfig_push",
392                         "10.200.200.1 255.255.255.255",
393                         translate("Push an ifconfig option to remote"),
394                         { client="0" }, { client="" } },
395                 { Value,
396                         "iroute",
397                         "10.200.200.0 255.255.255.0",
398                         translate("Route subnet to client"),
399                         { client="0" }, { client="" } },
400                 { Flag,
401                         "client_to_client",
402                         0,
403                         translate("Allow client-to-client traffic"),
404                         { client="0" }, { client="" } },
405                 { Flag,
406                         "duplicate_cn",
407                         0,
408                         translate("Allow multiple clients with same certificate"),
409                         { client="0" }, { client="" } },
410                 { Value,
411                         "client_config_dir",
412                         "/etc/openvpn/ccd",
413                         translate("Directory for custom client config files"),
414                         { client="0" }, { client="" } },
415                 { Flag,
416                         "ccd_exclusive",
417                         0,
418                         translate("Refuse connection if no custom client config"),
419                         { client="0" }, { client="" } },
420                 { Value,
421                         "tmp_dir",
422                         "/var/run/openvpn",
423                         translate("Temporary directory for client-connect return file"),
424                         { client="0" }, { client="" } },
425                 { Value,
426                         "hash_size",
427                         "256 256",
428                         translate("Set size of real and virtual address hash tables"),
429                         { client="0" }, { client="" } },
430                 { Value,
431                         "bcast_buffers",
432                         256,
433                         translate("Number of allocated broadcast buffers"),
434                         { client="0" }, { client="" } },
435                 { Value,
436                         "tcp_queue_limit",
437                         64,
438                         translate("Maximum number of queued TCP output packets"),
439                         { client="0" }, { client="" } },
440                 { Value,
441                         "max_clients",
442                         10,
443                         translate("Allowed maximum of connected clients"),
444                         { client="0" }, { client="" } },
445                 { Value,
446                         "max_routes_per_client",
447                         256,
448                         translate("Allowed maximum of internal"),
449                         { client="0" }, { client="" } },
450                 { Value,
451                         "connect_freq",
452                         "3 10",
453                         translate("Allowed maximum of new connections"),
454                         { client="0" }, { client="" } },
455                 { Flag,
456                         "username_as_common_name",
457                         0,
458                         translate("Use username as common name"),
459                         { client="0" }, { client="" } },
460                 { Flag,
461                         "client",
462                         0,
463                         translate("Configure client mode") },
464                 { Flag,
465                         "pull",
466                         0,
467                         translate("Accept options pushed from server"),
468                         { client="1" } },
469                 { FileUpload,
470                         "auth_user_pass",
471                         "/etc/openvpn/userpass.txt",
472                         translate("Authenticate using username/password"),
473                         { client="1" } },
474                 { ListValue,
475                         "auth_retry",
476                         { "none", "nointeract", "interact" },
477                         translate("Handling of authentication failures"),
478                         { client="1" } },
479                 { Value,
480                         "explicit_exit_notify",
481                         1,
482                         translate("Send notification to peer on disconnect"),
483                         { client="1" } },
484                 { DynamicList,
485                         "remote",
486                         "1.2.3.4",
487                         translate("Remote host name or ip address"),
488                         { client="1" } },
489                 { Flag,
490                         "remote_random",
491                         0,
492                         translate("Randomly choose remote server"),
493                         { client="1" } },
494                 { ListValue,
495                         "proto",
496                         { "udp", "tcp-client", "tcp-server" },
497                         translate("Use protocol"),
498                         { client="1" } },
499                 { Value,
500                         "connect_retry",
501                         5,
502                         translate("Connection retry interval"),
503                         { proto="tcp-client" }, { client="1" } },
504                 { Value,
505                         "http_proxy",
506                         "192.168.1.100 8080",
507                         translate("Connect to remote host through an HTTP proxy"),
508                         { client="1" } },
509                 { Flag,
510                         "http_proxy_retry",
511                         0,
512                         translate("Retry indefinitely on HTTP proxy errors"),
513                         { client="1" } },
514                 { Value,
515                         "http_proxy_timeout",
516                         5,
517                         translate("Proxy timeout in seconds"),
518                         { client="1" } },
519                 { DynamicList,
520                         "http_proxy_option",
521                         { "VERSION 1.0", "AGENT OpenVPN/2.0.9" },
522                         translate("Set extended HTTP proxy options"),
523                         { client="1" } },
524                 { Value,
525                         "socks_proxy",
526                         "192.168.1.200 1080",
527                         translate("Connect through Socks5 proxy"),
528                         { client="1" } },
529         -- client && socks_proxy
530                 { Value,
531                         "socks_proxy_retry",
532                         5,
533                         translate("Retry indefinitely on Socks proxy errors"),
534                         { client="1" } },
535                 { Value,
536                         "resolv_retry",
537                         "infinite",
538                         translate("If hostname resolve fails, retry"),
539                         { client="1" } },
540                 { ListValue,
541                         "redirect_gateway",
542                         { "", "local", "def1", "local def1" },
543                         translate("Automatically redirect default route"),
544                         { client="1" } },
545         } },
546
547         { "Cryptography", {
548                 { FileUpload,
549                         "secret",
550                         "/etc/openvpn/secret.key",
551                         translate("Enable Static Key encryption mode (non-TLS)") },
552         -- parse
553                 { Value,
554                         "auth",
555                         "SHA1",
556                         translate("HMAC authentication for packets") },
557         -- parse
558                 { Value,
559                         "cipher",
560                         "BF-CBC",
561                         translate("Encryption cipher for packets") },
562         -- parse
563                 { Value,
564                         "keysize",
565                         1024,
566                         translate("Size of cipher key") },
567         -- parse
568                 { Value,
569                         "engine",
570                         "dynamic",
571                         translate("Enable OpenSSL hardware crypto engines") },
572                 { Value,
573                         "replay_window",
574                         "64 15",
575                         translate("Replay protection sliding window size") },
576                 { Flag,
577                         "mute_replay_warnings",
578                         0,
579                         translate("Silence the output of replay warnings") },
580                 { Value,
581                         "replay_persist",
582                         "/var/run/openvpn-replay-state",
583                         translate("Persist replay-protection state") },
584                 { Flag,
585                         "tls_server",
586                         0,
587                         translate("Enable TLS and assume server role"),
588                         { tls_client="" }, { tls_client="0" } },
589                 { Flag,
590                         "tls_client",
591                         0,
592                         translate("Enable TLS and assume client role"),
593                         { tls_server="" }, { tls_server="0" } },
594                 { FileUpload,
595                         "ca",
596                         "/etc/easy-rsa/keys/ca.crt",
597                         translate("Certificate authority") },
598                 { FileUpload,
599                         "dh",
600                         "/etc/easy-rsa/keys/dh1024.pem",
601                         translate("Diffie Hellman parameters") },
602                 { FileUpload,
603                         "cert",
604                         "/etc/easy-rsa/keys/some-client.crt",
605                         translate("Local certificate") },
606                 { FileUpload,
607                         "key",
608                         "/etc/easy-rsa/keys/some-client.key",
609                         translate("Local private key") },
610                 { FileUpload,
611                         "pkcs12",
612                         "/etc/easy-rsa/keys/some-client.pk12",
613                         translate("PKCS#12 file containing keys") },
614                 { ListValue,
615                         "key_method",
616                         { 1, 2 },
617                         translate("Enable TLS and assume client role") },
618                 { Value,
619                         "tls_cipher",
620                         "DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:RC4-SHA:RC4-MD5:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5",
621                         translate("TLS cipher") },
622                 { Value,
623                         "tls_timeout",
624                         2,
625                         translate("Retransmit timeout on TLS control channel") },
626                 { Value,
627                         "reneg_bytes",
628                         1024,
629                         translate("Renegotiate data chan. key after bytes") },
630                 { Value,
631                         "reneg_pkts",
632                         100,
633                         translate("Renegotiate data chan. key after packets") },
634                 { Value,
635                         "reneg_sec",
636                         3600,
637                         translate("Renegotiate data chan. key after seconds") },
638                 { Value,
639                         "hand_window",
640                         60,
641                         translate("Timeframe for key exchange") },
642                 { Value,
643                         "tran_window",
644                         3600,
645                         translate("Key transition window") },
646                 { Flag,
647                         "single_session",
648                         0,
649                         translate("Allow only one session") },
650                 { Flag,
651                         "tls_exit",
652                         0,
653                         translate("Exit on TLS negotiation failure") },
654                 { Value,
655                         "tls_auth",
656                         "/etc/openvpn/tlsauth.key",
657                         translate("Additional authentication over TLS") },
658                 { Value,
659                         "tls_crypt",
660                         "/etc/openvpn/tlscrypt.key",
661                         translate("Encrypt and authenticate all control channel packets with the key") },
662         --      { Value,
663         --              "askpass",
664         --              "[file]",
665         --              translate("Get PEM password from controlling tty before we daemonize") },
666                 { Flag,
667                         "auth_nocache",
668                         0,
669                         translate("Don't cache --askpass or --auth-user-pass passwords") },
670                 { Value,
671                         "tls_remote",
672                         "remote_x509_name",
673                         translate("Only accept connections from given X509 name") },
674                 { ListValue,
675                         "ns_cert_type",
676                         { "client", "server" },
677                         translate("Require explicit designation on certificate") },
678                 { ListValue,
679                         "remote_cert_tls",
680                         { "client", "server" },
681                         translate("Require explicit key usage on certificate") },
682                 { Value,
683                         "crl_verify",
684                         "/etc/easy-rsa/keys/crl.pem",
685                         translate("Check peer certificate against a CRL") },
686                 { Value,
687                         "tls_version_min",
688                         "1.0",
689                         translate("The lowest supported TLS version") },
690                 { Value,
691                         "tls_version_max",
692                         "1.2",
693                         translate("The highest supported TLS version") },
694                 { ListValue,
695                         "key_direction",
696                         { 0, 1 },
697                         translate("The key direction for 'tls-auth' and 'secret' options") },
698         } }
699 }
700
701
702 local cts = { }
703 local params = { }
704
705 local m = Map("openvpn")
706 local p = m:section( SimpleSection )
707
708 m.apply_on_parse = true
709
710 p.template = "openvpn/pageswitch"
711 p.mode     = "advanced"
712 p.instance = arg[1]
713 p.category = arg[2] or "Service"
714
715 for _, c in ipairs(knownParams) do
716         cts[#cts+1] = c[1]
717         if c[1] == p.category then params = c[2] end
718 end
719
720 p.categories = cts
721
722
723 local s = m:section(
724         NamedSection, arg[1], "openvpn",
725         translate("%s" % arg[2])
726 )
727
728 s.title     = translate("%s" % arg[2])
729 s.addremove = false
730 s.anonymous = true
731
732
733 for _, option in ipairs(params) do
734         local o = s:option(
735                 option[1], option[2],
736                 option[2], option[4]
737         )
738
739         o.optional = true
740
741         if option[1] == DummyValue then
742                 o.value = option[3]
743         elseif option[1] == FileUpload then
744
745                 function o.cfgvalue(self, section)
746                         local cfg_val = AbstractValue.cfgvalue(self, section)
747
748                         if cfg_val then
749                                 return cfg_val
750                         end
751                 end
752
753                 function o.formvalue(self, section)
754                         local sel_val = AbstractValue.formvalue(self, section)
755                         local txt_val = luci.http.formvalue("cbid."..self.map.config.."."..section.."."..self.option..".textbox")
756
757                         if sel_val and sel_val ~= "" then
758                                 return sel_val
759                         end
760
761                         if txt_val and txt_val ~= "" then
762                                 return txt_val
763                         end
764                 end
765
766                 function o.remove(self, section)
767                         local cfg_val = AbstractValue.cfgvalue(self, section)
768                         local txt_val = luci.http.formvalue("cbid."..self.map.config.."."..section.."."..self.option..".textbox")
769                         
770                         if cfg_val and fs.access(cfg_val) and txt_val == "" then
771                                 fs.unlink(cfg_val)
772                         end
773                         return AbstractValue.remove(self, section)
774                 end
775         else
776                 if option[1] == DynamicList then
777                         function o.cfgvalue(...)
778                                 local val = AbstractValue.cfgvalue(...)
779                                 return ( val and type(val) ~= "table" ) and { val } or val
780                         end
781                 end
782
783                 if type(option[3]) == "table" then
784                         if o.optional then o:value("", "-- remove --") end
785                         for _, v in ipairs(option[3]) do
786                                 v = tostring(v)
787                                 o:value(v)
788                         end
789                         o.default = tostring(option[3][1])
790                 else
791                         o.default = tostring(option[3])
792                 end
793         end
794
795         for i=5,#option do
796                 if type(option[i]) == "table" then
797                         o:depends(option[i])
798                 end
799         end
800 end
801
802 return m