Example #1
0
 def store_token(self, data):
     Core.debug("storing OAuth token for %r", self.domain)
     self._store_token_libsecret(data)
     try:
         self._store_token_file(data)
     except Exception as e:
         Core.warn("could not write %r: %r", self.token_path, e)
Example #2
0
 def _forget_token(self):
     Core.debug("flushing OAuth tokens")
     nullroute.sec.clear_libsecret({
         "xdg:schema": self.TOKEN_SCHEMA,
         "domain": "pixiv.net"
     })
     os.unlink(self.TOKEN_PATH)
Example #3
0
    def increment_attr(self, dn, attr, incr=1, use_increment=True):
        import random
        import time

        if use_increment and \
           self.has_control(OID_LDAP_CONTROL_POSTREAD) and \
           self.has_feature(OID_LDAP_FEATURE_MODIFY_INCREMENT):
            incr = str(incr).encode()
            ctrl = ldap.controls.readentry.PostReadControl(attrList=[attr])
            res = self.conn.modify_ext_s(dn,
                                         [(ldap.MOD_INCREMENT, attr, incr)],
                                         serverctrls=[ctrl])
            for outctrl in res[3]:
                if outctrl.controlType == ctrl.controlType:
                    values = CaseInsensitiveDict(outctrl.entry)[attr]
                    return int(values[0])

        wait = 0
        while True:
            old_val = self.read_attr(dn, attr, raw=True)[0]
            new_val = str(int(old_val) + incr).encode()
            try:
                self.conn.modify_s(dn, [(ldap.MOD_DELETE, attr, old_val),
                                        (ldap.MOD_ADD, attr, new_val)])
                done = True
            except ldap.NO_SUCH_ATTRIBUTE as e:
                Core.debug("swap (%r, %r) failed: %r", old_val, new_val, e)
                wait += 1
                time.sleep(0.05 * 2**random.randint(0, wait))
            else:
                break
        return int(new_val)
Example #4
0
 def _discover_endpoints(self):
     if not self.discovery_url:
         raise ValueError(
             "either discovery URL or endpoint URLs must be specified")
     Core.debug("fetching discovery document %r", self.discovery_url)
     response = urllib.request.urlopen(self.discovery_url).read()
     response = json.loads(response)
     Core.debug("response data: %r", response)
     if not self.authorization_url:
         self.authorization_url = response["authorization_endpoint"]
     if not self.token_grant_url:
         self.token_grant_url = response["token_endpoint"]
Example #5
0
 def load_token(self):
     Core.debug("loading OAuth token for %r", self.domain)
     try:
         return self._load_token_libsecret()
     except KeyError:
         try:
             return self._load_token_file()
         except FileNotFoundError:
             pass
         except Exception as e:
             Core.debug("could not load %r: %r", self.token_path, e)
             self.forget_token()
     return None
Example #6
0
 def _load_member_name_map(self):
     map_path = Env.find_config_file("pixiv_member_names.txt")
     try:
         Core.debug("loading member aliases from %r", map_path)
         with open(map_path, "r") as fh:
             self.member_name_map = {}
             for line in fh:
                 if line.startswith((";", "#", "\n")):
                     continue
                 k, v = line.split("=")
                 self.member_name_map[k.strip()] = v.strip()
     except FileNotFoundError:
         Core.debug("member alias file %r not found; ignoring", map_path)
Example #7
0
 def request_tls_certificate(self, domains, csr, years=3):
     Core.debug("posting a ssl_multi_domain order for %r", domains)
     org = self.get_organizations()[0]
     order = {
         "certificate": {
             "common_name": domains[0],
             "csr": csr,
             "dns_names": domains,
             "signature_hash": "sha256",
         },
         "organization": { "id": org["id"] },
         "validity_years": years,
     }
     data = self.post_order("ssl_multi_domain", order)
     return data
