/****************************************************************************** * * * Copyright 2017 Subterranean Security * * * * 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. * * * *****************************************************************************/ package com.subterranean_security.crimson.viewer.net.command; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.subterranean_security.crimson.core.net.MessageFuture.Timeout; import com.subterranean_security.crimson.core.proto.Delta.MI_TriggerProfileDelta; import com.subterranean_security.crimson.core.proto.Delta.ProfileTimestamp; import com.subterranean_security.crimson.core.proto.Login.RQ_Login; import com.subterranean_security.crimson.core.proto.Login.RQ_LoginChallenge; import com.subterranean_security.crimson.core.proto.Login.RS_Login; import com.subterranean_security.crimson.core.proto.Login.RS_LoginChallenge; import com.subterranean_security.crimson.core.proto.MSG.Message; import com.subterranean_security.crimson.core.proto.Misc.Outcome; import com.subterranean_security.crimson.core.store.ConnectionStore; import com.subterranean_security.crimson.core.util.CryptoUtil; import com.subterranean_security.crimson.core.util.IDGen; import com.subterranean_security.crimson.sv.profile.ClientProfile; import com.subterranean_security.crimson.viewer.store.ProfileStore; import com.subterranean_security.crimson.viewer.ui.screen.main.MainFrame; public final class LoginCom { private static final Logger log = LoggerFactory.getLogger(LoginCom.class); private LoginCom() { } public static Outcome login(String user, String pass) { long t1 = System.currentTimeMillis(); Outcome.Builder outcome = Outcome.newBuilder().setResult(false); int id = IDGen.msg(); ConnectionStore.route(Message.newBuilder().setId(id).setRqLogin(RQ_Login.newBuilder().setUsername(user))); RS_Login loginResponse = null; try { Message response = ConnectionStore.waitForResponse(0, id, 5); if (response == null) { return outcome.setComment("Request timeout").build(); } else if (response.hasRqLoginChallenge()) { loginResponse = handleChallenge(response, pass); } else if (response.hasRsLogin()) { loginResponse = response.getRsLogin(); } } catch (InterruptedException e) { return outcome.build(); } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); } if (loginResponse != null) { outcome.setResult(loginResponse.getResponse().getResult()); if (loginResponse.getResponse().hasComment()) outcome.setComment(loginResponse.getResponse().getComment()); } else { outcome.setComment("Authentication failed"); } if (outcome.getResult()) { passLogin(loginResponse); } return outcome.setTime(System.currentTimeMillis() - t1).build(); } private static void passLogin(RS_Login rsLogin) { // load interface if (MainFrame.main == null) { MainFrame.main = new MainFrame(); } ProfileStore.update(rsLogin.getSpd()); triggerProfileDelta(); } private static RS_Login handleChallenge(Message m, String pass) { RQ_LoginChallenge challenge = m.getRqLoginChallenge(); String result = challenge.getCloud() ? CryptoUtil.hashOpencartPassword(pass, challenge.getSalt()) : CryptoUtil.hashCrimsonPassword(pass, challenge.getSalt()); ConnectionStore.route(Message.newBuilder().setId(m.getId()) .setRsLoginChallenge(RS_LoginChallenge.newBuilder().setResult(result)).build()); try { Message response = ConnectionStore.waitForResponse(0, m.getId(), 5); return (response != null && response.hasRsLogin()) ? response.getRsLogin() : null; } catch (InterruptedException e) { return null; } catch (Timeout e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } public static void triggerProfileDelta() { log.debug("Triggering profile delta update"); // report last update timestamps for current clients MI_TriggerProfileDelta.Builder mi = MI_TriggerProfileDelta.newBuilder(); for (int i = 0; i < ProfileStore.clients.size(); i++) { ClientProfile cp = ProfileStore.clients.get(i); mi.addProfileTimestamp( ProfileTimestamp.newBuilder().setCvid(cp.getCid()).setTimestamp(cp.getLastUpdate().getTime())); } ConnectionStore.route(Message.newBuilder().setMiTriggerProfileDelta(mi)); } }