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 }