Example #8
0
    def __init__(self, url, require_tls=True):
        Core.debug("creating libldap connection to %r", url)
        self.conn = ldap.initialize(url)
        if require_tls and not url.startswith(("ldaps://", "ldapi://")):
            self.conn.start_tls_s()

        self.rootDSE = CaseInsensitiveDict(self.conn.read_rootdse_s())
        self._controls = {
            v.decode()
            for v in self.rootDSE.get("supportedControl", [])
        }
        self._features = {
            v.decode()
            for v in self.rootDSE.get("supportedFeatures", [])
        }
Example #9
0
 def _load_token_libsecret(self):
     if self.user_name:
         try:
             data = nullroute.sec.get_libsecret(self.match_fields)
             return json.loads(data)
         except KeyError:
             Core.debug("entry not found; retrying without username")
             old_match_fields = {**self.match_fields}
             del old_match_fields["username"]
             data = nullroute.sec.get_libsecret(old_match_fields)
             Core.debug("migrating entry to add username field")
             nullroute.sec.clear_libsecret(old_match_fields)
             self._store_token_libsecret(json.loads(data))
             return json.loads(data)
     else:
         data = nullroute.sec.get_libsecret(self.match_fields)
         return json.loads(data)
Example #10
0
    def _authenticate(self):
        if self.api.user_id:
            Core.warn("BUG: _authenticate() called twice")
            return True

        data = self._load_token()
        if data:
            Core.trace("loaded token: %r", data)
            if os.environ.get("FORCE_TOKEN_REFRESH"):
                token_valid = False
            else:
                token_valid = data["expires_at"] > time.time()

            if token_valid:
                Core.debug("access token within expiry time, using as-is")
                self.api.user_id = data["user_id"]
                self.api.access_token = data["access_token"]
                self.api.refresh_token = data["refresh_token"]
                return True
            else:
                Core.debug("access token has expired, renewing")
                try:
                    token = self.api.auth(refresh_token=data["refresh_token"])
                    Core.trace("retrieved token: %r", token)
                except Exception as e:
                    Core.warn("could not refresh access token: %r", e)
                    #self._forget_token()
                else:
                    self._store_token(token)
                    return True

        data = self._load_creds()
        if data:
            Core.info("logging in to Pixiv as %r", data["login"])
            try:
                token = self.api.auth(username=data["login"],
                                      password=data["password"])
            except Exception as e:
                Core.warn("could not log in using username & password: %r", e)
            else:
                self._store_token(token)
                return True

        Core.die("could not log in to Pixiv (no credentials)")
        return False
Example #11
0
 def _store_token(self, token):
     data = {
         "access_token": token.response.access_token,
         "refresh_token": token.response.refresh_token,
         "expires_at": int(time.time() + token.response.expires_in),
         "user_id": token.response.user.id,
     }
     Core.debug("storing OAuth tokens")
     nullroute.sec.store_libsecret("Pixiv OAuth token",
                                   json.dumps(data),
                                   {"xdg:schema": self.TOKEN_SCHEMA,
                                    "domain": "pixiv.net",
                                    "userid": token.response.user.id,
                                    "username": token.response.user.account})
     try:
         with open(self.TOKEN_PATH, "w") as fh:
             json.dump(data, fh)
         return True
     except Exception as e:
         Core.warn("could not write %r: %r", self.TOKEN_PATH, e)
         return False
Example #12
0
 def _validate(self):
     Core.debug("verifying session status")
     resp = self.get("https://www.pixiv.net/member.php", allow_redirects=False)
     if resp.is_redirect:
         Core.trace("member.php redirects to %r", resp.next.url)
         url = requests.utils.urlparse(resp.next.url)
         if url.path == "/member.php":
             query = parse_query_string(url.query)
             self.user_id = int(query["id"])
             Core.debug("session is valid, userid %r", self.user_id)
             return True
     Core.debug("session is not valid")
     return False
