Search in sources :

Example 1 with PasswordCredential

use of me.vertretungsplan.objects.credential.PasswordCredential in project substitution-schedule-parser by vertretungsplanme.

the class LoginHandler method handleLogin.

private String handleLogin(Executor executor, CookieStore cookieStore, boolean needsResponse) throws JSONException, IOException, CredentialInvalidException {
    if (auth == null)
        return null;
    if (!(auth instanceof UserPasswordCredential || auth instanceof PasswordCredential)) {
        throw new IllegalArgumentException("Wrong authentication type");
    }
    String login;
    String password;
    if (auth instanceof UserPasswordCredential) {
        login = ((UserPasswordCredential) auth).getUsername();
        password = ((UserPasswordCredential) auth).getPassword();
    } else {
        login = null;
        password = ((PasswordCredential) auth).getPassword();
    }
    JSONObject data = scheduleData.getData();
    JSONObject loginConfig = data.getJSONObject(LOGIN_CONFIG);
    String type = loginConfig.optString(PARAM_TYPE, "post");
    switch(type) {
        case "post":
            List<Cookie> cookieList = cookieProvider != null ? cookieProvider.getCookies(auth) : null;
            String checkUrl = loginConfig.optString(PARAM_CHECK_URL, null);
            String checkText = loginConfig.optString(PARAM_CHECK_TEXT, null);
            if (cookieList != null && !needsResponse && !(checkUrl == null && checkText != null)) {
                for (Cookie cookie : cookieList) cookieStore.addCookie(cookie);
                if (checkUrl != null && checkText != null) {
                    try {
                        String response = executor.execute(Request.Get(checkUrl)).returnContent().asString();
                        if (!response.contains(checkText)) {
                            return null;
                        }
                    } catch (HttpResponseException e) {
                        return null;
                    }
                } else {
                    return null;
                }
            }
            executor.clearCookies();
            Document preDoc = null;
            if (loginConfig.has(PARAM_PRE_URL)) {
                String preUrl = loginConfig.getString(PARAM_PRE_URL);
                String preHtml = executor.execute(Request.Get(preUrl)).returnContent().asString();
                preDoc = Jsoup.parse(preHtml);
            }
            String postUrl = loginConfig.getString(PARAM_URL);
            JSONObject loginData = loginConfig.getJSONObject(PARAM_DATA);
            List<NameValuePair> nvps = new ArrayList<>();
            String typo3Challenge = null;
            BigInteger typo3RsaN = null;
            BigInteger typo3RsaE = null;
            if (loginData.has("_hiddeninputs") && preDoc != null) {
                for (Element hidden : preDoc.select(loginData.getString("_hiddeninputs") + " input[type=hidden]")) {
                    if (loginData.has(hidden.attr("name")))
                        continue;
                    nvps.add(new BasicNameValuePair(hidden.attr("name"), hidden.attr("value")));
                    if (hidden.attr("name").equals("challenge")) {
                        typo3Challenge = hidden.attr("value");
                    } else if (hidden.attr("name").equals("n") && hidden.attr("id").equals("rsa_n")) {
                        typo3RsaN = new BigInteger(hidden.attr("value"), 16);
                    } else if (hidden.attr("name").equals("e") && hidden.attr("id").equals("rsa_e")) {
                        typo3RsaE = new BigInteger(hidden.attr("value"), 16);
                    }
                }
            }
            for (String name : JSONObject.getNames(loginData)) {
                String value = loginData.getString(name);
                if (name.equals("_hiddeninputs"))
                    continue;
                switch(value) {
                    case "_login":
                        value = login;
                        break;
                    case "_password":
                        value = password;
                        break;
                    case "_password_md5":
                        value = DigestUtils.md5Hex(password);
                        break;
                    case "_password_md5_typo3":
                        value = DigestUtils.md5Hex(login + ":" + DigestUtils.md5Hex(password) + ":" + typo3Challenge);
                        break;
                    case "_password_rsa_typo3":
                        try {
                            final Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                            if (typo3RsaE == null && typo3RsaN == null) {
                                String key = executor.execute(Request.Get(new URL(new URL(postUrl), "/index.php?eID=FrontendLoginRsaPublicKey").toString())).returnContent().asString();
                                typo3RsaN = new BigInteger(key.split(":")[0], 16);
                                typo3RsaE = new BigInteger(key.split(":")[1], 16);
                            }
                            cipher.init(Cipher.ENCRYPT_MODE, KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(typo3RsaN, typo3RsaE)));
                            byte[] result = cipher.doFinal(password.getBytes());
                            value = "rsa:" + new Base64().encodeAsString(result);
                        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException | IllegalBlockSizeException | InvalidKeySpecException e) {
                            e.printStackTrace();
                        }
                        break;
                }
                nvps.add(new BasicNameValuePair(name, value));
            }
            Request request = Request.Post(postUrl);
            if (loginConfig.optBoolean("form-data", false)) {
                MultipartEntityBuilder builder = MultipartEntityBuilder.create();
                for (NameValuePair nvp : nvps) {
                    builder.addTextBody(nvp.getName(), nvp.getValue());
                }
                request.body(builder.build());
            } else {
                request.bodyForm(nvps, Charset.forName("UTF-8"));
            }
            String html = executor.execute(request).returnContent().asString();
            if (cookieProvider != null)
                cookieProvider.saveCookies(auth, cookieStore.getCookies());
            if (checkUrl != null && checkText != null) {
                try {
                    String response = executor.execute(Request.Get(checkUrl)).returnContent().asString();
                    if (response.contains(checkText))
                        throw new CredentialInvalidException();
                } catch (HttpResponseException e) {
                    throw new CredentialInvalidException();
                }
            } else if (checkText != null) {
                if (html.contains(checkText))
                    throw new CredentialInvalidException();
            }
            return html;
        case "basic":
            if (login == null)
                throw new IOException("wrong auth type");
            executor.auth(login, password);
            if (loginConfig.has(PARAM_URL)) {
                String url = loginConfig.getString(PARAM_URL);
                if (executor.execute(Request.Get(url)).returnResponse().getStatusLine().getStatusCode() != 200) {
                    throw new CredentialInvalidException();
                }
            }
            break;
        case "ntlm":
            if (login == null)
                throw new IOException("wrong auth type");
            executor.auth(login, password, null, null);
            if (loginConfig.has(PARAM_URL)) {
                String url = loginConfig.getString(PARAM_URL);
                if (executor.execute(Request.Get(url)).returnResponse().getStatusLine().getStatusCode() != 200) {
                    throw new CredentialInvalidException();
                }
            }
            break;
        case "fixed":
            String loginFixed = loginConfig.optString(PARAM_LOGIN, null);
            String passwordFixed = loginConfig.getString(PARAM_PASSWORD);
            if (!Objects.equals(loginFixed, login) || !Objects.equals(passwordFixed, password)) {
                throw new CredentialInvalidException();
            }
            break;
    }
    return null;
}
Also used : Base64(org.apache.commons.codec.binary.Base64) MultipartEntityBuilder(org.apache.http.entity.mime.MultipartEntityBuilder) Element(org.jsoup.nodes.Element) PasswordCredential(me.vertretungsplan.objects.credential.PasswordCredential) UserPasswordCredential(me.vertretungsplan.objects.credential.UserPasswordCredential) ArrayList(java.util.ArrayList) IllegalBlockSizeException(javax.crypto.IllegalBlockSizeException) HttpResponseException(org.apache.http.client.HttpResponseException) RSAPublicKeySpec(java.security.spec.RSAPublicKeySpec) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) BadPaddingException(javax.crypto.BadPaddingException) UserPasswordCredential(me.vertretungsplan.objects.credential.UserPasswordCredential) Document(org.jsoup.nodes.Document) URL(java.net.URL) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) CredentialInvalidException(me.vertretungsplan.exception.CredentialInvalidException) InvalidKeySpecException(java.security.spec.InvalidKeySpecException) Cookie(org.apache.http.cookie.Cookie) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) NameValuePair(org.apache.http.NameValuePair) Request(org.apache.http.client.fluent.Request) NoSuchPaddingException(javax.crypto.NoSuchPaddingException) IOException(java.io.IOException) InvalidKeyException(java.security.InvalidKeyException) JSONObject(org.json.JSONObject) BigInteger(java.math.BigInteger) Cipher(javax.crypto.Cipher)

