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

     1  // Copyright (C) 2020 - 2023 iDigitalFlame
     2  //
     3  // This program is free software: you can redistribute it and/or modify
     4  // it under the terms of the GNU General Public License as published by
     5  // the Free Software Foundation, either version 3 of the License, or
     6  // any later version.
     7  //
     8  // This program is distributed in the hope that it will be useful,
     9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    11  // GNU General Public License for more details.
    12  //
    13  // You should have received a copy of the GNU General Public License
    14  // along with this program.  If not, see <https://www.gnu.org/licenses/>.
    15  //
    16  
    17  package cfg
    18  
    19  const (
    20  	// ConnectTCP will provide a TCP connection setting to the generated Profile.
    21  	//
    22  	// If multiple connections are contained in the current Config Group, a
    23  	// 'ErrMultipleConnections' error will be returned during a build.
    24  	ConnectTCP = cBit(0xC0)
    25  	// ConnectTLS will provide a TLS over TCP connection setting to the generated
    26  	// Profile.
    27  	//
    28  	// If multiple connections are contained in the current Config Group, a
    29  	// 'ErrMultipleConnections' error will be returned during a build.
    30  	//
    31  	// This hint cannot be used as a Listener.
    32  	ConnectTLS = cBit(0xC1)
    33  	// ConnectUDP will provide a UCO connection setting to the generated Profile.
    34  	//
    35  	// If multiple connections are contained in the current Config Group, a
    36  	// 'ErrMultipleConnections' error will be returned during a build.
    37  	ConnectUDP = cBit(0xC2)
    38  	// ConnectICMP will provide a ICMP connection setting to the generated Profile.
    39  	//
    40  	// If multiple connections are contained in the current Config Group, a
    41  	// 'ErrMultipleConnections' error will be returned during a build.
    42  	ConnectICMP = cBit(0xC3)
    43  	// ConnectPipe will provide a Pipe connection setting to the generated Profile.
    44  	//
    45  	// If multiple connections are contained in the current Config Group, a
    46  	// 'ErrMultipleConnections' error will be returned during a build.
    47  	ConnectPipe = cBit(0xC4)
    48  	// ConnectTLSNoVerify will provide a TLS over TCP connection setting to the
    49  	// generated Profile.
    50  	//
    51  	// If multiple connections are contained in the current Config Group, a
    52  	// 'ErrMultipleConnections' error will be returned during a build.
    53  	//
    54  	// This hint cannot be used as a Listener.
    55  	ConnectTLSNoVerify = cBit(0xC5)
    56  )
    57  
    58  const (
    59  	valIP      = cBit(0xB0)
    60  	valWC2     = cBit(0xB1)
    61  	valTLSx    = cBit(0xB2)
    62  	valMuTLS   = cBit(0xB3)
    63  	valTLSxCA  = cBit(0xB4)
    64  	valTLSCert = cBit(0xB5)
    65  )
    66  
    67  // ConnectIP will provide an IP connection setting to the generated Profile with
    68  // the specified protocol number.
    69  //
    70  // If multiple connections are contained in the current Config Group, a
    71  // 'ErrMultipleConnections' error will be returned during a build.
    72  func ConnectIP(p uint) Setting {
    73  	return &cBytes{byte(valIP), byte(p)}
    74  }
    75  
    76  // ConnectTLSEx will provide a TLS connection setting to the generated Profile
    77  // with the specified TLS minimum version specified. Using the version value '0'
    78  // will use the system default (same as the ConnectTLS option).
    79  //
    80  // If multiple connections are contained in the current Config Group, a
    81  // 'ErrMultipleConnections' error will be returned during a build.
    82  //
    83  // This hint cannot be used as a Listener.
    84  func ConnectTLSEx(ver uint16) Setting {
    85  	return &cBytes{byte(valTLSx), byte(ver & 0xFF)}
    86  }
    87  
    88  // ConnectTLSExCA will provide a TLS connection setting to the generated Profile
    89  // with the specified TLS minimum version and will use the specified PEM bytes
    90  // as the Root CA to trust when connecting.
    91  //
    92  // Using the version value '0' will use the system default (same as the ConnectTLS
    93  // option). Empty PEM blocks will default to system root CAs.
    94  //
    95  // If multiple connections are contained in the current Config Group, a
    96  // 'ErrMultipleConnections' error will be returned during a build.
    97  //
    98  // This hint cannot be used as a Listener.
    99  func ConnectTLSExCA(ver uint16, ca []byte) Setting {
   100  	a := len(ca)
   101  	if a > 0xFFFF {
   102  		a = 0xFFFF
   103  	}
   104  	c := make(cBytes, 4+a)
   105  	_ = c[3+a]
   106  	c[0], c[1] = byte(valTLSxCA), byte(ver&0xFF)
   107  	c[2], c[3] = byte(a>>8), byte(a)
   108  	copy(c[4:], ca[:a])
   109  	return &c
   110  }
   111  
   112  // ConnectTLSCerts will provide a TLS connection setting to the generated Profile
   113  // with the specified TLS config that will allow for a Listener to use the
   114  // specified PEM and Private Key data in PEM format for listening.
   115  //
   116  // This will also work as a Connector and can use the specified certificate for
   117  // TLS authentication.
   118  //
   119  // Using the version value '0' will use the system default (same as the ConnectTLS
   120  // option). Empty PEM blocks will render and error on build.
   121  //
   122  // If multiple connections are contained in the current Config Group, a
   123  // 'ErrMultipleConnections' error will be returned during a build.
   124  func ConnectTLSCerts(ver uint16, pem, key []byte) Setting {
   125  	p, k := len(pem), len(key)
   126  	if p > 0xFFFF {
   127  		p = 0xFFFF
   128  	}
   129  	if k > 0xFFFF {
   130  		k = 0xFFFF
   131  	}
   132  	c := make(cBytes, 6+p+k)
   133  	_ = c[5+p+k]
   134  	c[0], c[1] = byte(valTLSCert), byte(ver&0xFF)
   135  	c[2], c[3] = byte(p>>8), byte(p)
   136  	c[4], c[5] = byte(k>>8), byte(k)
   137  	n := copy(c[6:], pem[:p]) + 6
   138  	copy(c[n:], key[:p])
   139  	return &c
   140  }
   141  
   142  // ConnectMuTLS will provide a TLS connection setting to the generated Profile
   143  // with the specified TLS config that will allow for a complete mTLS setup.
   144  //
   145  // This can be used for Listeners and Connectors, but the CA PEM data provided
   146  // MUST be able to validate the client certificates, otherwise connections will
   147  // fail.
   148  //
   149  // Using the version value '0' will use the system default (same as the ConnectTLS
   150  // option). Empty PEM blocks will render and error on build.
   151  //
   152  // If multiple connections are contained in the current Config Group, a
   153  // 'ErrMultipleConnections' error will be returned during a build.
   154  func ConnectMuTLS(ver uint16, ca, pem, key []byte) Setting {
   155  	a, p, k := len(ca), len(pem), len(key)
   156  	if a > 0xFFFF {
   157  		a = 0xFFFF
   158  	}
   159  	if p > 0xFFFF {
   160  		p = 0xFFFF
   161  	}
   162  	if k > 0xFFFF {
   163  		k = 0xFFFF
   164  	}
   165  	c := make(cBytes, 8+a+p+k)
   166  	_ = c[7+a+p+k]
   167  	c[0], c[1] = byte(valMuTLS), byte(ver&0xFF)
   168  	c[2], c[3] = byte(a>>8), byte(a)
   169  	c[4], c[5] = byte(p>>8), byte(p)
   170  	c[6], c[7] = byte(k>>8), byte(k)
   171  	n := copy(c[8:], ca[:a]) + 8
   172  	n += copy(c[n:], pem[:p])
   173  	copy(c[n:], key)
   174  	return &c
   175  }
   176  
   177  // ConnectWC2 will provide a WebC2 connection setting to the generated Profile
   178  // with the specified User-Agent, URL and Host Matcher strings (strings can be empty).
   179  //
   180  // If multiple connections are contained in the current Config Group, a
   181  // 'ErrMultipleConnections' error will be returned during a build.
   182  //
   183  // This hint cannot be used as a Listener.
   184  func ConnectWC2(url, host, agent string, headers map[string]string) Setting {
   185  	if len(url) > 0xFFFF {
   186  		url = url[:0xFFFF]
   187  	}
   188  	if len(host) > 0xFFFF {
   189  		host = host[:0xFFFF]
   190  	}
   191  	if len(agent) > 0xFFFF {
   192  		agent = agent[:0xFFFF]
   193  	}
   194  	c := make(cBytes, len(url)+len(host)+len(agent)+8)
   195  	_ = c[len(url)+len(host)+len(agent)+7]
   196  	c[0] = byte(valWC2)
   197  	c[1], c[2] = byte(len(url)>>8), byte(len(url))
   198  	c[3], c[4] = byte(len(host)>>8), byte(len(host))
   199  	c[5], c[6] = byte(len(agent)>>8), byte(len(agent))
   200  	c[7] = byte(len(headers))
   201  	n := copy(c[8:], url) + 8
   202  	n += copy(c[n:], host)
   203  	if copy(c[n:], agent); len(headers) == 0 {
   204  		return c
   205  	}
   206  	i := 0
   207  	for k, v := range headers {
   208  		if i >= 0xFF {
   209  			break
   210  		}
   211  		if len(k) > 0xFF {
   212  			k = k[:0xFF]
   213  		}
   214  		if len(v) > 0xFF {
   215  			v = v[:0xFF]
   216  		}
   217  		c = append(c, byte(len(k)), byte(len(v)))
   218  		c = append(c, []byte(k)...)
   219  		c = append(c, []byte(v)...)
   220  		i++
   221  	}
   222  	return &c
   223  }