Skip to content

Commit cef9524

Browse files
committed
Merge branch 'master' into hoverpy
Update after two months of cbapi development
2 parents 1b394c6 + d3e07a0 commit cef9524

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1502
-466
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Python bindings for Carbon Black REST API
22

3-
**Current version: 1.2.0**
3+
**Current version: 1.3.4**
44

55
[![Build Status](https://travis-ci.org/carbonblack/cbapi-python.svg?branch=master)](https://travis-ci.org/carbonblack/cbapi-python)
66

@@ -29,8 +29,8 @@ Backwards compatibility with old scripts is maintained through the `cbapi.legacy
2929
`cbapi.CbApi` directly will continue to work. Once cbapi 2.0.0 is released, the old `CbApi` will be deprecated and
3030
removed entirely no earlier than January 2017.
3131

32-
New scripts should use the `cbapi.CbEnterpriseResponseAPI` (for Carbon Black "Enterprise Response") and
33-
`cbapi.CbEnterpriseProtectionAPI` (for Carbon Black "Enterprise Protection" / former Bit9) API entry points.
32+
New scripts should use the `cbapi.CbResponseAPI` (for Cb Response) and
33+
`cbapi.CbProtectionAPI` (for Cb Protection / former Bit9) API entry points.
3434

3535
## Getting Started
3636

bin/cbapi

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env python
2+
3+
import argparse
4+
import contextlib
5+
6+
from cbapi.six import iteritems
7+
import sys
8+
from cbapi.utils import check_python_tls_compatibility
9+
10+
11+
def check_tls(opts):
12+
print("Newest TLS version supported by this platform is: {0}.".format(check_python_tls_compatibility()))
13+
14+
15+
command_map = {
16+
"check-tls": {
17+
"extra_args": {},
18+
"help": "Return the latest version of TLS supported by this version of Python and OpenSSL. "
19+
"Cb Response versions 6.1+ now require TLSv1.2 support.",
20+
"method": check_tls
21+
}
22+
}
23+
24+
25+
def main(args):
26+
parser = argparse.ArgumentParser()
27+
commands = parser.add_subparsers(dest="command_name", help="CbAPI subcommand")
28+
29+
for cmd_name, cmd_config in iteritems(command_map):
30+
cmd_parser = commands.add_parser(cmd_name, help=cmd_config.get("help", None))
31+
for cmd_arg_name, cmd_arg_config in iteritems(cmd_config.get("extra_args", {})):
32+
cmd_parser.add_argument(cmd_arg_name, **cmd_arg_config)
33+
34+
opts = parser.parse_args(args)
35+
command = command_map.get(opts.command_name)
36+
if not command:
37+
parser.print_usage()
38+
return
39+
40+
command_method = command.get("method", None)
41+
if command_method:
42+
return command_method(opts)
43+
else:
44+
parser.print_usage()
45+
46+
47+
if __name__ == '__main__':
48+
sys.exit(main(sys.argv[1:]))

bin/cbapi-defense

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,93 @@
11
#!/usr/bin/env python
22

3-
from cbapi.defense.cli import main
3+
import argparse
4+
import contextlib
5+
6+
from cbapi.six import iteritems
7+
from cbapi.six.moves import input
8+
import os
49
import sys
10+
import cbapi.six as six
11+
if six.PY3:
12+
from io import StringIO as StringIO
13+
else:
14+
from cStringIO import StringIO
15+
16+
from cbapi.six.moves.configparser import RawConfigParser
17+
18+
19+
@contextlib.contextmanager
20+
def temp_umask(umask):
21+
oldmask = os.umask(umask)
22+
try:
23+
yield
24+
finally:
25+
os.umask(oldmask)
26+
27+
28+
def configure(opts):
29+
credential_path = os.path.join(os.path.expanduser("~"), ".carbonblack")
30+
credential_file = os.path.join(credential_path, "credentials.defense")
31+
32+
print("Welcome to the CbAPI.")
33+
if os.path.exists(credential_file):
34+
print("An existing credential file exists at {0}.".format(credential_file))
35+
resp = input("Do you want to continue and overwrite the existing configuration? [Y/N] ")
36+
if resp.strip().upper() != "Y":
37+
print("Exiting.")
38+
return 1
39+
40+
if not os.path.exists(credential_path):
41+
os.makedirs(credential_path, 0o700)
42+
43+
url = input("URL to the Cb Defense API server (do not include '/integrationServices') [https://hostname]: ")
44+
45+
ssl_verify = True
46+
47+
connector_id = input("Connector ID: ")
48+
token = input("API key: ")
49+
50+
config = RawConfigParser()
51+
config.readfp(StringIO('[default]'))
52+
config.set("default", "url", url)
53+
config.set("default", "token", "{0}/{1}".format(token, connector_id))
54+
config.set("default", "ssl_verify", ssl_verify)
55+
with temp_umask(0):
56+
with os.fdopen(os.open(credential_file, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0o600), 'w') as fp:
57+
os.chmod(credential_file, 0o600)
58+
config.write(fp)
59+
print("Successfully wrote credentials to {0}.".format(credential_file))
60+
61+
62+
command_map = {
63+
"configure": {
64+
"extra_args": {},
65+
"help": "Configure CbAPI",
66+
"method": configure
67+
}
68+
}
69+
70+
71+
def main(args):
72+
parser = argparse.ArgumentParser()
73+
commands = parser.add_subparsers(dest="command_name", help="CbAPI subcommand")
74+
75+
for cmd_name, cmd_config in iteritems(command_map):
76+
cmd_parser = commands.add_parser(cmd_name, help=cmd_config.get("help", None))
77+
for cmd_arg_name, cmd_arg_config in iteritems(cmd_config.get("extra_args", {})):
78+
cmd_parser.add_argument(cmd_arg_name, **cmd_arg_config)
79+
80+
opts = parser.parse_args(args)
81+
command = command_map.get(opts.command_name)
82+
if not command:
83+
parser.print_usage()
84+
return
85+
86+
command_method = command.get("method", None)
87+
if command_method:
88+
return command_method(opts)
89+
else:
90+
parser.print_usage()
591

692

793
if __name__ == '__main__':

bin/cbapi-protection

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,100 @@
11
#!/usr/bin/env python
22

3-
from cbapi.protection.cli import main
3+
import argparse
4+
import contextlib
5+
6+
from cbapi.six import iteritems
7+
from cbapi.six.moves import input
8+
import os
49
import sys
10+
import cbapi.six as six
11+
if six.PY3:
12+
from io import StringIO as StringIO
13+
else:
14+
from cStringIO import StringIO
15+
16+
from cbapi.six.moves.configparser import RawConfigParser
17+
18+
19+
@contextlib.contextmanager
20+
def temp_umask(umask):
21+
oldmask = os.umask(umask)
22+
try:
23+
yield
24+
finally:
25+
os.umask(oldmask)
26+
27+
28+
def configure(opts):
29+
credential_path = os.path.join(os.path.expanduser("~"), ".carbonblack")
30+
credential_file = os.path.join(credential_path, "credentials.protection")
31+
32+
print("Welcome to the CbAPI.")
33+
if os.path.exists(credential_file):
34+
print("An existing credential file exists at {0}.".format(credential_file))
35+
resp = input("Do you want to continue and overwrite the existing configuration? [Y/N] ")
36+
if resp.strip().upper() != "Y":
37+
print("Exiting.")
38+
return 1
39+
40+
if not os.path.exists(credential_path):
41+
os.makedirs(credential_path, 0o700)
42+
43+
url = input("URL to the Cb Protection server [https://hostname]: ")
44+
45+
ssl_verify = None
46+
while ssl_verify not in ["Y", "N"]:
47+
ssl_verify = input("Use SSL/TLS certificate validation (answer 'N' if using self-signed certs) [Y/N]: ")
48+
ssl_verify = ssl_verify.strip().upper()
49+
50+
if ssl_verify == "Y":
51+
ssl_verify = True
52+
else:
53+
ssl_verify = False
54+
55+
token = input("API token: ")
56+
57+
config = RawConfigParser()
58+
config.readfp(StringIO('[default]'))
59+
config.set("default", "url", url)
60+
config.set("default", "token", token)
61+
config.set("default", "ssl_verify", ssl_verify)
62+
with temp_umask(0):
63+
with os.fdopen(os.open(credential_file, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0o600), 'w') as fp:
64+
os.chmod(credential_file, 0o600)
65+
config.write(fp)
66+
print("Successfully wrote credentials to {0}.".format(credential_file))
67+
68+
69+
command_map = {
70+
"configure": {
71+
"extra_args": {},
72+
"help": "Configure CbAPI",
73+
"method": configure
74+
}
75+
}
76+
77+
78+
def main(args):
79+
parser = argparse.ArgumentParser()
80+
commands = parser.add_subparsers(dest="command_name", help="CbAPI subcommand")
81+
82+
for cmd_name, cmd_config in iteritems(command_map):
83+
cmd_parser = commands.add_parser(cmd_name, help=cmd_config.get("help", None))
84+
for cmd_arg_name, cmd_arg_config in iteritems(cmd_config.get("extra_args", {})):
85+
cmd_parser.add_argument(cmd_arg_name, **cmd_arg_config)
86+
87+
opts = parser.parse_args(args)
88+
command = command_map.get(opts.command_name)
89+
if not command:
90+
parser.print_usage()
91+
return
92+
93+
command_method = command.get("method", None)
94+
if command_method:
95+
return command_method(opts)
96+
else:
97+
parser.print_usage()
598

699

7100
if __name__ == '__main__':

bin/cbapi-response

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,127 @@
11
#!/usr/bin/env python
22

3-
from cbapi.response.cli import main
3+
import argparse
4+
import contextlib
5+
6+
from cbapi.six import iteritems
7+
from cbapi.six.moves import input
8+
import os
49
import sys
10+
import getpass
11+
import cbapi.six as six
12+
if six.PY3:
13+
from io import StringIO as StringIO
14+
else:
15+
from cStringIO import StringIO
16+
17+
from cbapi.response.rest_api import get_api_token
18+
from cbapi.six.moves.configparser import RawConfigParser
19+
from cbapi.utils import check_python_tls_compatibility
20+
21+
22+
@contextlib.contextmanager
23+
def temp_umask(umask):
24+
oldmask = os.umask(umask)
25+
try:
26+
yield
27+
finally:
28+
os.umask(oldmask)
29+
30+
31+
def configure(opts):
32+
credential_path = os.path.join(os.path.expanduser("~"), ".carbonblack")
33+
credential_file = os.path.join(credential_path, "credentials.response")
34+
35+
print("Welcome to the CbAPI.")
36+
37+
# Check this Python version's compatibility with TLSv1.2.
38+
max_tls_version = check_python_tls_compatibility()
39+
40+
if max_tls_version != "TLSv1.2":
41+
print("NOTICE: this version of Python and OpenSSL does not support TLSv1.2.")
42+
print("TLSv1.2 is *required* to connect to Cb Response server versions >= 6.1.0.")
43+
print("It is highly recommended that you upgrade your Python and OpenSSL before using cbapi.")
44+
print("")
45+
46+
if os.path.exists(credential_file):
47+
print("An existing credential file exists at {0}.".format(credential_file))
48+
resp = input("Do you want to continue and overwrite the existing configuration? [Y/N] ")
49+
if resp.strip().upper() != "Y":
50+
print("Exiting.")
51+
return 1
52+
53+
if not os.path.exists(credential_path):
54+
os.makedirs(credential_path, 0o700)
55+
56+
url = input("URL to the Cb Response server [https://hostname]: ")
57+
58+
ssl_verify = None
59+
while ssl_verify not in ["Y", "N"]:
60+
ssl_verify = input("Use SSL/TLS certificate validation (answer 'N' if using self-signed certs) [Y/N]: ")
61+
ssl_verify = ssl_verify.strip().upper()
62+
63+
if ssl_verify == "Y":
64+
ssl_verify = True
65+
else:
66+
ssl_verify = False
67+
68+
token = input("API token (if unknown, leave blank): ")
69+
if not token:
70+
print("No API token provided: we will look it up using your username & password")
71+
username = input("Username: ")
72+
password = getpass.getpass("Password: ")
73+
74+
print("Retrieving API token for {0}...".format(username))
75+
76+
try:
77+
token = get_api_token(url, username, password, verify=ssl_verify)
78+
except Exception as e:
79+
import traceback
80+
traceback.print_exc()
81+
print("Could not retrieve API token: {0}".format(str(e)))
82+
return 1
83+
84+
config = RawConfigParser()
85+
config.readfp(StringIO('[default]'))
86+
config.set("default", "url", url)
87+
config.set("default", "token", token)
88+
config.set("default", "ssl_verify", ssl_verify)
89+
with temp_umask(0):
90+
with os.fdopen(os.open(credential_file, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0o600), 'w') as fp:
91+
os.chmod(credential_file, 0o600)
92+
config.write(fp)
93+
print("Successfully wrote credentials to {0}.".format(credential_file))
94+
95+
96+
command_map = {
97+
"configure": {
98+
"extra_args": {},
99+
"help": "Configure CbAPI",
100+
"method": configure
101+
}
102+
}
103+
104+
105+
def main(args):
106+
parser = argparse.ArgumentParser()
107+
commands = parser.add_subparsers(dest="command_name", help="CbAPI subcommand")
108+
109+
for cmd_name, cmd_config in iteritems(command_map):
110+
cmd_parser = commands.add_parser(cmd_name, help=cmd_config.get("help", None))
111+
for cmd_arg_name, cmd_arg_config in iteritems(cmd_config.get("extra_args", {})):
112+
cmd_parser.add_argument(cmd_arg_name, **cmd_arg_config)
113+
114+
opts = parser.parse_args(args)
115+
command = command_map.get(opts.command_name)
116+
if not command:
117+
parser.print_usage()
118+
return
119+
120+
command_method = command.get("method", None)
121+
if command_method:
122+
return command_method(opts)
123+
else:
124+
parser.print_usage()
5125

6126

7127
if __name__ == '__main__':

0 commit comments

Comments
 (0)