github.com/iDigitalFlame/xmt@v0.5.4/c2/cfg/z_json.go (about)

     1  //go:build !nojson && !implant
     2  // +build !nojson,!implant
     3  
     4  // Copyright (C) 2020 - 2023 iDigitalFlame
     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  // 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 <https://www.gnu.org/licenses/>.
    18  //
    19  
    20  package cfg
    21  
    22  import (
    23  	"encoding/base64"
    24  	"encoding/json"
    25  	"strconv"
    26  	"strings"
    27  	"time"
    28  
    29  	"github.com/PurpleSec/escape"
    30  	"github.com/iDigitalFlame/xmt/util"
    31  	"github.com/iDigitalFlame/xmt/util/xerr"
    32  )
    33  
    34  type config struct {
    35  	Type string
    36  	Args json.RawMessage
    37  }
    38  type mapper map[string]json.RawMessage
    39  
    40  func (c cBit) String() string {
    41  	switch c {
    42  	case Separator:
    43  		return "|"
    44  	case valHost:
    45  		return "host"
    46  	case valSleep:
    47  		return "sleep"
    48  	case valJitter:
    49  		return "jitter"
    50  	case valWeight:
    51  		return "weight"
    52  	case valKeyPin:
    53  		return "keypin"
    54  	case valKillDate:
    55  		return "killdate"
    56  	case valWorkHours:
    57  		return "workhours"
    58  	case SelectorLastValid:
    59  		return "select-last"
    60  	case SelectorRoundRobin:
    61  		return "select-round-robin"
    62  	case SelectorRandom:
    63  		return "select-random"
    64  	case SelectorSemiRoundRobin:
    65  		return "select-semi-round-robin"
    66  	case SelectorSemiRandom:
    67  		return "select-semi-random"
    68  	case ConnectTCP:
    69  		return "tcp"
    70  	case ConnectTLS:
    71  		return "tls"
    72  	case ConnectUDP:
    73  		return "udp"
    74  	case ConnectICMP:
    75  		return "icmp"
    76  	case ConnectPipe:
    77  		return "pipe"
    78  	case ConnectTLSNoVerify:
    79  		return "tls-insecure"
    80  	case valIP:
    81  		return "ip"
    82  	case valWC2:
    83  		return "wc2"
    84  	case valTLSx:
    85  		return "tls-ex"
    86  	case valMuTLS:
    87  		return "mtls"
    88  	case valTLSxCA:
    89  		return "tls-ca"
    90  	case valTLSCert:
    91  		return "tls-cert"
    92  	case WrapHex:
    93  		return "hex"
    94  	case WrapZlib:
    95  		return "zlib"
    96  	case WrapGzip:
    97  		return "gzip"
    98  	case WrapBase64:
    99  		return "base64"
   100  	case valXOR:
   101  		return "xor"
   102  	case valCBK:
   103  		return "cbk"
   104  	case valAES:
   105  		return "aes"
   106  	case TransformB64:
   107  		return "b64t"
   108  	case valDNS:
   109  		return "dns"
   110  	case valB64Shift:
   111  		return "b64s"
   112  	}
   113  	return "<invalid>"
   114  }
   115  func bitFromName(s string) cBit {
   116  	switch strings.ToLower(s) {
   117  	case "host":
   118  		return valHost
   119  	case "sleep":
   120  		return valSleep
   121  	case "jitter":
   122  		return valJitter
   123  	case "keypin":
   124  		return valKeyPin
   125  	case "weight":
   126  		return valWeight
   127  	case "killdate":
   128  		return valKillDate
   129  	case "workhours":
   130  		return valWorkHours
   131  	case "select-last":
   132  		return SelectorLastValid
   133  	case "select-round-robin":
   134  		return SelectorRoundRobin
   135  	case "select-random":
   136  		return SelectorRandom
   137  	case "select-semi-round-robin":
   138  		return SelectorSemiRoundRobin
   139  	case "select-semi-random":
   140  		return SelectorSemiRandom
   141  	case "tcp":
   142  		return ConnectTCP
   143  	case "tls":
   144  		return ConnectTLS
   145  	case "udp":
   146  		return ConnectUDP
   147  	case "icmp":
   148  		return ConnectICMP
   149  	case "pipe":
   150  		return ConnectPipe
   151  	case "tls-insecure":
   152  		return ConnectTLSNoVerify
   153  	case "ip":
   154  		return valIP
   155  	case "wc2":
   156  		return valWC2
   157  	case "tls-ex":
   158  		return valTLSx
   159  	case "mtls":
   160  		return valMuTLS
   161  	case "tls-ca":
   162  		return valTLSxCA
   163  	case "tls-cert":
   164  		return valTLSCert
   165  	case "hex":
   166  		return WrapHex
   167  	case "zlib":
   168  		return WrapZlib
   169  	case "gzip":
   170  		return WrapGzip
   171  	case "base64":
   172  		return WrapBase64
   173  	case "xor":
   174  		return valXOR
   175  	case "cbk":
   176  		return valCBK
   177  	case "aes":
   178  		return valAES
   179  	case "b64t":
   180  		return TransformB64
   181  	case "dns":
   182  		return valDNS
   183  	case "b64s":
   184  		return valB64Shift
   185  	}
   186  	return invalid
   187  }
   188  
   189  // String returns a string representation of the data included in this Config
   190  // instance. Each separate setting will be seperated by commas.
   191  func (c Config) String() string {
   192  	if len(c) == 0 || c[0] == 0 {
   193  		return ""
   194  	}
   195  	var b util.Builder
   196  	for i, x := 0, cBit(c[0]); i >= 0 && i < len(c); {
   197  		b.WriteString(x.String())
   198  		if i = c.next(i); i < 0 || i >= len(c) {
   199  			break
   200  		}
   201  		if x == Separator {
   202  			x = cBit(c[i])
   203  			continue
   204  		}
   205  		if x = cBit(c[i]); i >= 0 && i < len(c) && x != Separator {
   206  			b.WriteByte(',')
   207  		}
   208  	}
   209  	return b.Output()
   210  }
   211  
   212  // JSON will combine the supplied settings into a JSON payload and returned in
   213  // a byte slice. This will return any validation errors during conversion.
   214  //
   215  // Not valid when the 'nojson' tag is specified.
   216  func JSON(s ...Setting) ([]byte, error) {
   217  	return json.Marshal(Pack(s...))
   218  }
   219  func parseDayString(s string) (uint8, error) {
   220  	if len(s) == 0 {
   221  		return 0, nil
   222  	}
   223  	if s == "SMTWRFS" {
   224  		return 0, nil
   225  	}
   226  	var d uint8
   227  	for i := range s {
   228  		switch s[i] {
   229  		case 's', 'S':
   230  			if i == 0 {
   231  				d |= DaySunday
   232  				break
   233  			}
   234  			d |= DaySaturday
   235  		case 'm', 'M':
   236  			d |= DayMonday
   237  		case 't', 'T':
   238  			d |= DayTuesday
   239  		case 'w', 'W':
   240  			d |= DayWednesday
   241  		case 'r', 'R':
   242  			d |= DayThursday
   243  		case 'f', 'F':
   244  			d |= DayFriday
   245  		default:
   246  			return 0, xerr.New("invalid day char")
   247  		}
   248  	}
   249  	return d, nil
   250  }
   251  
   252  // MarshalJSON will attempt to convert the raw binary data in this Config
   253  // instance into a JSON format.
   254  //
   255  // The only error that may occur is 'ErrInvalidSetting' if an invalid
   256  // setting or data value is encountered during conversion.
   257  func (c Config) MarshalJSON() ([]byte, error) {
   258  	var (
   259  		b util.Builder
   260  		x cBit
   261  	)
   262  	b.WriteByte('[')
   263  	for i, n, z := 0, 0, false; n >= 0 && n < len(c); i = n {
   264  		if i == 0 || x == Separator {
   265  			b.WriteByte('[')
   266  		}
   267  		if x = cBit(c[i]); x == invalid {
   268  			return nil, ErrInvalidSetting
   269  		}
   270  		if n = c.next(i); n == i || n > len(c) || n == -1 || n < i {
   271  			n = len(c)
   272  		}
   273  		if x == Separator {
   274  			if n == len(c) {
   275  				break
   276  			}
   277  			b.WriteString("],")
   278  			z = true
   279  			continue
   280  		}
   281  		if i > 0 && !z {
   282  			b.WriteByte(',')
   283  		}
   284  		b.WriteString(`{"type":"` + x.String() + `"`)
   285  		switch z = false; x {
   286  		case WrapHex, WrapZlib, WrapGzip, WrapBase64:
   287  			fallthrough
   288  		case SelectorLastValid, SelectorRoundRobin, SelectorRandom, SelectorSemiRandom, SelectorSemiRoundRobin:
   289  			fallthrough
   290  		case ConnectTCP, ConnectTLS, ConnectUDP, ConnectICMP, ConnectPipe, ConnectTLSNoVerify:
   291  			fallthrough
   292  		case TransformB64:
   293  			goto end
   294  		}
   295  		b.WriteString(`,"args":`)
   296  		switch _ = c[n-1]; x {
   297  		case valHost:
   298  			if i+3 >= n {
   299  				return nil, xerr.Wrap("host", ErrInvalidSetting)
   300  			}
   301  			v := (int(c[i+2]) | int(c[i+1])<<8) + i
   302  			if v > n || v < i {
   303  				return nil, xerr.Wrap("host", ErrInvalidSetting)
   304  			}
   305  			b.WriteString(escape.JSON(string(c[i+3 : v+3])))
   306  		case valSleep:
   307  			if i+8 >= n {
   308  				return nil, xerr.Wrap("sleep", ErrInvalidSetting)
   309  			}
   310  			b.WriteString(escape.JSON(time.Duration(
   311  				uint64(c[i+8]) | uint64(c[i+7])<<8 | uint64(c[i+6])<<16 | uint64(c[i+5])<<24 |
   312  					uint64(c[i+4])<<32 | uint64(c[i+3])<<40 | uint64(c[i+2])<<48 | uint64(c[i+1])<<56,
   313  			).String()))
   314  		case valKeyPin:
   315  			if i+4 >= n {
   316  				return nil, xerr.Wrap("keypin", ErrInvalidSetting)
   317  			}
   318  			b.WriteString(`"` + util.Uitoa16(uint64(c[i+4])|uint64(c[i+3])<<8|uint64(c[i+2])<<16|uint64(c[i+1])<<24) + `"`)
   319  		case valKillDate:
   320  			if i+8 >= n {
   321  				return nil, xerr.Wrap("killdate", ErrInvalidSetting)
   322  			}
   323  			u := uint64(c[i+8]) | uint64(c[i+7])<<8 | uint64(c[i+6])<<16 | uint64(c[i+5])<<24 |
   324  				uint64(c[i+4])<<32 | uint64(c[i+3])<<40 | uint64(c[i+2])<<48 | uint64(c[i+1])<<56
   325  			if u == 0 {
   326  				b.WriteString(`""`)
   327  			} else {
   328  				b.WriteString(`"` + time.Unix(int64(u), 0).Format(time.RFC3339) + `"`)
   329  			}
   330  		case valWorkHours:
   331  			if i+5 >= n {
   332  				return nil, xerr.Wrap("workhours", ErrInvalidSetting)
   333  			}
   334  			if b.WriteByte('{'); c[i+1] > 0 || c[i+2] > 0 || c[i+3] > 0 || c[i+4] > 0 || c[i+5] > 0 {
   335  				b.WriteString(
   336  					`"start_hour":` + util.Uitoa(uint64(c[i+2])) + `,` +
   337  						`"start_min":` + util.Uitoa(uint64(c[i+3])) + `,` +
   338  						`"end_hour":` + util.Uitoa(uint64(c[i+4])) + `,` +
   339  						`"end_min":` + util.Uitoa(uint64(c[i+5])) + `,` +
   340  						`"days":"` + dayNumToString(c[i+1]) + `"`,
   341  				)
   342  			}
   343  			b.WriteByte('}')
   344  		case valJitter, valWeight, valIP, valTLSx, valB64Shift:
   345  			if i+1 >= n {
   346  				return nil, ErrInvalidSetting
   347  			}
   348  			b.WriteString(util.Uitoa(uint64(c[i+1])))
   349  		case valWC2:
   350  			if i+7 >= n {
   351  				return nil, xerr.Wrap("wc2", ErrInvalidSetting)
   352  			}
   353  			var (
   354  				v, z = (int(c[i+2]) | int(c[i+1])<<8) + i + 8, i + 8
   355  				w    = v > 0
   356  			)
   357  			if v > n || z > n || z < i || v < i {
   358  				return nil, xerr.Wrap("wc2", ErrInvalidSetting)
   359  			}
   360  			if v > z {
   361  				b.WriteString(`{"url":` + escape.JSON(string(c[z:v])))
   362  			}
   363  			if v, z = (int(c[i+4])|int(c[i+3])<<8)+v, v; v > z {
   364  				if v > n || z > n || v < z || z < i || v < i {
   365  					return nil, xerr.Wrap("wc2", ErrInvalidSetting)
   366  				}
   367  				if !w {
   368  					w = true
   369  					b.WriteString(`{"host":`)
   370  				} else {
   371  					b.WriteString(`,"host":`)
   372  				}
   373  				b.WriteString(escape.JSON(string(c[z:v])))
   374  			}
   375  			if v, z = (int(c[i+6])|int(c[i+5])<<8)+v, v; v > z {
   376  				if v > n || z > n || v < z || z < i || v < i {
   377  					return nil, xerr.Wrap("wc2", ErrInvalidSetting)
   378  				}
   379  				if !w {
   380  					w = true
   381  					b.WriteString(`{"agent":`)
   382  				} else {
   383  					b.WriteString(`,"agent":`)
   384  				}
   385  				b.WriteString(escape.JSON(string(c[z:v])))
   386  			}
   387  			if c[i+7] == 0 {
   388  				b.WriteByte('}')
   389  				goto end
   390  			}
   391  			if !w {
   392  				b.WriteString(`{"headers":{`)
   393  			} else {
   394  				b.WriteString(`,"headers":{`)
   395  			}
   396  			for j := 0; v < n && z < n && j < n; {
   397  				if j > 0 {
   398  					b.WriteByte(',')
   399  				}
   400  				z, j = v+2, int(c[v])+v+2
   401  				if v = int(c[v+1]) + j; z == j || z > n || j > n || v > n || v < j || j < z || z < i || j < i || v < i {
   402  					return nil, xerr.Wrap("wc2", ErrInvalidSetting)
   403  				}
   404  				b.WriteString(escape.JSON(string(c[z:j])))
   405  				b.WriteByte(':')
   406  				b.WriteString(escape.JSON(string(c[j:v])))
   407  			}
   408  			b.WriteString("}}")
   409  		case valMuTLS:
   410  			if i+7 >= n {
   411  				return nil, xerr.Wrap("mtls", ErrInvalidSetting)
   412  			}
   413  			var (
   414  				a = (int(c[i+3]) | int(c[i+2])<<8) + i + 8
   415  				p = (int(c[i+5]) | int(c[i+4])<<8) + a
   416  				k = (int(c[i+7]) | int(c[i+6])<<8) + p
   417  			)
   418  			if a > n || p > n || k > n || p < a || k < p || a < i || p < i || k < i {
   419  				return nil, xerr.Wrap("mtls", ErrInvalidSetting)
   420  			}
   421  			b.WriteString(`{"version":` + util.Uitoa(uint64(c[i+1])))
   422  			b.WriteString(`,"ca":"`)
   423  			e := base64.NewEncoder(base64.StdEncoding, &b)
   424  			e.Write(c[i+8 : a])
   425  			e.Close()
   426  			b.WriteString(`","pem":"`)
   427  			e = base64.NewEncoder(base64.StdEncoding, &b)
   428  			e.Write(c[a:p])
   429  			e.Close()
   430  			b.WriteString(`","key":"`)
   431  			e = base64.NewEncoder(base64.StdEncoding, &b)
   432  			e.Write(c[p:k])
   433  			e.Close()
   434  			b.WriteString(`"}`)
   435  		case valTLSxCA:
   436  			if i+4 >= n {
   437  				return nil, xerr.Wrap("tls-ca", ErrInvalidSetting)
   438  			}
   439  			a := (int(c[i+3]) | int(c[i+2])<<8) + i + 4
   440  			if a > n || a < i {
   441  				return nil, xerr.Wrap("tls-ca", ErrInvalidSetting)
   442  			}
   443  			b.WriteString(`{"version":` + util.Uitoa(uint64(c[i+1])))
   444  			b.WriteString(`,"ca":"`)
   445  			e := base64.NewEncoder(base64.StdEncoding, &b)
   446  			e.Write(c[i+4 : a])
   447  			e.Close()
   448  			b.WriteString(`"}`)
   449  		case valTLSCert:
   450  			if i+6 >= n {
   451  				return nil, xerr.Wrap("tls-cert", ErrInvalidSetting)
   452  			}
   453  			var (
   454  				p = (int(c[i+3]) | int(c[i+2])<<8) + i + 6
   455  				k = (int(c[i+5]) | int(c[i+4])<<8) + p
   456  			)
   457  			if p > n || k > n || p < i || k < i || k < p {
   458  				return nil, xerr.Wrap("tls-cert", ErrInvalidSetting)
   459  			}
   460  			b.WriteString(`{"version":` + util.Uitoa(uint64(c[i+1])))
   461  			b.WriteString(`,"pem":"`)
   462  			e := base64.NewEncoder(base64.StdEncoding, &b)
   463  			e.Write(c[i+6 : p])
   464  			e.Close()
   465  			b.WriteString(`","key":"`)
   466  			e = base64.NewEncoder(base64.StdEncoding, &b)
   467  			e.Write(c[p:k])
   468  			e.Close()
   469  			b.WriteString(`"}`)
   470  		case valXOR:
   471  			if i+3 >= n {
   472  				return nil, xerr.Wrap("xor", ErrInvalidSetting)
   473  			}
   474  			b.WriteByte('"')
   475  			var (
   476  				e = base64.NewEncoder(base64.StdEncoding, &b)
   477  				k = (int(c[i+2]) | int(c[i+1])<<8) + i
   478  			)
   479  			if k > n || k < i {
   480  				return nil, xerr.Wrap("xor", ErrInvalidSetting)
   481  			}
   482  			e.Write(c[i+3 : k+3])
   483  			e.Close()
   484  			b.WriteByte('"')
   485  		case valCBK:
   486  			if i+5 >= n {
   487  				return nil, xerr.Wrap("cbk", ErrInvalidSetting)
   488  			}
   489  			b.WriteString(`{"size":`)
   490  			b.WriteString(util.Uitoa(uint64(c[i+1])))
   491  			b.WriteString(`,"A":`)
   492  			b.WriteString(util.Uitoa(uint64(c[i+2])))
   493  			b.WriteString(`,"B":`)
   494  			b.WriteString(util.Uitoa(uint64(c[i+3])))
   495  			b.WriteString(`,"C":`)
   496  			b.WriteString(util.Uitoa(uint64(c[i+4])))
   497  			b.WriteString(`,"D":`)
   498  			b.WriteString(util.Uitoa(uint64(c[i+5])))
   499  			b.WriteByte('}')
   500  		case valAES:
   501  			if i+3 >= n {
   502  				return nil, xerr.Wrap("aes", ErrInvalidSetting)
   503  			}
   504  			var (
   505  				v = int(c[i+1]) + i + 3
   506  				z = int(c[i+2]) + v
   507  			)
   508  			if v == z || i+3 == v || v > n || z > n || z < i || v < i || z < v {
   509  				return nil, xerr.Wrap("aes", ErrInvalidSetting)
   510  			}
   511  			b.WriteString(`{"key":"`)
   512  			e := base64.NewEncoder(base64.StdEncoding, &b)
   513  			e.Write(c[i+3 : v])
   514  			e.Close()
   515  			b.WriteString(`","iv":"`)
   516  			e = base64.NewEncoder(base64.StdEncoding, &b)
   517  			e.Write(c[v:z])
   518  			e.Close()
   519  			b.WriteString(`"}`)
   520  		case valDNS:
   521  			if i+1 >= n {
   522  				return nil, xerr.Wrap("dns", ErrInvalidSetting)
   523  			}
   524  			_ = c[i+1]
   525  			b.WriteByte('[')
   526  			for x, v, e := int(c[i+1]), i+2, i+2; x > 0 && v < n; x-- {
   527  				if v += int(c[v]) + 1; e+1 > v || e+1 == v || v < e || v > n || e > n || x > n || e < i || v < i || x < i {
   528  					return nil, xerr.Wrap("dns", ErrInvalidSetting)
   529  				}
   530  				if x != int(c[i+1]) {
   531  					b.WriteByte(',')
   532  				}
   533  				b.WriteString(escape.JSON(string(c[e+1 : v])))
   534  				e = v
   535  			}
   536  			b.WriteByte(']')
   537  		}
   538  	end:
   539  		b.WriteByte('}')
   540  	}
   541  	b.WriteString("]]")
   542  	return []byte(b.Output()), nil
   543  }
   544  
   545  // UnmarshalJSON will attempt to convert the JSON data provided into this Config
   546  // instance.
   547  //
   548  // Errors during parsing or formatting will be returned along with the
   549  // 'ErrInvalidSetting' error if parsed data contains invalid values.
   550  func (c *Config) UnmarshalJSON(b []byte) error {
   551  	var h []json.RawMessage
   552  	if err := json.Unmarshal(b, &h); err != nil {
   553  		return err
   554  	}
   555  	if len(h) == 0 {
   556  		return nil
   557  	}
   558  	r := make([]Setting, 0, len(h)*4)
   559  	for k := range h {
   560  		var m []config
   561  		if err := json.Unmarshal(h[k], &m); err != nil {
   562  			return err
   563  		}
   564  		if len(m) == 0 {
   565  			continue
   566  		}
   567  		for i := range m {
   568  			switch x := bitFromName(m[i].Type); x {
   569  			case invalid:
   570  				return ErrInvalidSetting
   571  			case WrapHex, WrapZlib, WrapGzip, WrapBase64:
   572  				fallthrough
   573  			case SelectorLastValid, SelectorRoundRobin, SelectorRandom, SelectorSemiRandom, SelectorSemiRoundRobin:
   574  				fallthrough
   575  			case ConnectTCP, ConnectTLS, ConnectUDP, ConnectICMP, ConnectPipe, ConnectTLSNoVerify:
   576  				fallthrough
   577  			case TransformB64:
   578  				r = append(r, x)
   579  			case valHost:
   580  				var s string
   581  				if err := json.Unmarshal(m[i].Args, &s); err != nil {
   582  					return xerr.Wrap("host", err)
   583  				}
   584  				r = append(r, Host(s))
   585  			case valSleep:
   586  				var s string
   587  				if err := json.Unmarshal(m[i].Args, &s); err != nil {
   588  					return xerr.Wrap("sleep", err)
   589  				}
   590  				d, err := time.ParseDuration(s)
   591  				if err != nil {
   592  					return xerr.Wrap("sleep", err)
   593  				}
   594  				r = append(r, Sleep(d))
   595  			case valJitter:
   596  				var v uint8
   597  				if err := json.Unmarshal(m[i].Args, &v); err != nil {
   598  					return xerr.Wrap("jitter", err)
   599  				}
   600  				r = append(r, cBytes{byte(valJitter), v})
   601  			case valWeight:
   602  				var v uint8
   603  				if err := json.Unmarshal(m[i].Args, &v); err != nil {
   604  					return xerr.Wrap("weight", err)
   605  				}
   606  				r = append(r, cBytes{byte(valWeight), v})
   607  			case valKeyPin:
   608  				var s string
   609  				if err := json.Unmarshal(m[i].Args, &s); err != nil {
   610  					return xerr.Wrap("keypin", err)
   611  				}
   612  				v, err := strconv.ParseUint(s, 16, 32)
   613  				if err != nil {
   614  					return xerr.Wrap("keypin", err)
   615  				}
   616  				r = append(r, cBytes{byte(valKeyPin), byte(v >> 24), byte(v >> 16), byte(v >> 8), byte(v)})
   617  			case valKillDate:
   618  				var s string
   619  				if err := json.Unmarshal(m[i].Args, &s); err != nil {
   620  					return xerr.Wrap("killdate", err)
   621  				}
   622  				if len(s) == 0 {
   623  					r = append(r, cBytes{byte(valKillDate), 0, 0, 0, 0, 0, 0, 0, 0})
   624  				} else {
   625  					t, err := time.Parse(time.RFC3339, s)
   626  					if err != nil {
   627  						return xerr.Wrap("killdate", err)
   628  					}
   629  					v := t.Unix()
   630  					r = append(r, cBytes{
   631  						byte(valKillDate), byte(v >> 56), byte(v >> 48), byte(v >> 40), byte(v >> 32),
   632  						byte(v >> 24), byte(v >> 16), byte(v >> 8), byte(v),
   633  					})
   634  				}
   635  			case valWorkHours:
   636  				var z mapper
   637  				if err := json.Unmarshal(m[i].Args, &z); err != nil {
   638  					return xerr.Wrap("workhours", err)
   639  				}
   640  				var (
   641  					s, y, u, j uint8
   642  					k          string
   643  				)
   644  				if err := z.Unmarshal("days", false, &k); err != nil {
   645  					return err
   646  				}
   647  				if err := z.Unmarshal("start_hour", false, &s); err != nil {
   648  					return err
   649  				}
   650  				if err := z.Unmarshal("start_min", false, &y); err != nil {
   651  					return err
   652  				}
   653  				if err := z.Unmarshal("end_hour", false, &u); err != nil {
   654  					return err
   655  				}
   656  				if err := z.Unmarshal("end_min", false, &j); err != nil {
   657  					return err
   658  				}
   659  				d, err := parseDayString(k)
   660  				if err != nil {
   661  					return xerr.Wrap("workhours", err)
   662  				}
   663  				if s > 23 || y > 59 || u > 23 || j > 59 {
   664  					return xerr.Wrap("workhours", ErrInvalidSetting)
   665  				}
   666  				r = append(r, cBytes{byte(valWorkHours), d, s, y, u, j})
   667  			case valIP:
   668  				var v uint8
   669  				if err := json.Unmarshal(m[i].Args, &v); err != nil {
   670  					return xerr.Wrap("ip", err)
   671  				}
   672  				r = append(r, cBytes{byte(valIP), v})
   673  			case valWC2:
   674  				var z mapper
   675  				if err := json.Unmarshal(m[i].Args, &z); err != nil {
   676  					return xerr.Wrap("wc2", err)
   677  				}
   678  				var (
   679  					u, h, a string
   680  					j       map[string]string
   681  				)
   682  				if err := z.Unmarshal("url", false, &u); err != nil {
   683  					return err
   684  				}
   685  				if err := z.Unmarshal("host", false, &h); err != nil {
   686  					return err
   687  				}
   688  				if err := z.Unmarshal("agent", false, &a); err != nil {
   689  					return err
   690  				}
   691  				if d, ok := z["headers"]; ok {
   692  					if err := json.Unmarshal(d, &j); err != nil {
   693  						return xerr.Wrap("wc2", err)
   694  					}
   695  					for v := range j {
   696  						if len(v) == 0 {
   697  							return xerr.Wrap("wc2", ErrInvalidSetting)
   698  						}
   699  					}
   700  				}
   701  				r = append(r, ConnectWC2(u, h, a, j))
   702  			case valTLSx:
   703  				var v uint8
   704  				if err := json.Unmarshal(m[i].Args, &v); err != nil {
   705  					return xerr.Wrap("tls-ex", err)
   706  				}
   707  				r = append(r, cBytes{byte(valTLSx), v})
   708  			case valMuTLS:
   709  				var z mapper
   710  				if err := json.Unmarshal(m[i].Args, &z); err != nil {
   711  					return xerr.Wrap("mtls", err)
   712  				}
   713  				var (
   714  					a, p, k []byte
   715  					v       uint16
   716  				)
   717  				if err := z.Unmarshal("ca", false, &a); err != nil {
   718  					return xerr.Wrap("mtls", err)
   719  				}
   720  				if err := z.Unmarshal("pem", true, &p); err != nil {
   721  					return xerr.Wrap("mtls", err)
   722  				}
   723  				if err := z.Unmarshal("key", true, &k); err != nil {
   724  					return xerr.Wrap("mtls", err)
   725  				}
   726  				if d, ok := z["version"]; ok {
   727  					if err := json.Unmarshal(d, &v); err != nil {
   728  						return xerr.Wrap("mtls", err)
   729  					}
   730  				}
   731  				r = append(r, ConnectMuTLS(v, a, p, k))
   732  			case valTLSxCA:
   733  				var z mapper
   734  				if err := json.Unmarshal(m[i].Args, &z); err != nil {
   735  					return xerr.Wrap("tls-ca", err)
   736  				}
   737  				var (
   738  					a []byte
   739  					v uint16
   740  				)
   741  				if err := z.Unmarshal("ca", false, &a); err != nil {
   742  					return xerr.Wrap("tls-ca", err)
   743  				}
   744  				if d, ok := z["version"]; ok {
   745  					if err := json.Unmarshal(d, &v); err != nil {
   746  						return xerr.Wrap("tls-ca", err)
   747  					}
   748  				}
   749  				r = append(r, ConnectTLSExCA(v, a))
   750  			case valTLSCert:
   751  				var z mapper
   752  				if err := json.Unmarshal(m[i].Args, &z); err != nil {
   753  					return xerr.Wrap("tls-cert", err)
   754  				}
   755  				var (
   756  					p, k []byte
   757  					v    uint16
   758  				)
   759  				if err := z.Unmarshal("pem", true, &p); err != nil {
   760  					return xerr.Wrap("tls-cert", err)
   761  				}
   762  				if err := z.Unmarshal("key", true, &k); err != nil {
   763  					return xerr.Wrap("tls-cert", err)
   764  				}
   765  				if d, ok := z["version"]; ok {
   766  					if err := json.Unmarshal(d, &v); err != nil {
   767  						return xerr.Wrap("tls-cert", err)
   768  					}
   769  				}
   770  				r = append(r, ConnectTLSCerts(v, p, k))
   771  			case valXOR:
   772  				var (
   773  					v      = make([]byte, base64.StdEncoding.DecodedLen(len(m[i].Args)-2))
   774  					n, err = base64.StdEncoding.Decode(v, m[i].Args[1:len(m[i].Args)-1])
   775  				)
   776  				if err != nil {
   777  					return xerr.Wrap("xor", err)
   778  				}
   779  				r = append(r, WrapXOR(v[:n]))
   780  			case valCBK:
   781  				var z mapper
   782  				if err := json.Unmarshal(m[i].Args, &z); err != nil {
   783  					return xerr.Wrap("cbk", err)
   784  				}
   785  				var e, t, y, u, s uint8 = 0, 0, 0, 0, 128
   786  				if d, ok := z["size"]; ok {
   787  					if err := json.Unmarshal(d, &s); err != nil {
   788  						return xerr.Wrap("cbk", err)
   789  					}
   790  				}
   791  				if err := z.Unmarshal("A", true, &e); err != nil {
   792  					return xerr.Wrap("cbk", err)
   793  				}
   794  				if err := z.Unmarshal("B", true, &t); err != nil {
   795  					return xerr.Wrap("cbk", err)
   796  				}
   797  				if err := z.Unmarshal("C", true, &y); err != nil {
   798  					return xerr.Wrap("cbk", err)
   799  				}
   800  				if err := z.Unmarshal("D", true, &u); err != nil {
   801  					return xerr.Wrap("cbk", err)
   802  				}
   803  				r = append(r, cBytes{byte(valCBK), s, e, t, y, u})
   804  			case valAES:
   805  				var z mapper
   806  				if err := json.Unmarshal(m[i].Args, &z); err != nil {
   807  					return xerr.Wrap("aes", err)
   808  				}
   809  				var k, v []byte
   810  				if err := z.Unmarshal("iv", true, &v); err != nil {
   811  					return xerr.Wrap("aes", err)
   812  				}
   813  				if err := z.Unmarshal("key", true, &k); err != nil {
   814  					return xerr.Wrap("aes", err)
   815  				}
   816  				r = append(r, WrapAES(k, v))
   817  			case valDNS:
   818  				var d []string
   819  				if err := json.Unmarshal(m[i].Args, &d); err != nil {
   820  					return xerr.Wrap("dns", err)
   821  				}
   822  				r = append(r, TransformDNS(d...))
   823  			case valB64Shift:
   824  				var v uint8
   825  				if err := json.Unmarshal(m[i].Args, &v); err != nil {
   826  					return xerr.Wrap("b64S", err)
   827  				}
   828  				r = append(r, cBytes{byte(valB64Shift), v})
   829  			}
   830  		}
   831  		if k+1 < len(h) {
   832  			r = append(r, Separator)
   833  		}
   834  	}
   835  	*c = Bytes(r...)
   836  	return nil
   837  }
   838  func (c *config) UnmarshalJSON(b []byte) error {
   839  	var m map[string]json.RawMessage
   840  	if err := json.Unmarshal(b, &m); err != nil {
   841  		return err
   842  	}
   843  	v, ok := m["type"]
   844  	if !ok {
   845  		return xerr.Sub(`missing "type" string`, 0x61)
   846  	}
   847  	if err := json.Unmarshal(v, &c.Type); err != nil {
   848  		return err
   849  	}
   850  	if v, ok = m["args"]; ok {
   851  		if err := json.Unmarshal(v, &c.Args); err != nil {
   852  			return err
   853  		}
   854  	}
   855  	return nil
   856  }
   857  func (m mapper) Unmarshal(s string, r bool, v interface{}) error {
   858  	d, ok := m[s]
   859  	if !ok {
   860  		if !r {
   861  			return nil
   862  		}
   863  		if xerr.ExtendedInfo {
   864  			return xerr.Sub(`"`+s+`" not found`, 0x62)
   865  		}
   866  		return xerr.Sub("key not found", 0x62)
   867  	}
   868  	return json.Unmarshal(d, v)
   869  }