Example 2 with PasswordCredential

use of me.vertretungsplan.objects.credential.PasswordCredential in project substitution-schedule-parser by vertretungsplanme.

the class ESchoolParser method getSubstitutionSchedule.

@Override
public SubstitutionSchedule getSubstitutionSchedule() throws IOException, JSONException, CredentialInvalidException {
    if (!(scheduleData.getAuthenticationData() instanceof NoAuthenticationData) && (credential == null || !(credential instanceof PasswordCredential) || ((PasswordCredential) credential).getPassword() == null || ((PasswordCredential) credential).getPassword().isEmpty())) {
        throw new IOException("no login");
    }
    List<NameValuePair> nvps = new ArrayList<>();
    nvps.add(new BasicNameValuePair("wp", scheduleData.getData().getString(PARAM_ID)));
    nvps.add(new BasicNameValuePair("go", "vplan"));
    nvps.add(new BasicNameValuePair("content", "x14"));
    nvps.add(new BasicNameValuePair("sortby", "S"));
    String url = BASE_URL + "?" + URLEncodedUtils.format(nvps, "UTF-8");
    Document doc = Jsoup.parse(httpGet(url, ENCODING));
    if (doc.select("form[name=loginform]").size() > 0 && scheduleData.getAuthenticationData() instanceof PasswordAuthenticationData) {
        // Login required
        List<NameValuePair> formParams = new ArrayList<>();
        formParams.add(new BasicNameValuePair("password", ((PasswordCredential) credential).getPassword()));
        formParams.add(new BasicNameValuePair("login", ""));
        doc = Jsoup.parse(httpPost(url, ENCODING, formParams));
        if (doc.select("font[color=red]").text().contains("fehlgeschlagen")) {
            throw new CredentialInvalidException();
        }
    }
    SubstitutionSchedule schedule = parseESchoolSchedule(doc);
    return schedule;
}
Also used : BasicNameValuePair(org.apache.http.message.BasicNameValuePair) NameValuePair(org.apache.http.NameValuePair) NoAuthenticationData(me.vertretungsplan.objects.authentication.NoAuthenticationData) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) SubstitutionSchedule(me.vertretungsplan.objects.SubstitutionSchedule) PasswordCredential(me.vertretungsplan.objects.credential.PasswordCredential) ArrayList(java.util.ArrayList) PasswordAuthenticationData(me.vertretungsplan.objects.authentication.PasswordAuthenticationData) CredentialInvalidException(me.vertretungsplan.exception.CredentialInvalidException) IOException(java.io.IOException) Document(org.jsoup.nodes.Document)

