]> git.somenet.org - pub/jan/dslab.git/blob - ue3/src/Server/TCPW.java
GITOLITE.txt
[pub/jan/dslab.git] / ue3 / src / Server / TCPW.java
1 package Server;\r
2 \r
3 import java.io.*;\r
4 import java.util.*;\r
5 import java.net.*;\r
6 import java.io.*;\r
7 import java.security.*;\r
8 import javax.crypto.*;\r
9 import javax.crypto.spec.*;\r
10 import java.math.*;\r
11 import org.bouncycastle.openssl.*; \r
12 import org.bouncycastle.util.encoders.*;\r
13 \r
14 /*\r
15 * >--TCPW--<\r
16 * Author: Someone\r
17\r
18 * PROTOCOL\r
19 * -------------\r
20 * 4 byte: msg length\r
21 * $length: msg data\r
22 */\r
23 public class TCPW implements Runnable{\r
24   private TCP $parent = null;\r
25   //Client\r
26   private Socket $sock = null;\r
27   private InputStream $in = null;\r
28   private OutputStream $out = null;\r
29   private String[] $usrInfo = null;\r
30   private Cipher $s2c = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding");\r
31   private Cipher $c2s = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding");\r
32   private PublicKey $puk = null;\r
33   private SecretKey $skey = null;\r
34   private String $challenge = null;\r
35   private byte[] $iv = null;\r
36   private boolean $nextIsC = false;\r
37 \r
38 public TCPW(Socket $s, TCP $t)throws Exception{\r
39   $parent = $t;\r
40   $t.$conn.add(this);\r
41   $sock = $s;\r
42   $c2s.init(Cipher.DECRYPT_MODE, Main.$tcp.$prk);\r
43   $in = $sock.getInputStream();\r
44   $out = $sock.getOutputStream();\r
45   new Thread(this).start();\r
46 }\r
47 \r
48 public void run(){\r
49   try{\r
50     while($sock != null){\r
51       receive();\r
52     }\r
53   }catch(Exception $e){$e.printStackTrace();}\r
54   $parent.delConn(this);\r
55 }\r
56 \r
57 public void send(String $msg){\r
58   try{\r
59     byte[] $encrypted = $s2c.doFinal($msg.getBytes());\r
60     byte[] $len = Helper.int2ba($encrypted.length);\r
61     $out.write($len);\r
62     $out.write($encrypted);\r
63     $out.flush();\r
64   }catch(Exception $e){$e.printStackTrace();}\r
65 }\r
66 \r
67 public void receive()throws Exception{\r
68   int $len = Helper.ba2int(Helper.readBA($in, 4));\r
69   byte[]$raw = Helper.readBA($in, $len);\r
70   String $msg = null;\r
71   if($puk == null){\r
72     $msg = new String($raw);\r
73   }else{\r
74     $msg = new String($c2s.doFinal($raw));\r
75   }\r
76   if($nextIsC){ //check challenge or kill\r
77     if($msg.equals($challenge)){\r
78       $c2s = Cipher.getInstance("AES/CTR/NoPadding");\r
79       $s2c = Cipher.getInstance("AES/CTR/NoPadding");\r
80       $c2s.init(Cipher.ENCRYPT_MODE, $skey, new IvParameterSpec($iv));\r
81       $s2c.init(Cipher.DECRYPT_MODE, $skey, new IvParameterSpec($iv));\r
82     }else{\r
83       shutdown();\r
84     }\r
85     return;\r
86   }\r
87   String $data[] = $msg.trim().split("\\s+"); //regex: whitespace character once and more\r
88   \r
89   if($data[0].equalsIgnoreCase("!login")){\r
90     if($data[1] != null){\r
91       PEMReader in = new PEMReader(new FileReader(Main.$cfg.getString("keys.public.dir")+File.separator+$data[1])); \r
92       $puk = (PublicKey) in.readObject();\r
93       $c2s.init(Cipher.DECRYPT_MODE, $puk);\r
94 \r
95       byte[] $rand = new byte[32]; \r
96       new SecureRandom().nextBytes($rand);\r
97       $challenge = new String(Base64.encode($rand));\r
98 \r
99       KeyGenerator $gen = KeyGenerator.getInstance("AES"); \r
100       $gen.init(256); \r
101       $skey = $gen.generateKey();\r
102 \r
103       byte[] $iv = new byte[16]; \r
104       new SecureRandom().nextBytes($iv);\r
105       send("!ok "+$data[2]+" "+$challenge+" "+new String(Base64.encode($skey.getEncoded()))+" "+new String(Base64.encode($rand)));\r
106 \r
107       $nextIsC = true;\r
108     }\r
109     shutdown();\r
110   }\r
111   if(!isLoggedIn()){\r
112     send("Not logged in! Log in now! (!login user pass)");\r
113     return;\r
114   }\r
115   if($data[0].equalsIgnoreCase("!logout")){\r
116     java.util.Date now = new Date(System.currentTimeMillis()); \r
117     java.text.DateFormat formatter = new java.text.SimpleDateFormat("dd.MM.yyyy HH:mm"); \r
118     String $date = formatter.format(now);\r
119     $usrInfo[2] = "Offline since:"+$date;\r
120     $usrInfo = null;\r
121     send("logged out!");\r
122   }\r
123   if($data[0].equalsIgnoreCase("!send")){\r
124     $parent.sendAll($usrInfo[0]+" said: "+$msg.substring(5).trim());\r
125   }\r
126   if($data[0].equalsIgnoreCase("!msg")){\r
127     String[] $udata = Main.$usr.get($data[1]);\r
128     if($udata == null || $data.length <2){\r
129       send("Supplied user is invalid!");\r
130       return;\r
131     }\r
132     TCPW $tmp = $parent.getConnByName($data[1]);\r
133     if($tmp == null){\r
134       send("User offline");\r
135       return;\r
136     }\r
137     if($tmp != null && $tmp.isLoggedIn())$tmp.send($usrInfo[0]+" whispers: "+$msg.substring(5+$data[1].length()).trim());\r
138     send("privmsg sent!");\r
139   }\r
140 }\r
141 \r
142 public boolean isLoggedIn(){\r
143   if($usrInfo != null) return true;\r
144   return false;\r
145 }\r
146 public String getName(){\r
147   if($usrInfo != null)return $usrInfo[0];\r
148   return null;\r
149 }\r
150 \r
151 public void shutdown(){\r
152   try{\r
153     $out.close();\r
154     $in.close();\r
155     $sock.close();\r
156     $sock = null;\r
157   }catch(Exception $e){$e.printStackTrace();}\r
158 }\r
159 }