Example #13
0
    def _authenticate(self):
        if self.user_id:
            return True

        psid = os.environ.get("PIXIV_PHPSESSID")
        if psid:
            cookie = requests.cookies.create_cookie(name="PHPSESSID",
                                                    value=psid,
                                                    domain=".pixiv.net")
            cookie.expires = int(time.time() + 3600)
            Core.debug("storing cookie: %r", cookie)
            self._store_token(serialize_cookie(cookie))

        token = self._load_token()
        if token:
            if os.environ.get("FORCE_TOKEN_REFRESH"):
                del os.environ["FORCE_TOKEN_REFRESH"]
                token_valid = False
            else:
                #token_valid = token["expires"] >= time.time()
                # Just pretend the cookie is still valid, as it now comes
                # from the web browser which will keep it active, and we
                # don't really have any way to get a new one anyway.
                token_valid = True
                token["expires"] = int(time.time() + 86400 * 30)

            if token_valid:
                cookie = requests.cookies.create_cookie(**token)
                Core.debug("loaded cookie: %r", cookie)
                self.ua.cookies.set_cookie(cookie)
                if self._validate():
                    cookie.expires = int(time.time() + 86400 * 30)
                    Core.debug("updating cookie: %r", cookie)
                    self._store_token(serialize_cookie(cookie))
                    return True
            else:
                Core.debug("cookie has expired")

        raise Exception("Pixiv cookie not found or expired")
Example #14
0
 def _load_token(self):
     try:
         data = nullroute.sec.get_libsecret({"xdg:schema": self.TOKEN_SCHEMA,
                                             "domain": "pixiv.net"})
         Core.debug("found OAuth token in keyring")
         return json.loads(data)
     except KeyError:
         try:
             with open(self.TOKEN_PATH, "r") as fh:
                 data = json.load(fh)
             Core.debug("found OAuth token in filesystem")
             return data
         except FileNotFoundError:
             pass
         except Exception as e:
             Core.debug("could not load %r: %r", self.TOKEN_PATH, e)
             self._forget_token()
     return None
Example #15
0
 def _grant_token(self, params):
     if not self.token_grant_url:
         self._discover_endpoints()
     Core.debug("token grant URL: %r", self.token_grant_url)
     post_data = {
         "client_id": self.client_id,
         "client_secret": self.client_secret,
         **params
     }
     Core.debug("request data: %r", post_data)
     post_data = urllib.parse.urlencode(post_data).encode()
     Core.debug("encoded data: %r", post_data)
     response = urllib.request.urlopen(self.token_grant_url,
                                       post_data).read()
     response = json.loads(response)
     response.setdefault("expires_at",
                         int(time.time() + response["expires_in"]))
     return response
Example #16
0
 def post(self, ep, *args, **kwargs):
     uri = self.base + ep
     Core.debug("posting to %r" % uri)
     resp = self.ua.post(uri, *args, **kwargs)
     resp.raise_for_status()
     return resp
Example #17
0
 def get(self, ep, *args, **kwargs):
     uri = self.base + ep
     Core.debug("fetching %r" % uri)
     resp = self.ua.get(uri, *args, **kwargs)
     resp.raise_for_status()
     return resp
Example #18
0
 def forget_token(self):
     Core.debug("flushing OAuth tokens for %r", self.domain)
     self._clear_token_libsecret()
     self._clear_token_file()
Example #19
0
        sshsigbuf = sys.stdin.read()

    namespace = args.namespace or ""

    sshsig_outer = SshsigSignature.from_armored(sshsigbuf)

    keyblob = sshsig_outer.public_key
    sigblob = sshsig_outer.signature

    keydata = ssh_parse_publickey(keyblob)
    sigdata = ssh_parse_signature(sigblob)

    if args.publickey:
        agentkey = SshAgentKey(None, keyblob)
        if args.publickey == agentkey.publickey_base64():
            Core.debug("enveloped publickey matches provided")
        elif args.publickey == agentkey.publickey_base64(with_type=True):
            Core.debug("enveloped publickey matches provided")
        else:
            Core.die("enveloped publickey does not match provided")
    if args.fingerprint:
        agentkey = SshAgentKey(None, keyblob)
        if args.fingerprint == agentkey.fprint_md5_hex():
            Core.debug(
                "enveloped publickey MD5 fingerprint matches provided one")
        elif args.fingerprint == agentkey.fprint_sha256_base64():
            Core.debug(
                "enveloped publickey SHA256 fingerprint matches provided one")
        else:
            Core.die("enveloped publickey fingerprint does not match provided")
    if args.namespace: