def _submitMessage(self, phone, message): """ write the message down to the given file :param phone: given phone number :param message: the provided message, containing the otp """ ret = False filename = self.config.get("file", "") here = self.config.get("here", "") if here: filename = "%s%s%s" % (here, os.path.sep, filename) try: with open(filename, "w") as f: msg = "%s:%s" % (str2unicode(phone), str2unicode(message)) f.write(msg) ret = True except Exception as exx: log.error("Failed to open file %r", filename) raise ProviderNotAvailable("Failed to open file %r" % filename) return ret
def _submitMessage(self, phone, message): ''' send out a message to a phone via an http sms connector :param phone: the phone number :param message: the message to submit to the phone ''' log.debug("[submitMessage] submitting message " "%s to %s" % (message, phone)) pparams = {} # ----------------------------------------------------------------- -- # care for the authentication if self.auth_type == 'basic': auth_method = HTTPBasicAuth elif self.auth_type == 'digest': auth_method = HTTPDigestAuth else: auth_method = None if self.username and auth_method: pparams['auth'] = auth_method(username=self.username, password=self.password) # ----------------------------------------------------------------- -- # fill in the data into the payload json_body = {} json_body.update(self.payload) sms_message = json_body[self.sms_text_key] if sms_message and '<message>' in sms_message: sms_message = sms_message.replace('<message>', message) else: sms_message = message json_body[self.sms_text_key] = sms_message # ----------------------------------------------------------------- -- # care for the phone number # do some phone number normalisation if MSISDN parameter is provided # prepare the phone number msisdn = 'true' in ("%r" % self.config.get('MSISDN', "false")).lower() if msisdn: phone = self._get_msisdn_phonenumber(phone) # ------------------------------------------------------------------ -- # replace the phone if there is a given template for it sms_phone = self._apply_phone_template( phone, json_body.get(self.sms_phone_key)) json_body[self.sms_phone_key] = sms_phone # ----------------------------------------------------------------- -- # care for connection timeout if self.timeout: pparams['timeout'] = self.timeout # -------------------------------------------------------------- -- # setup http headers # submitting the json body requires the correct HTTP headers # with contenttype declaration: headers = { 'Content-type': 'application/json', 'Accept': 'application/json' } if self.headers: headers.update(self.headers) http_session = requests.Session() # -------------------------------------------------------------- -- # support for proxies if self.proxy: http_session.proxies.update(self.proxy) # ------------------------------------------------------------- -- # client certificate - # we check if the client certificate exists, which is # referenced as a filename if self.client_cert and os.path.isfile(self.client_cert): http_session.cert = self.client_cert # ------------------------------------------------------------- -- # server certificate server_cert = self.server_cert if server_cert is not None: # Session.post() doesn't like unicode values in Session.verify if isinstance(server_cert, str): server_cert = server_cert.encode('utf-8') http_session.verify = server_cert # ------------------------------------------------------------- -- retry = 3 while retry > 0: try: log.debug("Request Header: %r", headers) log.debug("Request Content: %r", json_body) response = http_session.post(self.urls[0], json=json_body, headers=headers, **pparams) if response.ok: log.info("RestSMSProvider request success!") log.debug("Response Headers: %r", response.headers) log.debug("Response Content: %r", response.content) return True log.info("RestSMSProvider request failed: %r", response.reason) return False except requests.exceptions.Timeout as exc: log.exception("RestSMSProvider timed out %r" % exc) retry -= 1 if retry <= 0: raise ProviderNotAvailable("RestSMSProvider timed out %r" % exc) except Exception as exc: log.exception("RestSMSProvider %r" % exc) retry = 0 raise Exception("Failed to send SMS. %s" % str(exc))
def _submitMessage(self, phone, message): """ submit the message to the SMPP Server """ result = True # setup the configuration if not self.config: raise Exception("missing configuration!") try: client = smpplib.client.Client(self.server, self.port) client.connect() log.debug("connected to %r:%r", self.server, self.port) except Exception as exx: log.exception("Failed to connect to server") raise ProviderNotAvailable("Failed to connect to server %r" % exc) try: log.debug("binding to system_id %r (system_type %r)", self.system_id, self.system_type) # transform the arguments from unicode down to string / byte array password = self.password.encode(self.target_encoding, 'ignore') system_id = self.system_id.encode(self.target_encoding, 'ignore') system_type = self.system_type.encode(self.target_encoding, 'ignore') client.bind_transceiver(system_id=system_id, password=password, system_type=system_type) # transform the arguments from unicode down to string / byte array source_addr = self.source_addr.encode(self.target_encoding, 'ignore') destination_addr = phone.encode(self.target_encoding, 'ignore') short_message = message.encode(self.target_encoding, 'ignore') # according to spec messages should not be longer than 160 chars if len(short_message) <= 160: self._send(client, source_addr, destination_addr, short_message) log.debug("message %r submitted to %r", short_message, phone) else: # messages longer than 160 chars should be # split down into small chunks of 153 chars max_msg_len = 153 for i in range(0, len(short_message), max_msg_len): msg = short_message[i:i + max_msg_len] if not msg: continue self._send(client, source_addr, destination_addr, msg) log.debug("message %r submitted to %r", msg, phone) except Exception as exx: log.exception(exx) result = False finally: client.unbind() client.disconnect() return result
def _submitMessage(self, phone, message): ''' Submits the message for phone to the email gateway. Returns true in case of success ''' ret = False if ('mailserver' not in self.config or 'mailsender' not in self.config or 'mailto' not in self.config): log.error("[submitMessage] incomplete config: %s. mailserver, " "mailsender and mailto needed." % self.config) return ret # prepare the phone number msisdn = 'true' in ("%r" % self.config.get('MSISDN', "false")).lower() if msisdn: phone = self._get_msisdn_phonenumber(phone) # prepare the smtp server connection parameters default_port = 25 start_tls_params = {} start_tls = str(self.config.get("start_tls", False)).lower() == 'true' if start_tls: default_port = 587 start_tls_params_keyfile = self.config.get("keyfile", None) start_tls_params_certfile = self.config.get("certfile", None) use_ssl = str(self.config.get("use_ssl", False)).lower() == 'true' if use_ssl: default_port = 465 server = self.config.get("mailserver") port = int(self.config.get("mailserver_port", default_port)) # support for mailserver syntax like server:port # if port is not explicit defined if "mailserver_port" not in self.config and ':' in server: server, _sep, port = server.rpartition(':') user = self.config.get("mailuser") password = self.config.get("mailpassword") fromaddr = self.config.get("mailsender", "linotp@localhost") toaddr = self.config.get("mailto") subject = self.config.get("subject", "") body = self.config.get("body", "") log.debug("[submitMessage] submitting message %s to %s", message, phone) toaddr = string.replace(toaddr, PHONE_TAG, phone) if not subject: subject = "[LinOTP]" subject = string.replace(subject, PHONE_TAG, phone) subject = string.replace(subject, MSG_TAG, message) if not body: body = "<otp>" body = string.replace(body, PHONE_TAG, phone) body = string.replace(body, MSG_TAG, message) msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s" % (fromaddr, toaddr, subject, body)) serv = None try: # if SSL is defined, we require a different base class if not use_ssl: serv = smtplib.SMTP(server, port) else: serv = smtplib.SMTP_SSL(server, port) serv.set_debuglevel(1) serv.ehlo() if start_tls and not use_ssl: if serv.has_extn('STARTTLS'): serv.starttls(start_tls_params_keyfile, start_tls_params_certfile) serv.ehlo() else: log.error("Start_TLS not supported:") raise Exception("Start_TLS requested but not supported" " by server %r" % server) if user: if serv.has_extn('AUTH'): log.debug("authenticating to mailserver, user: %s, " "pass: %r", user, sha256(password).hexdigest()) serv.login(user, password) else: log.error("AUTH not supported:") data_dict = serv.sendmail(fromaddr, toaddr, msg) log.debug("sendmail: %r", data_dict) (code, response) = serv.quit() log.debug("quit: (%r) %r", code, response) ret = True except smtplib.socket.error as exc: log.exception('Error: could not connect to server') if boolean(self.config.get('raise_exception', True)): raise ProviderNotAvailable('Error: could not connect ' 'to server: %r' % exc) ret = False except Exception as exx: log.exception("[submitMessage] %s", exx) if boolean(self.config.get('raise_exception', False)): raise Exception(exx) ret = False finally: if serv: serv.close() return ret
def request(self, url, parameter, username=None, password=None, method='GET'): try: pparams = {} if 'timeout' in self.config and self.config['timeout']: pparams['timeout'] = parse_timeout(self.config['timeout']) if 'PROXY' in self.config and self.config['PROXY']: if isinstance(self.config['PROXY'], str): proxy_defintion = { "http": self.config['PROXY'], "https": self.config['PROXY'] } elif isinstance(self.config['PROXY'], dict): proxy_defintion = self.config['PROXY'] pparams['proxies'] = proxy_defintion if username and password is not None: auth = None auth_type = self.config.get('AUTH_TYPE', 'basic').lower().strip() if auth_type == 'basic': auth = HTTPBasicAuth(username, password) if auth_type == 'digest': auth = HTTPDigestAuth(username, password) if auth: pparams['auth'] = auth # -------------------------------------------------------------- -- # fianly execute the request if method == 'GET': response = requests.get(url, params=parameter, **pparams) else: response = requests.post(url, data=parameter, **pparams) reply = response.text # some providers like clickatell have no response.status! log.debug("HttpSMSProvider >>%r...%r<<", reply[:20], reply[-20:]) ret = self._check_success(reply) except (requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError, requests.exceptions.Timeout, requests.exceptions.ReadTimeout, requests.exceptions.TooManyRedirects) as exc: log.exception("HttpSMSProvider timed out") raise ProviderNotAvailable("Failed to send SMS - timed out %r" % exc) except Exception as exc: log.error("HttpSMSProvider %r", exc) raise Exception("Failed to send SMS. %r" % exc) return ret
def request(self, url, parameter, username=None, password=None, method="GET"): try: pparams = {} pparams["timeout"] = HttpSMSProvider.DEFAULT_TIMEOUT if "timeout" in self.config and self.config["timeout"]: pparams["timeout"] = parse_timeout(self.config["timeout"]) if "PROXY" in self.config and self.config["PROXY"]: if isinstance(self.config["PROXY"], str): proxy_defintion = { "http": self.config["PROXY"], "https": self.config["PROXY"], } elif isinstance(self.config["PROXY"], dict): proxy_defintion = self.config["PROXY"] pparams["proxies"] = proxy_defintion if username and password is not None: auth = None auth_type = (self.config.get("AUTH_TYPE", "basic").lower().strip()) if auth_type == "basic": auth = HTTPBasicAuth(username, password) if auth_type == "digest": auth = HTTPDigestAuth(username, password) if auth: pparams["auth"] = auth # -------------------------------------------------------------- # set server certificate validation policy server_certificate = self.load_server_cert( self.config, server_cert_key="SERVER_CERTIFICATE") if server_certificate is False: pparams["verify"] = False if server_certificate: pparams["verify"] = server_certificate # -------------------------------------------------------------- -- # finally execute the request if method == "GET": response = requests.get(url, params=parameter, **pparams) else: response = requests.post(url, data=parameter, **pparams) reply = response.text # some providers like clickatell have no response.status! log.debug("HttpSMSProvider >>%r...%r<<", reply[:20], reply[-20:]) ret = self._check_success(reply) except ( requests.exceptions.ConnectTimeout, requests.exceptions.ConnectionError, requests.exceptions.Timeout, requests.exceptions.ReadTimeout, requests.exceptions.TooManyRedirects, ) as exc: log.error("HttpSMSProvider timed out") raise ProviderNotAvailable("Failed to send SMS - timed out %r" % exc) except Exception as exc: log.error("HttpSMSProvider %r", exc) raise Exception("Failed to send SMS. %r" % exc) return ret
def _submitMessage(self, phone, message): """ send out a message to a phone via an http sms connector :param phone: the phone number :param message: the message to submit to the phone """ log.debug("[submitMessage] submitting message %s to %s", message, phone) pparams = {} # ----------------------------------------------------------------- -- # care for the authentication if self.auth_type == "basic": auth_method = HTTPBasicAuth elif self.auth_type == "digest": auth_method = HTTPDigestAuth else: auth_method = None if self.username and auth_method: pparams["auth"] = auth_method(username=self.username, password=self.password) # ----------------------------------------------------------------- -- # fill in the data into the payload json_body = deepcopy(self.payload) sms_message = json_body.get(self.sms_text_key, "") if sms_message and "<message>" in sms_message: sms_message = sms_message.replace("<message>", message) else: sms_message = message json_replace(json_body, key=self.sms_text_key, value=sms_message) # ----------------------------------------------------------------- -- # care for the phone number # do some phone number normalisation if MSISDN parameter is provided # prepare the phone number msisdn = "true" in ("%r" % self.config.get("MSISDN", "false")).lower() if msisdn: phone = self._get_msisdn_phonenumber(phone) # ------------------------------------------------------------------ -- # replace the phone if there is a given template for it sms_phone = self._apply_phone_template( phone, json_body.get(self.sms_phone_key)) json_replace(json_body, key=self.sms_phone_key, value=sms_phone) # ----------------------------------------------------------------- -- # care for connection timeout pparams["timeout"] = self.timeout # -------------------------------------------------------------- -- # setup http headers # submitting the json body requires the correct HTTP headers # with contenttype declaration: headers = { "Content-type": "application/json", "Accept": "application/json", } if self.headers: headers.update(self.headers) http_session = requests.Session() # -------------------------------------------------------------- -- # support for proxies if self.proxy: http_session.proxies.update(self.proxy) # ------------------------------------------------------------- -- # client certificate - # we check if the client certificate exists, which is # referenced as a filename if self.client_cert and os.path.isfile(self.client_cert): http_session.cert = self.client_cert # ------------------------------------------------------------- -- # set server certificate validation policy if self.server_cert is False: http_session.verify = False if self.server_cert: http_session.verify = self.server_cert # ------------------------------------------------------------- -- retry = 3 while retry > 0: try: log.debug("Request Header: %r", headers) log.debug("Request Content: %r", json_body) response = http_session.post(self.urls[0], json=json_body, headers=headers, **pparams) if response.ok: log.info("RestSMSProvider request success!") log.debug("Response Headers: %r", response.headers) log.debug("Response Content: %r", response.content) return True log.info("RestSMSProvider request failed: %r", response.reason) return False except requests.exceptions.Timeout as exc: log.error("RestSMSProvider timed out %r", exc) retry -= 1 if retry <= 0: raise ProviderNotAvailable("RestSMSProvider timed out %r" % exc) except Exception as exc: log.error("RestSMSProvider %r", exc) retry = 0 raise Exception("Failed to send SMS. %s" % str(exc))