Example 3 with PasswordCredential

use of me.vertretungsplan.objects.credential.PasswordCredential in project substitution-schedule-parser by vertretungsplanme.

the class SchoolJoomlaParser method executeTask.

@NotNull
private JSONObject executeTask(String task) throws JSONException, IOException, CredentialInvalidException {
    String baseurl = scheduleData.getData().getString(PARAM_BASEURL);
    String username = "";
    String password = "";
    if (credential != null) {
        if (credential instanceof UserPasswordCredential) {
            if (scheduleData.getType() != SubstitutionSchedule.Type.TEACHER) {
                throw new IOException("student schedules only have passwords or no password");
            }
            username = ((UserPasswordCredential) credential).getUsername();
            password = ((UserPasswordCredential) credential).getPassword();
        } else if (credential instanceof PasswordCredential) {
            if (scheduleData.getType() != SubstitutionSchedule.Type.STUDENT) {
                throw new IOException("teacher schedules need a username");
            }
            password = ((PasswordCredential) credential).getPassword();
        }
    }
    String json = httpGet(baseurl + "/components/com_school_mobile/wserv/service" + ".php?select=&user=" + username + "&pw=" + password + "&task=" + task, "UTF-8");
    if (!json.startsWith("{") && json.contains("{")) {
        // sometimes the server gives error messages above the JSON
        json = json.substring(json.indexOf("{"));
    }
    final JSONObject data = new JSONObject(json);
    final int error = data.getInt("error");
    if (error != 0 || data.getJSONArray("errors").length() > 0) {
        switch(error) {
            // wrong teacher password
            case 12:
            case // wrong student password
            17:
                throw new CredentialInvalidException();
            case // teacher auth failed
            3002:
                if (scheduleData.getType() == SubstitutionSchedule.Type.TEACHER) {
                    throw new CredentialInvalidException();
                }
                break;
            default:
                throw new IOException(data.getString("error_desc"));
        }
    }
    return data;
}
Also used : JSONObject(org.json.JSONObject) PasswordCredential(me.vertretungsplan.objects.credential.PasswordCredential) UserPasswordCredential(me.vertretungsplan.objects.credential.UserPasswordCredential) CredentialInvalidException(me.vertretungsplan.exception.CredentialInvalidException) IOException(java.io.IOException) UserPasswordCredential(me.vertretungsplan.objects.credential.UserPasswordCredential) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

IOException (java.io.IOException)3 CredentialInvalidException (me.vertretungsplan.exception.CredentialInvalidException)3 PasswordCredential (me.vertretungsplan.objects.credential.PasswordCredential)3 ArrayList (java.util.ArrayList)2 UserPasswordCredential (me.vertretungsplan.objects.credential.UserPasswordCredential)2 NameValuePair (org.apache.http.NameValuePair)2 BasicNameValuePair (org.apache.http.message.BasicNameValuePair)2 JSONObject (org.json.JSONObject)2 Document (org.jsoup.nodes.Document)2 BigInteger (java.math.BigInteger)1 URL (java.net.URL)1 InvalidKeyException (java.security.InvalidKeyException)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 InvalidKeySpecException (java.security.spec.InvalidKeySpecException)1 RSAPublicKeySpec (java.security.spec.RSAPublicKeySpec)1 BadPaddingException (javax.crypto.BadPaddingException)1 Cipher (javax.crypto.Cipher)1 IllegalBlockSizeException (javax.crypto.IllegalBlockSizeException)1 NoSuchPaddingException (javax.crypto.NoSuchPaddingException)1 SubstitutionSchedule (me.vertretungsplan.objects.SubstitutionSchedule)1