summaryrefslogtreecommitdiff
path: root/azurelinuxagent/utils
diff options
context:
space:
mode:
Diffstat (limited to 'azurelinuxagent/utils')
-rw-r--r--azurelinuxagent/utils/cryptutil.py121
-rw-r--r--azurelinuxagent/utils/fileutil.py7
-rw-r--r--azurelinuxagent/utils/osutil.py27
-rw-r--r--azurelinuxagent/utils/restutil.py22
-rw-r--r--azurelinuxagent/utils/shellutil.py6
-rw-r--r--azurelinuxagent/utils/textutil.py8
6 files changed, 148 insertions, 43 deletions
diff --git a/azurelinuxagent/utils/cryptutil.py b/azurelinuxagent/utils/cryptutil.py
new file mode 100644
index 0000000..5ee5637
--- /dev/null
+++ b/azurelinuxagent/utils/cryptutil.py
@@ -0,0 +1,121 @@
+# Microsoft Azure Linux Agent
+#
+# Copyright 2014 Microsoft Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Requires Python 2.4+ and Openssl 1.0+
+#
+
+import base64
+import struct
+from azurelinuxagent.future import ustr, bytebuffer
+from azurelinuxagent.exception import CryptError
+import azurelinuxagent.utils.shellutil as shellutil
+
+class CryptUtil(object):
+ def __init__(self, openssl_cmd):
+ self.openssl_cmd = openssl_cmd
+
+ def gen_transport_cert(self, prv_file, crt_file):
+ """
+ Create ssl certificate for https communication with endpoint server.
+ """
+ cmd = ("{0} req -x509 -nodes -subj /CN=LinuxTransport -days 32768 "
+ "-newkey rsa:2048 -keyout {1} "
+ "-out {2}").format(self.openssl_cmd, prv_file, crt_file)
+ shellutil.run(cmd)
+
+ def get_pubkey_from_prv(self, file_name):
+ cmd = "{0} rsa -in {1} -pubout 2>/dev/null".format(self.openssl_cmd,
+ file_name)
+ pub = shellutil.run_get_output(cmd)[1]
+ return pub
+
+ def get_pubkey_from_crt(self, file_name):
+ cmd = "{0} x509 -in {1} -pubkey -noout".format(self.openssl_cmd,
+ file_name)
+ pub = shellutil.run_get_output(cmd)[1]
+ return pub
+
+ def get_thumbprint_from_crt(self, file_name):
+ cmd="{0} x509 -in {1} -fingerprint -noout".format(self.openssl_cmd,
+ file_name)
+ thumbprint = shellutil.run_get_output(cmd)[1]
+ thumbprint = thumbprint.rstrip().split('=')[1].replace(':', '').upper()
+ return thumbprint
+
+ def decrypt_p7m(self, p7m_file, trans_prv_file, trans_cert_file, pem_file):
+ cmd = ("{0} cms -decrypt -in {1} -inkey {2} -recip {3} "
+ "| {4} pkcs12 -nodes -password pass: -out {5}"
+ "").format(self.openssl_cmd, p7m_file, trans_prv_file,
+ trans_cert_file, self.openssl_cmd, pem_file)
+ shellutil.run(cmd)
+
+ def crt_to_ssh(self, input_file, output_file):
+ shellutil.run("ssh-keygen -i -m PKCS8 -f {0} >> {1}".format(input_file,
+ output_file))
+
+ def asn1_to_ssh(self, pubkey):
+ lines = pubkey.split("\n")
+ lines = [x for x in lines if not x.startswith("----")]
+ base64_encoded = "".join(lines)
+ try:
+ #TODO remove pyasn1 dependency
+ from pyasn1.codec.der import decoder as der_decoder
+ der_encoded = base64.b64decode(base64_encoded)
+ der_encoded = der_decoder.decode(der_encoded)[0][1]
+ key = der_decoder.decode(self.bits_to_bytes(der_encoded))[0]
+ n=key[0]
+ e=key[1]
+ keydata = bytearray()
+ keydata.extend(struct.pack('>I', len("ssh-rsa")))
+ keydata.extend(b"ssh-rsa")
+ keydata.extend(struct.pack('>I', len(self.num_to_bytes(e))))
+ keydata.extend(self.num_to_bytes(e))
+ keydata.extend(struct.pack('>I', len(self.num_to_bytes(n)) + 1))
+ keydata.extend(b"\0")
+ keydata.extend(self.num_to_bytes(n))
+ keydata_base64 = base64.b64encode(bytebuffer(keydata))
+ return ustr(b"ssh-rsa " + keydata_base64 + b"\n",
+ encoding='utf-8')
+ except ImportError as e:
+ raise CryptError("Failed to load pyasn1.codec.der")
+
+ def num_to_bytes(self, num):
+ """
+ Pack number into bytes. Retun as string.
+ """
+ result = bytearray()
+ while num:
+ result.append(num & 0xFF)
+ num >>= 8
+ result.reverse()
+ return result
+
+ def bits_to_bytes(self, bits):
+ """
+ Convert an array contains bits, [0,1] to a byte array
+ """
+ index = 7
+ byte_array = bytearray()
+ curr = 0
+ for bit in bits:
+ curr = curr | (bit << index)
+ index = index - 1
+ if index == -1:
+ byte_array.append(curr)
+ curr = 0
+ index = 7
+ return bytes(byte_array)
+
diff --git a/azurelinuxagent/utils/fileutil.py b/azurelinuxagent/utils/fileutil.py
index 08592bc..5369a7c 100644
--- a/azurelinuxagent/utils/fileutil.py
+++ b/azurelinuxagent/utils/fileutil.py
@@ -27,7 +27,7 @@ import shutil
import pwd
import tempfile
import azurelinuxagent.logger as logger
-from azurelinuxagent.future import text
+from azurelinuxagent.future import ustr
import azurelinuxagent.utils.textutil as textutil
def read_file(filepath, asbin=False, remove_bom=False, encoding='utf-8'):
@@ -46,7 +46,7 @@ def read_file(filepath, asbin=False, remove_bom=False, encoding='utf-8'):
if remove_bom:
#Remove bom on bytes data before it is converted into string.
data = textutil.remove_bom(data)
- data = text(data, encoding=encoding)
+ data = ustr(data, encoding=encoding)
return data
def write_file(filepath, contents, asbin=False, encoding='utf-8', append=False):
@@ -100,6 +100,7 @@ def replace_file(filepath, contents):
return 1
return 0
+
def base_name(path):
head, tail = os.path.split(path)
return tail
@@ -151,7 +152,7 @@ def rm_dirs(*args):
def update_conf_file(path, line_start, val, chk_err=False):
conf = []
if not os.path.isfile(path) and chk_err:
- raise Exception("Can't find config file:{0}".format(path))
+ raise IOError("Can't find config file:{0}".format(path))
conf = read_file(path).split('\n')
conf = [x for x in conf if not x.startswith(line_start)]
conf.append(val)
diff --git a/azurelinuxagent/utils/osutil.py b/azurelinuxagent/utils/osutil.py
deleted file mode 100644
index 9de47e7..0000000
--- a/azurelinuxagent/utils/osutil.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Microsoft Azure Linux Agent
-#
-# Copyright 2014 Microsoft Corporation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Requires Python 2.4+ and Openssl 1.0+
-#
-
-"""
-Load OSUtil implementation from azurelinuxagent.distro
-"""
-from azurelinuxagent.distro.default.osutil import OSUtilError
-import azurelinuxagent.distro.loader as loader
-
-OSUTIL = loader.get_osutil()
-
diff --git a/azurelinuxagent/utils/restutil.py b/azurelinuxagent/utils/restutil.py
index 2acfa57..2e8b0be 100644
--- a/azurelinuxagent/utils/restutil.py
+++ b/azurelinuxagent/utils/restutil.py
@@ -21,8 +21,9 @@ import time
import platform
import os
import subprocess
-import azurelinuxagent.logger as logger
import azurelinuxagent.conf as conf
+import azurelinuxagent.logger as logger
+from azurelinuxagent.exception import HttpError
from azurelinuxagent.future import httpclient, urlparse
"""
@@ -31,9 +32,6 @@ REST api util functions
RETRY_WAITING_INTERVAL = 10
-class HttpError(Exception):
- pass
-
def _parse_url(url):
o = urlparse(url)
rel_uri = o.path
@@ -51,8 +49,8 @@ def get_http_proxy():
Get http_proxy and https_proxy from environment variables.
Username and password is not supported now.
"""
- host = conf.get("HttpProxy.Host", None)
- port = conf.get("HttpProxy.Port", None)
+ host = conf.get_httpproxy_host()
+ port = conf.get_httpproxy_port()
return (host, port)
def _http_request(method, host, rel_uri, port=None, data=None, secure=False,
@@ -61,7 +59,7 @@ def _http_request(method, host, rel_uri, port=None, data=None, secure=False,
if secure:
port = 443 if port is None else port
if proxy_host is not None and proxy_port is not None:
- conn = httpclient.HTTPSConnection(proxy_host, proxy_port)
+ conn = httpclient.HTTPSConnection(proxy_host, proxy_port, timeout=10)
conn.set_tunnel(host, port)
#If proxy is used, full url is needed.
url = "https://{0}:{1}{2}".format(host, port, rel_uri)
@@ -71,7 +69,7 @@ def _http_request(method, host, rel_uri, port=None, data=None, secure=False,
else:
port = 80 if port is None else port
if proxy_host is not None and proxy_port is not None:
- conn = httpclient.HTTPConnection(proxy_host, proxy_port)
+ conn = httpclient.HTTPConnection(proxy_host, proxy_port, timeout=10)
#If proxy is used, full url is needed.
url = "http://{0}:{1}{2}".format(host, port, rel_uri)
else:
@@ -128,8 +126,12 @@ def http_request(method, url, data, headers=None, max_retry=3, chk_proxy=False):
if retry < max_retry - 1:
logger.info("Retry={0}, {1} {2}", retry, method, url)
time.sleep(RETRY_WAITING_INTERVAL)
-
- raise HttpError("HTTP Err: {0} {1}".format(method, url))
+
+ if url is not None and len(url) > 100:
+ url_log = url[0: 100] #In case the url is too long
+ else:
+ url_log = url
+ raise HttpError("HTTP Err: {0} {1}".format(method, url_log))
def http_get(url, headers=None, max_retry=3, chk_proxy=False):
return http_request("GET", url, data=None, headers=headers,
diff --git a/azurelinuxagent/utils/shellutil.py b/azurelinuxagent/utils/shellutil.py
index 372c78a..98871a1 100644
--- a/azurelinuxagent/utils/shellutil.py
+++ b/azurelinuxagent/utils/shellutil.py
@@ -20,7 +20,7 @@
import platform
import os
import subprocess
-from azurelinuxagent.future import text
+from azurelinuxagent.future import ustr
import azurelinuxagent.logger as logger
if not hasattr(subprocess,'check_output'):
@@ -75,9 +75,9 @@ def run_get_output(cmd, chk_err=True, log_cmd=True):
logger.verb(u"run cmd '{0}'", cmd)
try:
output=subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True)
- output = text(output, encoding='utf-8', errors="backslashreplace")
+ output = ustr(output, encoding='utf-8', errors="backslashreplace")
except subprocess.CalledProcessError as e :
- output = text(e.output, encoding='utf-8', errors="backslashreplace")
+ output = ustr(e.output, encoding='utf-8', errors="backslashreplace")
if chk_err:
if log_cmd:
logger.error(u"run cmd '{0}' failed", e.cmd)
diff --git a/azurelinuxagent/utils/textutil.py b/azurelinuxagent/utils/textutil.py
index e0f1395..851f98a 100644
--- a/azurelinuxagent/utils/textutil.py
+++ b/azurelinuxagent/utils/textutil.py
@@ -224,5 +224,13 @@ def gen_password_hash(password, crypt_id, salt_len):
salt = "${0}${1}".format(crypt_id, salt)
return crypt.crypt(password, salt)
+def get_bytes_from_pem(pem_str):
+ base64_bytes = ""
+ for line in pem_str.split('\n'):
+ if "----" not in line:
+ base64_bytes += line
+ return base64_bytes
+
+
Version = LooseVersion