Advertisement
Guest User

Untitled

a guest
Mar 31st, 2017
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.65 KB | None | 0 0
  1. import org.jivesoftware.smack.AbstractXMPPConnection;
  2. import org.jivesoftware.smack.SmackConfiguration;
  3. import org.jivesoftware.smack.SmackException;
  4. import org.jivesoftware.smack.XMPPException;
  5. import org.jivesoftware.smack.chat.Chat;
  6. import org.jivesoftware.smack.chat.ChatManager;
  7. import org.jivesoftware.smack.packet.Message;
  8. import org.jivesoftware.smack.packet.Presence;
  9. import org.jivesoftware.smack.roster.Roster;
  10. import org.jivesoftware.smack.roster.RosterEntry;
  11. import org.jivesoftware.smack.tcp.XMPPTCPConnection;
  12. import org.jivesoftware.smackx.carbons.CarbonManager;
  13. import org.jivesoftware.smackx.mam.MamManager;
  14. import org.jivesoftware.smackx.muc.MultiUserChat;
  15. import org.jivesoftware.smackx.muc.MultiUserChatException;
  16. import org.jivesoftware.smackx.muc.MultiUserChatManager;
  17. import org.jivesoftware.smackx.omemo.OmemoInitializer;
  18. import org.jivesoftware.smackx.omemo.OmemoManager;
  19. import org.jivesoftware.smackx.omemo.elements.OmemoBundleElement;
  20. import org.jivesoftware.smackx.omemo.exceptions.*;
  21. import org.jivesoftware.smackx.omemo.internal.*;
  22. import org.jivesoftware.smackx.omemo.listener.OmemoMessageListener;
  23. import org.jivesoftware.smackx.omemo.listener.OmemoMucMessageListener;
  24. import org.jivesoftware.smackx.omemo.signal.SignalFileBasedOmemoStore;
  25. import org.jivesoftware.smackx.omemo.signal.SignalOmemoService;
  26. import org.jivesoftware.smackx.omemo.signal.SignalOmemoSession;
  27. import org.jivesoftware.smackx.omemo.util.KeyUtil;
  28. import org.jxmpp.jid.BareJid;
  29. import org.jxmpp.jid.EntityBareJid;
  30. import org.jxmpp.jid.EntityFullJid;
  31. import org.jxmpp.jid.impl.JidCreate;
  32. import org.jxmpp.jid.parts.Resourcepart;
  33. import org.jxmpp.stringprep.XmppStringprepException;
  34. import org.whispersystems.libsignal.IdentityKey;
  35.  
  36. import java.io.File;
  37. import java.util.ArrayList;
  38. import java.util.Date;
  39. import java.util.List;
  40. import java.util.Scanner;
  41. import java.util.stream.Collectors;
  42.  
  43.  
  44. /**
  45. * Test
  46. * Created by vanitas on 28.11.16.
  47. */
  48. public class Main {
  49. private AbstractXMPPConnection connection;
  50. private OmemoManager omemoManager;
  51.  
  52. private Main() throws XmppStringprepException {
  53. //*
  54. SmackConfiguration.DEBUG = true;
  55. /*/
  56. SmackConfiguration.DEBUG = false;
  57. //*/
  58.  
  59. new OmemoInitializer().initialize();
  60. }
  61.  
  62. public void start() throws Exception {
  63. Scanner scanner = new Scanner(System.in);
  64. String jidname = null, password = null;
  65. while(jidname == null) {
  66. System.out.println("Enter username:");
  67. jidname = scanner.nextLine();
  68. }
  69. while (password == null) {
  70. System.out.println("Enter password:");
  71. password = scanner.nextLine();
  72. }
  73. connection = new XMPPTCPConnection(jidname, password);
  74.  
  75.  
  76. connection.setPacketReplyTimeout(30000);
  77. connection = connection.connect();
  78. connection.login();
  79. System.out.println("Logged in. Begin setting up OMEMO...");
  80. omemoManager = OmemoManager.getInstanceFor(connection);
  81. SignalFileBasedOmemoStore store = new SignalFileBasedOmemoStore(omemoManager, new File("store"));
  82.  
  83. OmemoMessageListener<IdentityKey> messageListener = (decrypted, message, wrapping, omemoMessageInformation) -> {
  84. BareJid sender = message.getFrom().asBareJid();
  85. if (sender != null && decrypted != null) {
  86. System.out.println("\033[34m" + sender + ": " + decrypted + "\033[0m "+(omemoMessageInformation != null ? omemoMessageInformation : ""));
  87. }
  88. };
  89. OmemoMucMessageListener<IdentityKey> mucMessageListener = (multiUserChat, bareJid, s, message, message1, omemoMessageInformation) -> {
  90. if(multiUserChat != null && bareJid != null && s != null) {
  91. System.out.println("\033[36m"+multiUserChat.getRoom()+": "+bareJid+": "+s+"\033[0m "+(omemoMessageInformation != null ? omemoMessageInformation : ""));
  92. }
  93. };
  94.  
  95. SignalOmemoService omemoService = new SignalOmemoService(omemoManager, store);
  96. CarbonManager.getInstanceFor(connection).enableCarbons();
  97.  
  98. omemoService.addOmemoMessageListener(messageListener);
  99. omemoService.addOmemoMucMessageListener(mucMessageListener);
  100.  
  101. Roster roster = Roster.getInstanceFor(connection);
  102. roster.setSubscriptionMode(Roster.SubscriptionMode.accept_all);
  103.  
  104. ChatManager cm = ChatManager.getInstanceFor(connection);
  105. cm.addChatListener((chat, b) -> chat.addMessageListener((chat1, message) -> {
  106. if(message.getBody() != null && chat1 != null) {
  107. System.out.println("Message received: " + chat1.getParticipant().toString() + ": " + message.getBody());
  108. }
  109. }));
  110.  
  111. MultiUserChatManager mucm = MultiUserChatManager.getInstanceFor(connection);
  112. mucm.setAutoJoinOnReconnect(true);
  113. mucm.addInvitationListener((xmppConnection, multiUserChat, entityFullJid, s, s1, message, invite) -> {
  114. try {
  115. multiUserChat.join(Resourcepart.from("OMEMO"));
  116. multiUserChat.addMessageListener(message1 -> {
  117. System.out.println("MUC: "+message1.getFrom()+": "+message1.getBody());
  118. });
  119. System.out.println("Joined Room "+multiUserChat.getRoom().asBareJid().toString());
  120. } catch (SmackException.NoResponseException | XMPPException.XMPPErrorException | InterruptedException | MultiUserChatException.NotAMucServiceException | SmackException.NotConnectedException | XmppStringprepException e) {
  121. e.printStackTrace();
  122. }
  123. });
  124. System.out.println("OMEMO setup complete. You can now start chatting.");
  125. String line;
  126. Chat current = null;
  127. boolean omemo = false;
  128.  
  129. while ((line = scanner.nextLine()) != null) {
  130. String [] split = line.split(" ");
  131. if(line.startsWith("/chat ")) {
  132. String l = line.substring("/chat ".length());
  133. if(l.length() == 0) {
  134. System.out.println(current != null ? current.getParticipant() : "null");
  135. } else {
  136. String id = split[1];
  137. BareJid jid = getJid(id);
  138. if(jid != null) {
  139. current = cm.createChat(jid.asEntityJidIfPossible());
  140. current.sendMessage(l.substring(id.length() + 1));
  141. }
  142. }
  143. } else if (line.startsWith("/quit")) {
  144. scanner.close();
  145. connection.disconnect(new Presence(Presence.Type.unavailable, "Smack is still alive :D", 100, Presence.Mode.away));
  146. break;
  147. } else if (line.startsWith("/add")) {
  148. String jid = split.length == 4 ? split[1] : null;
  149. if(jid != null) {
  150. BareJid b = JidCreate.bareFrom(jid);
  151. roster.createEntry(b, split[2], new String[]{split[3]});
  152. } else {
  153. System.out.println("Usage: /add jid@server nick group");
  154. }
  155. } else if(line.startsWith("/remove")) {
  156. if(split.length == 2) {
  157. BareJid b = getJid(split[1]);
  158. roster.removeEntry(roster.getEntry(b));
  159. System.out.println("Removed contact from roster");
  160. }
  161. } else if(line.startsWith("/list")){
  162.  
  163. if(split.length == 1) {
  164. for (RosterEntry r : roster.getEntries()) {
  165. System.out.println(r.getName() + " (" + r.getJid() + ") Can I see? " + r.canSeeHisPresence() + ". Can they see? " + r.canSeeMyPresence() + ". Online? " + roster.getPresence(r.getJid()).isAvailable());
  166. }
  167. for (EntityBareJid r : mucm.getJoinedRooms()) {
  168. System.out.println(r.asBareJid().toString());
  169. }
  170. } else {
  171. BareJid jid = getJid(split[1]);
  172. try {
  173. List<Presence> presences = roster.getAllPresences(jid);
  174. for(Presence p : presences) {
  175. System.out.println(p.getFrom()+" "+omemoManager.resourceSupportsOmemo(p.getFrom()));
  176. }
  177. } catch (Exception e) {}
  178. CachedDeviceList list = store.loadCachedDeviceList(jid);
  179. if(list == null) {
  180. list = new CachedDeviceList();
  181. }
  182. ArrayList<String> fps = new ArrayList<>();
  183. for(int id : list.getActiveDevices()) {
  184. IdentityKey idk = store.loadOmemoIdentityKey(new OmemoDevice(jid, id));
  185. if(idk != null) {
  186. fps.add(KeyUtil.prettyFingerprint(store.keyUtil().getFingerprint(idk)));
  187. } else {
  188. OmemoBundleElement b = omemoManager.getOmemoService().getPubSubHelper().fetchBundle(new OmemoDevice(jid, id));
  189. idk = store.keyUtil().identityKeyFromBytes(b.getIdentityKey());
  190. if(idk != null) {
  191. fps.add(KeyUtil.prettyFingerprint(store.keyUtil().getFingerprint(idk)));
  192. }
  193. }
  194. }
  195. for(int i=0; i<fps.size(); i++) {
  196. System.out.println(i+": "+fps.get(i));
  197. }
  198. }
  199. } else if(line.startsWith("/trust")) {
  200. if(split.length == 2) {
  201. System.out.println("Usage: \n0: Untrusted, 1: Trusted, otherwise: Undecided");
  202. BareJid jid = getJid(split[1]);
  203. if(jid != null) {
  204. CachedDeviceList l = store.loadCachedDeviceList(jid);
  205. int ourId = store.loadOmemoDeviceId();
  206. l.getActiveDevices().stream().filter(i -> i != ourId).forEach(i -> {
  207. OmemoDevice d = new OmemoDevice(jid, i);
  208. SignalOmemoSession s = (SignalOmemoSession) store.getOmemoSessionOf(d);
  209. if(s.getIdentityKey() == null) {
  210. try {
  211. System.out.println("Build session...");
  212. omemoService.buildSessionFromOmemoBundle(d);
  213. s = (SignalOmemoSession) store.getOmemoSessionOf(d);
  214. System.out.println("Session built.");
  215. } catch (CannotEstablishOmemoSessionException | CorruptedOmemoKeyException e) {
  216. e.printStackTrace();
  217. }
  218. }
  219. if (store.isDecidedOmemoIdentity(d, s.getIdentityKey())) {
  220. if (store.isTrustedOmemoIdentity(d, s.getIdentityKey())) {
  221. System.out.println("Status: Trusted");
  222. } else {
  223. System.out.println("Status: Untrusted");
  224. }
  225. } else {
  226. System.out.println("Status: Undecided");
  227. }
  228. System.out.println(KeyUtil.prettyFingerprint(s.getFingerprint()));
  229. String decision = scanner.nextLine();
  230. if (decision.equals("0")) {
  231. store.distrustOmemoIdentity(d, s.getIdentityKey());
  232. System.out.println("Identity has been untrusted.");
  233. } else if (decision.equals("1")) {
  234. store.trustOmemoIdentity(d, s.getIdentityKey());
  235. System.out.println("Identity has been trusted.");
  236. }
  237. });
  238. }
  239. }
  240.  
  241. } else if(line.startsWith("/fetchDevices")) {
  242. if(split.length == 2) {
  243. System.out.println("Fetching devices...");
  244. System.out.println("DeviceList "+ split[1]+" "+omemoManager.getOmemoService().getPubSubHelper().fetchDeviceList(getJid(split[1])));
  245. } else {
  246. System.out.println("Usage: /fetchDevices <jid>");
  247. }
  248. } else if(line.startsWith("/purge")) {
  249. omemoManager.purgeDevices();
  250. System.out.println("Purge successful.");
  251. } else if(line.startsWith("/regenerate")) {
  252. omemoManager.regenerate();
  253. System.out.println("Regeneration successful.");
  254. } else if(line.startsWith("/omemo")) {
  255. if(split.length == 1) {
  256. } else {
  257. BareJid recipient = getJid(split[1]);
  258. if (recipient != null) {
  259. String message = "";
  260. for (int i = 2; i < split.length; i++) {
  261. message += split[i] + " ";
  262. }
  263. Message m = new Message();
  264. m.setBody(message.trim());
  265. m.setTo(recipient);
  266.  
  267. try {
  268. Message e = omemoManager.encrypt(recipient, m);
  269. current = cm.createChat(recipient.asEntityJidIfPossible());
  270. current.sendMessage(e);
  271. } catch (UndecidedOmemoIdentityException e) {
  272. System.out.println("There are undecided identities:");
  273. for(OmemoDevice d : e.getUntrustedDevices()) {
  274. System.out.println(d.toString());
  275. }
  276. }
  277.  
  278. }
  279. }
  280. omemo = true;
  281. }
  282. else if(line.startsWith("/mucomemo")) {
  283. if(split.length >= 3) {
  284. BareJid mucJid = getJid(split[1]);
  285. if (mucJid != null) {
  286. String message = "";
  287. for (int i = 2; i < split.length; i++) {
  288. message += split[i] + " ";
  289. }
  290. Message m = new Message();
  291. m.setBody(message.trim());
  292. MultiUserChat muc = mucm.getMultiUserChat(mucJid.asEntityBareJidIfPossible());
  293. List<EntityFullJid> occupants = muc.getOccupants();
  294. ArrayList<BareJid> recipients = occupants.stream().map(e ->
  295. muc.getOccupant(e.asEntityFullJidIfPossible()).getJid().asBareJid())
  296. .collect(Collectors.toCollection(ArrayList::new));
  297. Message encrypted = omemoManager.encrypt(recipients, m);
  298. muc.sendMessage(encrypted);
  299. }
  300. }
  301. } else if(line.startsWith("/fingerprint")) {
  302. String fingerprint = omemoManager.getOurFingerprint();
  303. System.out.println(KeyUtil.prettyFingerprint(fingerprint));
  304. } else if(line.startsWith("/help")) {
  305. if(split.length == 1) {
  306. System.out.println("Available options: \n" +
  307. "/chat <Nickname/Jid> <Message>: Send a normal unencrypted chat message to a user. \n" +
  308. "/omemo <Nickname/Jid> <Message>: Send an OMEMO encrypted message to a user. \n" +
  309. "/mucomemo <MUC-Jid> <Message>: Send an OMEMO encrypted message to a group chat. \n" +
  310. "/list: List your roster. \n" +
  311. "/list <Nickname/Jid>: List all devices of a user. \n" +
  312. "/fingerprint: Show your OMEMO fingerprint. \n" +
  313. "/purge: Remove all other devices from your list of active devices. \n" +
  314. "/regenerate: Create a new OMEMO identity. \n" +
  315. "/add <jid> <Nickname> <group>: Add a new contact to your roster. \n" +
  316. "/remove <jid>: Remove a contact from your roster. \n" +
  317. "/quit: Quit the application.");
  318. }
  319. } else if(line.startsWith("/mam")) {
  320. MamManager mamManager = MamManager.getInstanceFor(connection);
  321. MamManager.MamQueryResult result = mamManager.queryArchive(new Date(System.currentTimeMillis()-1000*60*60*24), new Date(System.currentTimeMillis()));
  322. for(ClearTextMessage<?> r : omemoManager.decryptMamQueryResult(result)) {
  323. ClearTextMessage<IdentityKey> d = (ClearTextMessage<IdentityKey>) r;
  324. messageListener.onOmemoMessageReceived(d.getBody(), d.getOriginalMessage(), null, d.getMessageInformation());
  325. }
  326. System.out.println("Query finished");
  327. }
  328.  
  329.  
  330.  
  331. else {
  332. if(current != null) {
  333. if(!omemo) {
  334. current.sendMessage(line);
  335. } else {
  336. Message m = new Message();
  337. m.setBody(line.trim());
  338. try {
  339. Message e = omemoManager.encrypt(current.getParticipant().asEntityBareJid(), m);
  340. current.sendMessage(e);
  341. } catch (UndecidedOmemoIdentityException e) {
  342. System.out.println("There are undecided identities:");
  343. for(OmemoDevice d : e.getUntrustedDevices()) {
  344. System.out.println(d.toString());
  345. }
  346. }
  347. }
  348. }
  349. else
  350. System.out.println("please open a chat");
  351. }
  352. }
  353.  
  354.  
  355. }
  356.  
  357. public static void main(String[] args) {
  358. try {
  359. Main main = new Main();
  360. main.start();
  361. } catch (Exception ignored) {
  362. ignored.printStackTrace();
  363. }
  364. }
  365.  
  366. public BareJid getJid(String user) {
  367. Roster roster = Roster.getInstanceFor(connection);
  368. RosterEntry r = null;
  369. for(RosterEntry s : roster.getEntries()) {
  370. if(s.getName() != null && s.getName().equals(user)) {
  371. r = s;
  372. break;
  373. }
  374. }
  375. if(r != null) {
  376. return r.getJid();
  377. } else {
  378. try {
  379. return JidCreate.bareFrom(user);
  380. } catch (XmppStringprepException e) {
  381. e.printStackTrace();
  382. return null;
  383. }
  384. }
  385. }
  386. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement