Compare commits
656 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e94fdc6db | ||
|
|
52b56e23b2 | ||
|
|
2dfff2a75f | ||
|
|
36b07264f0 | ||
|
|
b5cf3b4f74 | ||
|
|
d86b7c7f77 | ||
|
|
11cc48ca25 | ||
|
|
bc88930fb7 | ||
|
|
9fa09cc1f9 | ||
|
|
69a40c8179 | ||
|
|
5cd7563d12 | ||
|
|
98b860b0f7 | ||
|
|
f78dada550 | ||
|
|
61c794e08f | ||
|
|
793c41a5c4 | ||
|
|
7c4c6f5912 | ||
|
|
7bd3e1d2a4 | ||
|
|
3d7f31b23d | ||
|
|
7a7914463f | ||
|
|
d4cfbbb822 | ||
|
|
51b775cfd4 | ||
|
|
ca9c60d2eb | ||
|
|
e3fd0e838d | ||
|
|
98e4421a90 | ||
|
|
800af34763 | ||
|
|
c6bf28f3f7 | ||
|
|
c94aadcb0e | ||
|
|
5c33f6784b | ||
|
|
6614498744 | ||
|
|
d2d3eb6490 | ||
|
|
e50da8164f | ||
|
|
0e993bec6f | ||
|
|
790ad468e4 | ||
|
|
87f76bb62b | ||
|
|
55ff7e8387 | ||
|
|
b6727bf7d2 | ||
|
|
bc1e457097 | ||
|
|
5b48bce585 | ||
|
|
cfb5ba89ce | ||
|
|
c34d1e3de6 | ||
|
|
5ceef16486 | ||
|
|
6a9683719c | ||
|
|
8a850dc8e6 | ||
|
|
cde66cd584 | ||
|
|
8216801728 | ||
|
|
7835e0c2c7 | ||
|
|
e608d10f45 | ||
|
|
75b5c97095 | ||
|
|
2465b8a376 | ||
|
|
d5876a12ed | ||
|
|
33cdd5d083 | ||
|
|
5c6587d4a8 | ||
|
|
bbdb59b9f9 | ||
|
|
c20d1d7d32 | ||
|
|
415844511c | ||
|
|
09c73019c5 | ||
|
|
a95d78438c | ||
|
|
10db82e9a0 | ||
|
|
ba674ad551 | ||
|
|
b6cae7cd2d | ||
|
|
35f36481b9 | ||
|
|
b077189dd5 | ||
|
|
0257815141 | ||
|
|
705559d65e | ||
|
|
d0639e8925 | ||
|
|
64285140f9 | ||
|
|
51de9f9fdf | ||
|
|
05e4d4468e | ||
|
|
269780c577 | ||
|
|
f203881b0d | ||
|
|
7800b7c910 | ||
|
|
aaf892e3af | ||
|
|
1ccb2c5dea | ||
|
|
6bcf29c0ed | ||
|
|
782bbee8c0 | ||
|
|
2aa175a6ca | ||
|
|
53792a5a28 | ||
|
|
6f157d936f | ||
|
|
330fbfe8cc | ||
|
|
a74ca40660 | ||
|
|
57f01ffb07 | ||
|
|
1e0bab65e3 | ||
|
|
68952d579e | ||
|
|
25cb9471f0 | ||
|
|
294bca139c | ||
|
|
935af538f1 | ||
|
|
e9264a8253 | ||
|
|
6600c589ab | ||
|
|
0f406e9daa | ||
|
|
7a79eeb143 | ||
|
|
8c6f1dd36b | ||
|
|
6212b69fb4 | ||
|
|
446f9f0a0f | ||
|
|
20fa6a3083 | ||
|
|
280dd94198 | ||
|
|
fa3dff268b | ||
|
|
a658dba410 | ||
|
|
fb7526fc4f | ||
|
|
d0ee4d60d0 | ||
|
|
060e3198bc | ||
|
|
891c441a6d | ||
|
|
9cfc785cd3 | ||
|
|
46ab6ed491 | ||
|
|
f5e49ef598 | ||
|
|
04552375a9 | ||
|
|
101f92b256 | ||
|
|
f578d68e55 | ||
|
|
8e6fabd69a | ||
|
|
09f664cdea | ||
|
|
7b3d3dc85e | ||
|
|
e93b343ac4 | ||
|
|
8b768983a7 | ||
|
|
6f1fa30bc6 | ||
|
|
8b66681929 | ||
|
|
e42136a6ef | ||
|
|
e2dc7ba09d | ||
|
|
5347cb9c26 | ||
|
|
3b84111493 | ||
|
|
018c229ae4 | ||
|
|
cfab272321 | ||
|
|
440a9f6bda | ||
|
|
935505bc4f | ||
|
|
3c8dcf8808 | ||
|
|
d16b3ed8fa | ||
|
|
bf8367d6cf | ||
|
|
4d250095cb | ||
|
|
0451eb193e | ||
|
|
1c6139e013 | ||
|
|
9f0db83c48 | ||
|
|
505da188eb | ||
|
|
09c29e894e | ||
|
|
8c976ac7f0 | ||
|
|
64bf97bfb0 | ||
|
|
15c367ffb4 | ||
|
|
75ce5772ea | ||
|
|
626fc39804 | ||
|
|
57d6650e8e | ||
|
|
68f1000e42 | ||
|
|
0d59fd7e01 | ||
|
|
21f74efa10 | ||
|
|
e039940f49 | ||
|
|
3f9263a57a | ||
|
|
d115b5ae70 | ||
|
|
54cee9db7f | ||
|
|
b7d89f6919 | ||
|
|
5630d3f660 | ||
|
|
9c009a872e | ||
|
|
3fc9af63c1 | ||
|
|
26cefc95e8 | ||
|
|
a33e90f081 | ||
|
|
71ae158d7b | ||
|
|
a2f9ca1d4d | ||
|
|
38ddbcc314 | ||
|
|
87463049f1 | ||
|
|
514e19b172 | ||
|
|
c6d1fe9e59 | ||
|
|
82893ffae2 | ||
|
|
3787f8befb | ||
|
|
a77ccc406d | ||
|
|
60659a89c3 | ||
|
|
1b7990897e | ||
|
|
3e96015e61 | ||
|
|
53e453f72e | ||
|
|
15e234558d | ||
|
|
b70e91bbd4 | ||
|
|
e8553f966f | ||
|
|
11c63dcb9f | ||
|
|
5c80450ce7 | ||
|
|
3189d144a5 | ||
|
|
a66d018363 | ||
|
|
d88d72e50b | ||
|
|
b0566b9d4c | ||
|
|
ed389d8f05 | ||
|
|
bbaa8bdba5 | ||
|
|
6200bfa13e | ||
|
|
1bfe847a84 | ||
|
|
20b270ae9a | ||
|
|
111660854d | ||
|
|
76f2e6c9a4 | ||
|
|
8b4b962643 | ||
|
|
1b225f2a55 | ||
|
|
77f612eb61 | ||
|
|
0ef18a7cba | ||
|
|
32ad26f8bf | ||
|
|
8e68426ad6 | ||
|
|
c985e22196 | ||
|
|
87d05a95ff | ||
|
|
bb124e23b2 | ||
|
|
47b5fd666d | ||
|
|
31a092f6b4 | ||
|
|
f93a621856 | ||
|
|
84bffad3fc | ||
|
|
b4e9e55c34 | ||
|
|
a5bf9d3eb3 | ||
|
|
c643234c98 | ||
|
|
4ce309107a | ||
|
|
525a8f6a16 | ||
|
|
2be31b726a | ||
|
|
1a26f8215d | ||
|
|
da496669c2 | ||
|
|
013ca2a00a | ||
|
|
63324e0d52 | ||
|
|
e4079aa746 | ||
|
|
150814f6a8 | ||
|
|
a44a76a7da | ||
|
|
1d09a558a7 | ||
|
|
01b8b0d876 | ||
|
|
04d9ec8c3c | ||
|
|
79af9e89c4 | ||
|
|
aab45078ad | ||
|
|
e49c920d16 | ||
|
|
3749d52b66 | ||
|
|
729fd9301f | ||
|
|
bbd9acf551 | ||
|
|
572e8a4962 | ||
|
|
4b6fdc92dc | ||
|
|
097b566e54 | ||
|
|
ceb12438b6 | ||
|
|
d02bcade3a | ||
|
|
c4426952ad | ||
|
|
a7e64a1a03 | ||
|
|
de294da2a7 | ||
|
|
40d63c9e7a | ||
|
|
aa708a2d28 | ||
|
|
4acc9aca27 | ||
|
|
837fcc65f5 | ||
|
|
fe86194cc2 | ||
|
|
9c30e2e86d | ||
|
|
ef986202ee | ||
|
|
35d5da9f11 | ||
|
|
c664801d7d | ||
|
|
a695cf177d | ||
|
|
e41c84335d | ||
|
|
90365e270e | ||
|
|
4e9d4e8ddd | ||
|
|
9985cf5473 | ||
|
|
35fdd16940 | ||
|
|
d74a341e5d | ||
|
|
9fd4c37834 | ||
|
|
f070e4523a | ||
|
|
16e87a81ac | ||
|
|
38ebc81590 | ||
|
|
0a0a6aae0b | ||
|
|
3b80e8dd02 | ||
|
|
e287eac462 | ||
|
|
3060ad5575 | ||
|
|
8cd140ef33 | ||
|
|
47651b1ff2 | ||
|
|
243e0efefc | ||
|
|
35ee0c098f | ||
|
|
49dedd361c | ||
|
|
dd55a3e0b6 | ||
|
|
ceef6ee6be | ||
|
|
e6cdbefb3b | ||
|
|
ad893ad134 | ||
|
|
8ccfb376f3 | ||
|
|
015a74fd14 | ||
|
|
52d0536d2c | ||
|
|
e08f91c237 | ||
|
|
eac3b29d5f | ||
|
|
4db2abc01c | ||
|
|
e7c75933e7 | ||
|
|
874649f134 | ||
|
|
7cb242c168 | ||
|
|
1b1ccab8b7 | ||
|
|
7b9756f48e | ||
|
|
aae8a9959c | ||
|
|
d5a0099f49 | ||
|
|
18a03c063e | ||
|
|
4e53f1ee90 | ||
|
|
8ae64337ed | ||
|
|
c7952371b7 | ||
|
|
8ae3270807 | ||
|
|
a9495dc02f | ||
|
|
176d819559 | ||
|
|
8dabf88ae5 | ||
|
|
8a9352b3f7 | ||
|
|
d032504b17 | ||
|
|
d60fa9918b | ||
|
|
1f659948cd | ||
|
|
236447c65f | ||
|
|
6ba5f0f35b | ||
|
|
52779d9db9 | ||
|
|
55ddf853cd | ||
|
|
a3b47e0cb5 | ||
|
|
8254187bf3 | ||
|
|
0c458e2f1a | ||
|
|
987f443b5d | ||
|
|
9130cd63d3 | ||
|
|
18c1b44475 | ||
|
|
05492baf8d | ||
|
|
22192d1a46 | ||
|
|
b7b357528c | ||
|
|
a63240a848 | ||
|
|
e78b48ab20 | ||
|
|
7a312546f3 | ||
|
|
903038b8de | ||
|
|
2a194f98ec | ||
|
|
e9109812e1 | ||
|
|
0a25c2263d | ||
|
|
491f9bdcee | ||
|
|
b36e37f9da | ||
|
|
f9b04b84cd | ||
|
|
ee2950cd19 | ||
|
|
a0c63b6108 | ||
|
|
5f8855df55 | ||
|
|
08d6da2941 | ||
|
|
0a90a3eaba | ||
|
|
b3901a7652 | ||
|
|
0c2d894cea | ||
|
|
12b8a43dbe | ||
|
|
d42fdc4ff6 | ||
|
|
116fcfcf7a | ||
|
|
2fe54d17df | ||
|
|
efa98d514c | ||
|
|
c8d2b2594b | ||
|
|
51789228be | ||
|
|
2162ce1ae3 | ||
|
|
e5c076ab4e | ||
|
|
8c96264304 | ||
|
|
5e096c8ec9 | ||
|
|
c298fbfadc | ||
|
|
24a8dc408c | ||
|
|
d7748cea4f | ||
|
|
8fa96d1f3f | ||
|
|
5553eb6371 | ||
|
|
4e2d19714c | ||
|
|
618a9c0e2b | ||
|
|
c1788c37a1 | ||
|
|
7d90eb65ed | ||
|
|
a4f7728fad | ||
|
|
f1dc3f2ab2 | ||
|
|
549512e93e | ||
|
|
8385e586c0 | ||
|
|
747e1f0992 | ||
|
|
5fdf710c81 | ||
|
|
4c6a445361 | ||
|
|
4e1bbc1156 | ||
|
|
786e304bb9 | ||
|
|
4da8054e21 | ||
|
|
99ac7b8401 | ||
|
|
8110a9a3eb | ||
|
|
d8cadd2ff3 | ||
|
|
79a0334a02 | ||
|
|
ab0e10e60f | ||
|
|
b9737ed89e | ||
|
|
c6896d7392 | ||
|
|
61fab03b24 | ||
|
|
f526e5fa12 | ||
|
|
4979a22d3e | ||
|
|
ab1d8fa350 | ||
|
|
bb03255da0 | ||
|
|
c02fdb2463 | ||
|
|
f13e2213ea | ||
|
|
42d06a05c0 | ||
|
|
7ed1c1c231 | ||
|
|
c6ee813479 | ||
|
|
2df2fe0e4c | ||
|
|
15cc09f1b8 | ||
|
|
7fef0ecdf5 | ||
|
|
35f4a1c424 | ||
|
|
585bf9423f | ||
|
|
6dc945571d | ||
|
|
a6df72cfc8 | ||
|
|
e9ac4bef20 | ||
|
|
690f797da2 | ||
|
|
a2fddb4404 | ||
|
|
d187965233 | ||
|
|
a050eeef05 | ||
|
|
b6725ee802 | ||
|
|
a979e1ad50 | ||
|
|
2240d2a6a5 | ||
|
|
74c51df580 | ||
|
|
62e51018d0 | ||
|
|
0d05068f91 | ||
|
|
ed74ed24a0 | ||
|
|
45ab22f0d9 | ||
|
|
1441fade90 | ||
|
|
2153835545 | ||
|
|
2739cb4861 | ||
|
|
bc3ba4c993 | ||
|
|
50630d62fd | ||
|
|
0de97ad9e0 | ||
|
|
65e88f49d4 | ||
|
|
5690e7c399 | ||
|
|
18d0e840b5 | ||
|
|
552146d015 | ||
|
|
ac6987c54a | ||
|
|
76175672ad | ||
|
|
c8ae1e85b3 | ||
|
|
08f410cacc | ||
|
|
d138af7217 | ||
|
|
d51b8cab0c | ||
|
|
8d662e6636 | ||
|
|
fa6305ee98 | ||
|
|
fdffb23989 | ||
|
|
22d4559a7a | ||
|
|
4e13ab1d05 | ||
|
|
d57a1d6035 | ||
|
|
3f2d1381d0 | ||
|
|
d3aad7a185 | ||
|
|
23f7214fc3 | ||
|
|
e67dbf6123 | ||
|
|
041eafba73 | ||
|
|
5b5b79f5c4 | ||
|
|
93565392cd | ||
|
|
ed56d67cea | ||
|
|
e1356dd2b6 | ||
|
|
1790246fed | ||
|
|
15ad7704d2 | ||
|
|
533f61f67a | ||
|
|
8b841bc9e3 | ||
|
|
0bed5fae27 | ||
|
|
a03e1af7e7 | ||
|
|
883424030f | ||
|
|
688faa9baa | ||
|
|
764724748b | ||
|
|
2c73e8f816 | ||
|
|
2ba8296843 | ||
|
|
00942c1431 | ||
|
|
4a2964985c | ||
|
|
bd1d699040 | ||
|
|
4ef8260e9a | ||
|
|
6a5ddbd3d4 | ||
|
|
760d303dfa | ||
|
|
3afa2c38fb | ||
|
|
7789b602c8 | ||
|
|
bbfdc7b7de | ||
|
|
986a41d180 | ||
|
|
de08810a47 | ||
|
|
bcda65e453 | ||
|
|
5810e7c0df | ||
|
|
25fa596cd6 | ||
|
|
ddc9155c24 | ||
|
|
2df9c52c09 | ||
|
|
ee8058a2d9 | ||
|
|
554047da85 | ||
|
|
62ca9b71ff | ||
|
|
bc3bf969ba | ||
|
|
3f6619ff59 | ||
|
|
4f38b3a9c0 | ||
|
|
a4270efaf2 | ||
|
|
d2f5db1f37 | ||
|
|
1af26bb915 | ||
|
|
70dff87240 | ||
|
|
dbd75e02f7 | ||
|
|
18029df99c | ||
|
|
b0f77dfefd | ||
|
|
fa11b7c9be | ||
|
|
2616f490fe | ||
|
|
25a06c3ec1 | ||
|
|
0c3035a2b5 | ||
|
|
86a19faf68 | ||
|
|
9113277cd3 | ||
|
|
77a33c441b | ||
|
|
a3030f3ea3 | ||
|
|
0434988ade | ||
|
|
d32d6bc5e3 | ||
|
|
8ddc3b4ef2 | ||
|
|
b74ba817ea | ||
|
|
5f1d7a0746 | ||
|
|
71ad7140be | ||
|
|
7aa79b89e8 | ||
|
|
6ad8b1a15d | ||
|
|
a7df6e1503 | ||
|
|
acdc2d00b4 | ||
|
|
14def89f50 | ||
|
|
4ed8031172 | ||
|
|
08fdd23e23 | ||
|
|
fcc874fa18 | ||
|
|
a3509b7f22 | ||
|
|
a82ac9eaf0 | ||
|
|
f25156a637 | ||
|
|
3e70fa8d58 | ||
|
|
586472e364 | ||
|
|
da1ccfddeb | ||
|
|
1ad7e91527 | ||
|
|
5f785e26b9 | ||
|
|
b14c29b25c | ||
|
|
5326b7610a | ||
|
|
9c985f2d20 | ||
|
|
d9fda2b207 | ||
|
|
00d3395359 | ||
|
|
2709441d5b | ||
|
|
46bd780862 | ||
|
|
d3dce8f943 | ||
|
|
a1ecd25e8b | ||
|
|
d564086377 | ||
|
|
4914dbc971 | ||
|
|
e484e667a6 | ||
|
|
46c5982d3d | ||
|
|
205d2ad577 | ||
|
|
6874295c45 | ||
|
|
aea96132ec | ||
|
|
9f85f0b846 | ||
|
|
b1b94b49e4 | ||
|
|
5df0b9e961 | ||
|
|
866a93a8bc | ||
|
|
e3f28e1c06 | ||
|
|
76f2595df7 | ||
|
|
4026aa2e5f | ||
|
|
d41095c35e | ||
|
|
2b6bedac0e | ||
|
|
8b5e081233 | ||
|
|
64360f5996 | ||
|
|
7e6196511f | ||
|
|
fa72b2cd10 | ||
|
|
65b587cdbb | ||
|
|
cdd5a53767 | ||
|
|
56d2f9fbdb | ||
|
|
f7b3a6d571 | ||
|
|
a98d287e26 | ||
|
|
71642eac65 | ||
|
|
4b9ee4c31e | ||
|
|
5075ede6a9 | ||
|
|
35a914a549 | ||
|
|
c6150cc198 | ||
|
|
d5e3722c97 | ||
|
|
2a09cad420 | ||
|
|
05111f093d | ||
|
|
965d318164 | ||
|
|
28fd3bd461 | ||
|
|
3b246f7e27 | ||
|
|
17facd8b72 | ||
|
|
ae79fe1660 | ||
|
|
ee71bcfbe8 | ||
|
|
d9db1cf5b3 | ||
|
|
67f2610032 | ||
|
|
28daa93268 | ||
|
|
362fdf9bae | ||
|
|
e5bded7dee | ||
|
|
4cb0e5bfb4 | ||
|
|
d1ff527550 | ||
|
|
7629a43d82 | ||
|
|
b635112d36 | ||
|
|
4ac59a7859 | ||
|
|
8fbba59e8d | ||
|
|
45f4768a5c | ||
|
|
a566684e32 | ||
|
|
34adc83c71 | ||
|
|
6f00987850 | ||
|
|
9abff4f0ac | ||
|
|
e9006ae199 | ||
|
|
82245298f4 | ||
|
|
b1dc418a53 | ||
|
|
25f12b0e5d | ||
|
|
4d02ae0582 | ||
|
|
b9f8645258 | ||
|
|
2346a6d553 | ||
|
|
f8719f13df | ||
|
|
8309ab0ec8 | ||
|
|
2e72b310d9 | ||
|
|
f0122f1403 | ||
|
|
f23818ceea | ||
|
|
cd0e2f18e6 | ||
|
|
89a58d7e30 | ||
|
|
98a7aaca18 | ||
|
|
ce48cb4deb | ||
|
|
be133e7a0b | ||
|
|
ffd7043ee7 | ||
|
|
87623a8d75 | ||
|
|
b51aac8a86 | ||
|
|
730c78ac53 | ||
|
|
1662b8505b | ||
|
|
8ef208a9e2 | ||
|
|
7a3b871b33 | ||
|
|
0760607a7d | ||
|
|
9042d3f3b9 | ||
|
|
57c653be5f | ||
|
|
cbd8d09849 | ||
|
|
9d0e3c8d61 | ||
|
|
028d5bacc5 | ||
|
|
e337682d8e | ||
|
|
cfc6e8777e | ||
|
|
e3196dac4d | ||
|
|
179cf75862 | ||
|
|
f7e4e89b12 | ||
|
|
12d2b1f926 | ||
|
|
62088a6661 | ||
|
|
a817db5bd6 | ||
|
|
8cc0469ee7 | ||
|
|
bb6ec29b18 | ||
|
|
1ff6a767d0 | ||
|
|
357502fe03 | ||
|
|
17835b9b78 | ||
|
|
a1456742a8 | ||
|
|
f3742f29da | ||
|
|
f3f8462ddc | ||
|
|
73a7d893e3 | ||
|
|
759f5d71a6 | ||
|
|
af92153974 | ||
|
|
9b398c03ab | ||
|
|
675b3133b4 | ||
|
|
43f1c72511 | ||
|
|
ddb5748a76 | ||
|
|
c89c4361c3 | ||
|
|
78049abac1 | ||
|
|
acd511f676 | ||
|
|
c1eaa9f74c | ||
|
|
e6288e2d07 | ||
|
|
0f4ae61e7d | ||
|
|
6cd32bf96f | ||
|
|
3648c7953a | ||
|
|
4043829cf2 | ||
|
|
689f5f0d1f | ||
|
|
47e1695512 | ||
|
|
6ce8b49e05 | ||
|
|
1b961fc4ad | ||
|
|
9c24401b18 | ||
|
|
74d8b18408 | ||
|
|
5936a48e59 | ||
|
|
aa7f8ac90b | ||
|
|
ebfa9b2a5d | ||
|
|
5d6f855387 | ||
|
|
25b0631190 | ||
|
|
1c5434d72c | ||
|
|
ecd4645988 | ||
|
|
b0849387b7 | ||
|
|
669ce8ee7c | ||
|
|
6df4be93e3 | ||
|
|
f756d3bec1 | ||
|
|
1559ded009 | ||
|
|
ce41046786 | ||
|
|
7ec03e45a5 | ||
|
|
6dc0f105cc | ||
|
|
94ae720a22 | ||
|
|
76b4c6ba82 | ||
|
|
1a963b91bb | ||
|
|
7e21ac0eb8 | ||
|
|
1c9e7b982a | ||
|
|
b6e1bf63c3 | ||
|
|
76f83d7763 | ||
|
|
1a5b157c8f | ||
|
|
65fbb7bd0d | ||
|
|
8e176c2086 | ||
|
|
2a90ea69fd | ||
|
|
37c8d3425d | ||
|
|
18d4c3a9e9 | ||
|
|
46ec8f52e7 | ||
|
|
0a642f2441 | ||
|
|
f004326855 | ||
|
|
2ae7808ca9 | ||
|
|
b04d074341 | ||
|
|
0d9e0eac9a | ||
|
|
00929a51c0 | ||
|
|
e56793f01e | ||
|
|
7d7803a4d9 | ||
|
|
62f9864395 | ||
|
|
1de5209340 | ||
|
|
07110bbbf1 | ||
|
|
e285b17e3f | ||
|
|
613e9a298e | ||
|
|
6175d92583 | ||
|
|
f89581be1b | ||
|
|
c6075e1d93 | ||
|
|
3906f06617 |
6
.coveragerc
Normal file
@@ -0,0 +1,6 @@
|
||||
[rum]
|
||||
branch = True
|
||||
|
||||
[report]
|
||||
omit = *contrib*, *tnetstring*, *platform*, *console*
|
||||
include = *libmproxy*
|
||||
8
.gitignore
vendored
@@ -3,10 +3,12 @@ MANIFEST
|
||||
/dist
|
||||
/tmp
|
||||
/doc
|
||||
*.py[cd]
|
||||
/venv
|
||||
*.py[cdo]
|
||||
*.swp
|
||||
*.swo
|
||||
mitmproxyc
|
||||
mitmdumpc
|
||||
mitmplaybackc
|
||||
mitmrecordc
|
||||
.coverage
|
||||
netlib
|
||||
libpathod
|
||||
|
||||
191
CHANGELOG
@@ -1,24 +1,195 @@
|
||||
|
||||
x January 2013: mitmproxy 0.9:
|
||||
|
||||
* Upstream certs mode is now the default.
|
||||
|
||||
* Add a WSGI container that lets you host in-proxy web applications.
|
||||
|
||||
* Full transparent proxy support for Linux and OSX.
|
||||
|
||||
* Introduce netlib, a common codebase for mitmproxy and pathod
|
||||
(http://github.com/cortesi/netlib).
|
||||
|
||||
* Full support for SNI.
|
||||
|
||||
* Color palettes for mitmproxy, tailored for light and dark terminal
|
||||
backgrounds.
|
||||
|
||||
* Stream flows to file as responses arrive with the "W" shortcut in
|
||||
mitmproxy.
|
||||
|
||||
* Extend the filter language, including ~d domain match operator, ~a to
|
||||
match asset flows (js, images, css).
|
||||
|
||||
* Follow mode in mitmproxy ("F" shortcut) to "tail" flows as they arrive.
|
||||
|
||||
* --dummy-certs option to specify and preserve the dummy certificate
|
||||
directory.
|
||||
|
||||
* Server replay from the current captured buffer.
|
||||
|
||||
* Huge improvements in content views. We now have viewers for AMF, HTML,
|
||||
JSON, Javascript, images, XML, URL-encoded forms, as well as hexadecimal
|
||||
and raw views.
|
||||
|
||||
* Add Set Headers, analagous to replacement hooks. Defines headers that are set
|
||||
on flows, based on a matching pattern.
|
||||
|
||||
* A graphical editor for path components in mitmproxy.
|
||||
|
||||
* A small set of standard user-agent strings, which can be used easily in
|
||||
the header editor.
|
||||
|
||||
* Proxy authentication to limit access to mitmproxy
|
||||
|
||||
|
||||
1 March 2010: mitmproxy 0.2
|
||||
5 April 2012: mitmproxy 0.8:
|
||||
|
||||
* Detailed tutorial for Android interception. Some features that land in
|
||||
this release have finally made reliable Android interception possible.
|
||||
|
||||
* Upstream-cert mode, which uses information from the upstream server to
|
||||
generate interception certificates.
|
||||
|
||||
* Replacement patterns that let you easily do global replacements in flows
|
||||
matching filter patterns. Can be specified on the command-line, or edited
|
||||
interactively.
|
||||
|
||||
* Much more sophisticated and usable pretty printing of request bodies.
|
||||
Support for auto-indentation of Javascript, inspection of image EXIF
|
||||
data, and more.
|
||||
|
||||
* Details view for flows, showing connection and SSL cert information (X
|
||||
keyboard shortcut).
|
||||
|
||||
* Server certificates are now stored and serialized in saved traffic for
|
||||
later analysis. This means that the 0.8 serialization format is NOT
|
||||
compatible with 0.7.
|
||||
|
||||
* Many other improvements, including bugfixes, and expanded scripting API,
|
||||
and more sophisticated certificate handling.
|
||||
|
||||
|
||||
20 February 2012: mitmproxy 0.7:
|
||||
|
||||
* New built-in key/value editor. This lets you interactively edit URL query
|
||||
strings, headers and URL-encoded form data.
|
||||
|
||||
* Extend script API to allow duplication and replay of flows.
|
||||
|
||||
* API for easy manipulation of URL-encoded forms and query strings.
|
||||
|
||||
* Add "D" shortcut in mitmproxy to duplicate a flow.
|
||||
|
||||
* Reverse proxy mode. In this mode mitmproxy acts as an HTTP server,
|
||||
forwarding all traffic to a specified upstream server.
|
||||
|
||||
* UI improvements - use unicode characters to make GUI more compact,
|
||||
improve spacing and layout throughout.
|
||||
|
||||
* Add support for filtering by HTTP method.
|
||||
|
||||
* Add the ability to specify an HTTP body size limit.
|
||||
|
||||
* Move to typed netstrings for serialization format - this makes 0.7
|
||||
backwards-incompatible with serialized data from 0.6!
|
||||
|
||||
* Significant improvements in speed and responsiveness of UI.
|
||||
|
||||
* Many minor bugfixes and improvements.
|
||||
|
||||
|
||||
7 August 2011: mitmproxy 0.6:
|
||||
|
||||
* New scripting API that allows much more flexible and fine-grained
|
||||
rewriting of traffic. See the docs for more info.
|
||||
|
||||
* Support for gzip and deflate content encodings. A new "z"
|
||||
keybinding in mitmproxy to let us quickly encode and decode content, plus
|
||||
automatic decoding for the "pretty" view mode.
|
||||
|
||||
* An event log, viewable with the "v" shortcut in mitmproxy, and the
|
||||
"-e" command-line flag in mitmdump.
|
||||
|
||||
* Huge performance improvements: mitmproxy interface, loading
|
||||
large numbers of flows from file.
|
||||
|
||||
* A new "replace" convenience method for all flow objects, that does a
|
||||
universal regex-based string replacement.
|
||||
|
||||
* Header management has been rewritten to maintain both case and order.
|
||||
|
||||
* Improved stability for SSL interception.
|
||||
|
||||
* Default expiry time on generated SSL certs has been dropped to avoid an
|
||||
OpenSSL overflow bug that caused certificates to expire in the distant
|
||||
past on some systems.
|
||||
|
||||
* A "pretty" view mode for JSON and form submission data.
|
||||
|
||||
* Expanded documentation and examples.
|
||||
|
||||
* Countless other small improvements and bugfixes.
|
||||
|
||||
|
||||
27 June 2011: mitmproxy 0.5:
|
||||
|
||||
* An -n option to start the tools without binding to a proxy port.
|
||||
|
||||
* Allow scripts, hooks, sticky cookies etc. to run on flows loaded from
|
||||
save files.
|
||||
|
||||
* Regularize command-line options for mitmproxy and mitmdump.
|
||||
|
||||
* Add an "SSL exception" to mitmproxy's license to remove possible
|
||||
distribution issues.
|
||||
|
||||
* Add a --cert-wait-time option to make mitmproxy pause after a new SSL
|
||||
certificate is generated. This can pave over small discrepancies in
|
||||
system time between the client and server.
|
||||
|
||||
* Handle viewing big request and response bodies more elegantly. Only
|
||||
render the first 100k of large documents, and try to avoid running the
|
||||
XML indenter on non-XML data.
|
||||
|
||||
* BUGFIX: Make the "revert" keyboard shortcut in mitmproxy work after a
|
||||
flow has been replayed.
|
||||
|
||||
* BUGFIX: Repair a problem that sometimes caused SSL connections to consume
|
||||
100% of CPU.
|
||||
|
||||
|
||||
30 March 2011: mitmproxy 0.4
|
||||
|
||||
* Full serialization of HTTP conversations
|
||||
|
||||
* Client and server replay
|
||||
|
||||
* On-the-fly generation of dummy SSL certificates
|
||||
|
||||
* mitmdump has "grown up" into a powerful tcpdump-like tool for HTTP/S
|
||||
|
||||
* Dozens of improvements to the mitmproxy console interface
|
||||
|
||||
* Python scripting hooks for programmatic modification of traffic
|
||||
|
||||
|
||||
1 March 2010: mitmproxy 0.2
|
||||
|
||||
* Big speed and responsiveness improvements, thanks to Thomas Roth
|
||||
|
||||
|
||||
* Support urwid 0.9.9
|
||||
*
|
||||
|
||||
* Terminal beeping based on filter expressions
|
||||
|
||||
|
||||
* Filter expressions for terminal beeps, limits, interceptions and sticky
|
||||
cookies can now be passed on the command line.
|
||||
|
||||
* Save requests and responses to file
|
||||
|
||||
|
||||
* Split off non-interactive dump functionality into a new tool called
|
||||
mitmdump
|
||||
|
||||
|
||||
* "A" will now accept all intercepted connections
|
||||
|
||||
|
||||
* Lots of bugfixes
|
||||
|
||||
|
||||
|
||||
|
||||
39
CONTRIBUTORS
@@ -1,4 +1,35 @@
|
||||
179 Aldo Cortesi
|
||||
18 Henrik Nordstrom
|
||||
13 Thomas Roth
|
||||
1 Henrik Nordström
|
||||
759 Aldo Cortesi
|
||||
18 Henrik Nordstrom
|
||||
13 Thomas Roth
|
||||
11 Stephen Altamirano
|
||||
10 András Veres-Szentkirályi
|
||||
8 Rouli
|
||||
7 Alexis Hildebrandt
|
||||
5 Maximilian Hils
|
||||
4 Bryan Bishop
|
||||
4 Valtteri Virtanen
|
||||
3 Chris Neasbitt
|
||||
2 Michael Frister
|
||||
2 Heikki Hannikainen
|
||||
2 Jim Lloyd
|
||||
2 Mark E. Haase
|
||||
2 Rob Wills
|
||||
2 alts
|
||||
2 israel
|
||||
1 Jakub Nawalaniec
|
||||
1 Paul
|
||||
1 phil plante
|
||||
1 Rory McCann
|
||||
1 Henrik Nordström
|
||||
1 Rune Halvorsen
|
||||
1 Sahn Lam
|
||||
1 Felix Wolfsteller
|
||||
1 Eric Entzel
|
||||
1 Ulrich Petri
|
||||
1 Andy Smith
|
||||
1 Yuangxuan Wang
|
||||
1 meeee
|
||||
1 capt8bit
|
||||
1 Mathieu Mitchell
|
||||
1 Jason A. Novak
|
||||
1 Nicolas Esteves
|
||||
|
||||
693
LICENSE
@@ -1,674 +1,19 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
Copyright (c) 2013, Aldo Cortesi. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
include LICENSE
|
||||
include CHANGELOG
|
||||
include CONTRIBUTORS
|
||||
include README.mkd
|
||||
include README.txt
|
||||
exclude README.mkd
|
||||
recursive-include examples *
|
||||
recursive-include doc *
|
||||
recursive-include test *
|
||||
|
||||
76
README.mkd
@@ -1,54 +1,60 @@
|
||||
__mitmproxy__ is an interactive, SSL-capable man-in-the-middle proxy for HTTP
|
||||
with a console interface.
|
||||
|
||||
__mitmproxy__ is an SSL-capable, intercepting HTTP proxy. It provides a console
|
||||
interface that allows traffic flows to be inspected and edited on the fly.
|
||||
__mitmdump__ is the command-line version of mitmproxy. Think tcpdump for HTTP.
|
||||
|
||||
__mitmdump__ is the command-line version of mitmproxy, with the same
|
||||
functionality but without the frills. Think tcpdump for HTTP.
|
||||
__libmproxy__ is the library that mitmproxy and mitmdump are built on.
|
||||
|
||||
Both tools are fully documentented in the commandline __--help__ flag, and, in
|
||||
the case of __mitmproxy__, a built-in help page accessible through the __?__
|
||||
keyboard shortcut.
|
||||
Documentation, tutorials and distribution packages can be found on the
|
||||
mitmproxy.org website:
|
||||
|
||||
[mitmproxy.org](http://mitmproxy.org).
|
||||
|
||||
|
||||
Capabilities
|
||||
------------
|
||||
Features
|
||||
--------
|
||||
|
||||
- Intercept HTTP requests and responses and modify them on the fly.
|
||||
- Save complete HTTP conversations for later replay and analysis.
|
||||
- Replay the client-side of an HTTP conversations.
|
||||
- Replay HTTP responses of a previously recorded server.
|
||||
- Make scripted changes to HTTP traffic using Python.
|
||||
- Reverse proxy mode to forward traffic to a specified server.
|
||||
- Transparent proxy mode on OSX and Linux.
|
||||
- Make scripted changes to HTTP traffic using Python.
|
||||
- SSL certificates for interception are generated on the fly.
|
||||
|
||||
|
||||
Download
|
||||
--------
|
||||
|
||||
Releases and rendered documentation can be found on the mitmproxy website:
|
||||
|
||||
[mitmproxy.org](http://mitmproxy.org)
|
||||
|
||||
Source is hosted on github:
|
||||
|
||||
[github.com/cortesi/mitmproxy](http://github.com/cortesi/mitmproxy)
|
||||
- And much, much more.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
* [Python](http://www.python.org) 2.6.x or 2.7.x.
|
||||
* [openssl](http://www.openssl.org/). Installed by default on most systems.
|
||||
* [urwid](http://excess.org/urwid/) version 0.9.8 or newer.
|
||||
* The test suite uses the [pry](http://github.com/cortesi/pry) unit testing
|
||||
library.
|
||||
* [Python](http://www.python.org) 2.7.x.
|
||||
* [netlib](http://pypi.python.org/pypi/netlib), version matching mitmproxy.
|
||||
* [PyOpenSSL](http://pypi.python.org/pypi/pyOpenSSL) 0.13 or newer.
|
||||
* [pyasn1](http://pypi.python.org/pypi/pyasn1) 0.1.2 or newer.
|
||||
* [urwid](http://excess.org/urwid/) version 1.1 or newer.
|
||||
* [PIL](http://www.pythonware.com/products/pil/) version 1.1 or newer.
|
||||
* [lxml](http://lxml.de/) version 2.3 or newer.
|
||||
* [flask](http://flask.pocoo.org/) version 0.9 or newer.
|
||||
|
||||
Optional, for extended content decoding:
|
||||
|
||||
* [PyAMF](http://www.pyamf.org/) version 0.6.1 or newer.
|
||||
* [protobuf](https://code.google.com/p/protobuf/) version 2.5.0 or newer.
|
||||
|
||||
__mitmproxy__ is tested and developed on OSX, Linux and OpenBSD. Windows is not
|
||||
officially supported at the moment.
|
||||
|
||||
|
||||
Hacking
|
||||
-------
|
||||
|
||||
The following components are needed if you plan to hack on mitmproxy:
|
||||
|
||||
* The test suite uses the [nose](http://readthedocs.org/docs/nose/en/latest/) unit testing
|
||||
framework and requires [pathod](http://pathod.org) and [flask](http://flask.pocoo.org/).
|
||||
* Rendering the documentation requires [countershape](http://github.com/cortesi/countershape).
|
||||
|
||||
__mitmproxy__ is tested and developed on OSX, Linux and OpenBSD.
|
||||
Please ensure that all patches are accompanied by matching changes in the test
|
||||
suite. The project maintains 100% test coverage.
|
||||
|
||||
You should also make sure that your console environment is set up with the
|
||||
following:
|
||||
|
||||
* EDITOR environment variable to determine the external editor.
|
||||
* PAGER environment variable to determine the external pager.
|
||||
* Appropriate entries in your mailcap files to determine external
|
||||
viewers for request and response contents.
|
||||
|
||||
11
README.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
**mitmproxy** is an interactive, SSL-capable man-in-the-middle proxy for HTTP
|
||||
with a console interface.
|
||||
|
||||
**mitmdump** is the command-line version of mitmproxy. Think tcpdump for HTTP.
|
||||
|
||||
**libmproxy** is the library that mitmproxy and mitmdump are built on.
|
||||
|
||||
Complete documentation and a set of practical tutorials is included in the
|
||||
distribution package, and is also available at mitmproxy.org_.
|
||||
|
||||
.. _mitmproxy.org: http://mitmproxy.org
|
||||
9
doc-src/01-bootstrap.min.css
vendored
Normal file
@@ -1,91 +1,12 @@
|
||||
|
||||
a {
|
||||
color: #3F8ED8;
|
||||
text-decoration: none;
|
||||
body {
|
||||
padding-top: 60px;
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
|
||||
#hd.doc {
|
||||
-x-system-font:none;
|
||||
font-family: Helvetica,Arial,Tahoma,Verdana,Sans-Serif;
|
||||
color: #555555;
|
||||
margin: 0;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
#hd.doc h1 {
|
||||
letter-spacing: 3px;
|
||||
font-size: 2.5em;
|
||||
line-height: 100%;
|
||||
margin: 0.3em 0;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
#nav {
|
||||
float: right;
|
||||
}
|
||||
|
||||
|
||||
#bd {
|
||||
-x-system-font:none;
|
||||
font-family: Helvetica,Arial,Tahoma,Verdana,Sans-Serif;
|
||||
font-size: 1.6em;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
#bd h1 {
|
||||
font-size: 1.4em;
|
||||
border-bottom: 5px solid #ff7033;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
#bd h2 {
|
||||
font-size: 1.1em;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
#ft.doc {
|
||||
color: #aaa;
|
||||
border-top: 1px solid #aaa;
|
||||
clear: both;
|
||||
margin-top: 2em;
|
||||
font-size: 0.8em;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.faq .question {
|
||||
font-size: 1.1em;
|
||||
.tablenum {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
pre {
|
||||
padding: 10px;
|
||||
background-color: #dddddd;
|
||||
}
|
||||
|
||||
.docindex, .docindex ul {
|
||||
margin-top: 0.1em;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.docindex li {
|
||||
list-style-position: inside;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.docindex ul {
|
||||
margin-left: 2em;
|
||||
}
|
||||
|
||||
li a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
font-size: 14px;
|
||||
.nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
572
doc-src/_explicit.graffle/data.plist
Normal file
@@ -0,0 +1,572 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>ActiveLayerIndex</key>
|
||||
<integer>0</integer>
|
||||
<key>ApplicationVersion</key>
|
||||
<array>
|
||||
<string>com.omnigroup.OmniGraffle.MacAppStore</string>
|
||||
<string>139.16</string>
|
||||
</array>
|
||||
<key>AutoAdjust</key>
|
||||
<true/>
|
||||
<key>BackgroundGraphic</key>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{0, 0}, {559.19998741149902, 782.79998779296875}}</string>
|
||||
<key>Class</key>
|
||||
<string>SolidGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>2</integer>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>BaseZoom</key>
|
||||
<integer>0</integer>
|
||||
<key>CanvasOrigin</key>
|
||||
<string>{0, 0}</string>
|
||||
<key>ColumnAlign</key>
|
||||
<integer>1</integer>
|
||||
<key>ColumnSpacing</key>
|
||||
<real>36</real>
|
||||
<key>CreationDate</key>
|
||||
<string>2013-01-02 19:31:53 +0000</string>
|
||||
<key>Creator</key>
|
||||
<string>Aldo Cortesi</string>
|
||||
<key>DisplayScale</key>
|
||||
<string>1.000 cm = 1.000 cm</string>
|
||||
<key>GraphDocumentVersion</key>
|
||||
<integer>8</integer>
|
||||
<key>GraphicsList</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>Class</key>
|
||||
<string>LineGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>4074</integer>
|
||||
<key>Points</key>
|
||||
<array>
|
||||
<string>{300.4483540852865, 420.70833897590637}</string>
|
||||
<string>{344.88497416178387, 420.70833897590654}</string>
|
||||
<string>{362.21830749511713, 420.04167230923986}</string>
|
||||
<string>{413.55166625976557, 419.70833905537921}</string>
|
||||
</array>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>HeadArrow</key>
|
||||
<string>FilledArrow</string>
|
||||
<key>Legacy</key>
|
||||
<true/>
|
||||
<key>TailArrow</key>
|
||||
<string>0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Class</key>
|
||||
<string>LineGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>4070</integer>
|
||||
<key>Points</key>
|
||||
<array>
|
||||
<string>{84.896692911783873, 420.66667453447985}</string>
|
||||
<string>{129.33331298828122, 420.66667453448002}</string>
|
||||
<string>{146.66664632161454, 420.00000786781334}</string>
|
||||
<string>{198.00000508626297, 419.66667461395269}</string>
|
||||
</array>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>HeadArrow</key>
|
||||
<string>FilledArrow</string>
|
||||
<key>Legacy</key>
|
||||
<true/>
|
||||
<key>TailArrow</key>
|
||||
<string>0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{326.00000000000023, 391.39999198913591}, {62, 24}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>FitText</key>
|
||||
<string>YES</string>
|
||||
<key>Flow</key>
|
||||
<string>Resize</string>
|
||||
<key>FontInfo</key>
|
||||
<dict>
|
||||
<key>Font</key>
|
||||
<string>Helvetica</string>
|
||||
<key>Size</key>
|
||||
<real>12</real>
|
||||
</dict>
|
||||
<key>ID</key>
|
||||
<integer>4063</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Pad</key>
|
||||
<integer>0</integer>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs20 \cf0 2: Forwarded \
|
||||
Request}</string>
|
||||
<key>VerticalPad</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Wrap</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{110, 403.39997863769622}, {49, 12}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>FitText</key>
|
||||
<string>YES</string>
|
||||
<key>Flow</key>
|
||||
<string>Resize</string>
|
||||
<key>FontInfo</key>
|
||||
<dict>
|
||||
<key>Font</key>
|
||||
<string>Helvetica</string>
|
||||
<key>Size</key>
|
||||
<real>12</real>
|
||||
</dict>
|
||||
<key>ID</key>
|
||||
<integer>4061</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Pad</key>
|
||||
<integer>0</integer>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs20 \cf0 1: Request}</string>
|
||||
<key>VerticalPad</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Wrap</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{430.83098347981803, 515.99999999999989}, {36, 14}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>FitText</key>
|
||||
<string>YES</string>
|
||||
<key>Flow</key>
|
||||
<string>Resize</string>
|
||||
<key>ID</key>
|
||||
<integer>4026</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Pad</key>
|
||||
<integer>0</integer>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs24 \cf0 Server}</string>
|
||||
<key>VerticalPad</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Wrap</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{40.499999999999993, 486.66666666666663}, {31, 14}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>FitText</key>
|
||||
<string>YES</string>
|
||||
<key>Flow</key>
|
||||
<string>Resize</string>
|
||||
<key>ID</key>
|
||||
<integer>4025</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Pad</key>
|
||||
<integer>0</integer>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs24 \cf0 Client}</string>
|
||||
<key>VerticalPad</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Wrap</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{417.16432189941418, 323.90565299479198}, {63.333332061767578, 185.52200317382812}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>4004</integer>
|
||||
<key>ImageID</key>
|
||||
<integer>6</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{205.34386889139773, 289.33333333333331}, {84, 248.66667175292969}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>4023</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Color</key>
|
||||
<dict>
|
||||
<key>b</key>
|
||||
<string>0</string>
|
||||
<key>g</key>
|
||||
<string>0.463735</string>
|
||||
<key>r</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;\red37\green17\blue0;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs24 \cf2 mitmproxy}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{4.6666666467984399, 351.33332316080771}, {102.66666412353516, 130.66667175292969}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>134</integer>
|
||||
<key>ImageID</key>
|
||||
<integer>3</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GridInfo</key>
|
||||
<dict/>
|
||||
<key>GuidesLocked</key>
|
||||
<string>NO</string>
|
||||
<key>GuidesVisible</key>
|
||||
<string>YES</string>
|
||||
<key>HPages</key>
|
||||
<integer>1</integer>
|
||||
<key>ImageCounter</key>
|
||||
<integer>7</integer>
|
||||
<key>ImageLinkBack</key>
|
||||
<array>
|
||||
<dict/>
|
||||
<dict/>
|
||||
</array>
|
||||
<key>ImageList</key>
|
||||
<array>
|
||||
<string>image6.tiff</string>
|
||||
<string>image3.icns</string>
|
||||
</array>
|
||||
<key>KeepToScale</key>
|
||||
<false/>
|
||||
<key>Layers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>Lock</key>
|
||||
<string>NO</string>
|
||||
<key>Name</key>
|
||||
<string>Layer 1</string>
|
||||
<key>Print</key>
|
||||
<string>YES</string>
|
||||
<key>View</key>
|
||||
<string>YES</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>LayoutInfo</key>
|
||||
<dict>
|
||||
<key>Animate</key>
|
||||
<string>NO</string>
|
||||
<key>circoMinDist</key>
|
||||
<real>18</real>
|
||||
<key>circoSeparation</key>
|
||||
<real>0.0</real>
|
||||
<key>layoutEngine</key>
|
||||
<string>dot</string>
|
||||
<key>neatoSeparation</key>
|
||||
<real>0.0</real>
|
||||
<key>twopiSeparation</key>
|
||||
<real>0.0</real>
|
||||
</dict>
|
||||
<key>LinksVisible</key>
|
||||
<string>NO</string>
|
||||
<key>MagnetsVisible</key>
|
||||
<string>NO</string>
|
||||
<key>MasterSheets</key>
|
||||
<array/>
|
||||
<key>ModificationDate</key>
|
||||
<string>2013-01-03 02:27:49 +0000</string>
|
||||
<key>Modifier</key>
|
||||
<string>Aldo Cortesi</string>
|
||||
<key>NotesVisible</key>
|
||||
<string>NO</string>
|
||||
<key>Orientation</key>
|
||||
<integer>2</integer>
|
||||
<key>OriginVisible</key>
|
||||
<string>NO</string>
|
||||
<key>PageBreaks</key>
|
||||
<string>YES</string>
|
||||
<key>PrintInfo</key>
|
||||
<dict>
|
||||
<key>NSBottomMargin</key>
|
||||
<array>
|
||||
<string>float</string>
|
||||
<string>41</string>
|
||||
</array>
|
||||
<key>NSHorizonalPagination</key>
|
||||
<array>
|
||||
<string>coded</string>
|
||||
<string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG</string>
|
||||
</array>
|
||||
<key>NSLeftMargin</key>
|
||||
<array>
|
||||
<string>float</string>
|
||||
<string>18</string>
|
||||
</array>
|
||||
<key>NSPaperSize</key>
|
||||
<array>
|
||||
<string>size</string>
|
||||
<string>{595.19998741149902, 841.79998779296875}</string>
|
||||
</array>
|
||||
<key>NSPrintReverseOrientation</key>
|
||||
<array>
|
||||
<string>int</string>
|
||||
<string>0</string>
|
||||
</array>
|
||||
<key>NSRightMargin</key>
|
||||
<array>
|
||||
<string>float</string>
|
||||
<string>18</string>
|
||||
</array>
|
||||
<key>NSTopMargin</key>
|
||||
<array>
|
||||
<string>float</string>
|
||||
<string>18</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>PrintOnePage</key>
|
||||
<false/>
|
||||
<key>ReadOnly</key>
|
||||
<string>NO</string>
|
||||
<key>RowAlign</key>
|
||||
<integer>1</integer>
|
||||
<key>RowSpacing</key>
|
||||
<real>36</real>
|
||||
<key>SheetTitle</key>
|
||||
<string>Canvas 1</string>
|
||||
<key>SmartAlignmentGuidesActive</key>
|
||||
<string>YES</string>
|
||||
<key>SmartDistanceGuidesActive</key>
|
||||
<string>YES</string>
|
||||
<key>UniqueID</key>
|
||||
<integer>1</integer>
|
||||
<key>UseEntirePage</key>
|
||||
<false/>
|
||||
<key>VPages</key>
|
||||
<integer>1</integer>
|
||||
<key>WindowInfo</key>
|
||||
<dict>
|
||||
<key>CurrentSheet</key>
|
||||
<integer>0</integer>
|
||||
<key>ExpandedCanvases</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Canvas 1</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Frame</key>
|
||||
<string>{{300, 236}, {974, 874}}</string>
|
||||
<key>ListView</key>
|
||||
<true/>
|
||||
<key>OutlineWidth</key>
|
||||
<integer>142</integer>
|
||||
<key>RightSidebar</key>
|
||||
<false/>
|
||||
<key>ShowRuler</key>
|
||||
<true/>
|
||||
<key>Sidebar</key>
|
||||
<true/>
|
||||
<key>SidebarWidth</key>
|
||||
<integer>120</integer>
|
||||
<key>VisibleRegion</key>
|
||||
<string>{{0, 202}, {550, 469.33333333333337}}</string>
|
||||
<key>Zoom</key>
|
||||
<real>1.5</real>
|
||||
<key>ZoomValues</key>
|
||||
<array>
|
||||
<array>
|
||||
<string>Canvas 1</string>
|
||||
<real>1.5</real>
|
||||
<real>1</real>
|
||||
</array>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
doc-src/_explicit.graffle/image3.icns
Normal file
BIN
doc-src/_explicit.graffle/image6.tiff
Normal file
1054
doc-src/_explicit_https.graffle/data.plist
Normal file
BIN
doc-src/_explicit_https.graffle/image3.icns
Normal file
BIN
doc-src/_explicit_https.graffle/image6.tiff
Normal file
@@ -1,30 +1,78 @@
|
||||
<div id="doc">
|
||||
<div style="" id="hd" class="doc">
|
||||
<!--(block nav)-->
|
||||
<div id="nav">
|
||||
<!--(block pb)-->
|
||||
<a href="@!urlTo(previous)!@">prev</a>
|
||||
<!--(end)-->
|
||||
<!--(block nb)-->
|
||||
<a href="@!urlTo(next)!@">next</a>
|
||||
<!--(end)-->
|
||||
$!pb if previous else "prev"!$ |
|
||||
<a href="@!urlTo('/index.html')!@">index</a> |
|
||||
$!nb if next else "next"!$
|
||||
</div>
|
||||
<!--(end)-->
|
||||
$!nav if this.title!="docs" else ""!$
|
||||
<h1><a href="@!urlTo("/index.html")!@">mitmproxy docs</a></h1>
|
||||
</div>
|
||||
<div id="bd">
|
||||
<div id="yui-main">
|
||||
<div style="" class="yui-b">
|
||||
$!title if this.title!="docs" else ""!$
|
||||
$!body!$
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="" id="ft" class="doc">
|
||||
<p>@!copyright!@</p>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="@!urlTo(idxpath)!@">mitmproxy 0.9 docs</a>
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="span3">
|
||||
<div class="well sidebar-nav">
|
||||
<ul class="nav nav-list">
|
||||
$!nav(idxpath, this, state)!$
|
||||
$!nav("install.html", this, state)!$
|
||||
$!nav("howmitmproxy.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Tools</li>
|
||||
$!nav("mitmproxy.html", this, state)!$
|
||||
$!nav("mitmdump.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Features</li>
|
||||
$!nav("anticache.html", this, state)!$
|
||||
$!nav("clientreplay.html", this, state)!$
|
||||
$!nav("filters.html", this, state)!$
|
||||
$!nav("proxyauth.html", this, state)!$
|
||||
$!nav("replacements.html", this, state)!$
|
||||
$!nav("serverreplay.html", this, state)!$
|
||||
$!nav("setheaders.html", this, state)!$
|
||||
$!nav("sticky.html", this, state)!$
|
||||
$!nav("reverseproxy.html", this, state)!$
|
||||
$!nav("upstreamcerts.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Installing Certificates</li>
|
||||
$!nav("ssl.html", this, state)!$
|
||||
$!nav("certinstall/firefox.html", this, state)!$
|
||||
$!nav("certinstall/osx.html", this, state)!$
|
||||
$!nav("certinstall/windows7.html", this, state)!$
|
||||
$!nav("certinstall/ios.html", this, state)!$
|
||||
$!nav("certinstall/ios-simulator.html", this, state)!$
|
||||
$!nav("certinstall/android.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Transparent Proxying</li>
|
||||
$!nav("transparent.html", this, state)!$
|
||||
$!nav("transparent/linux.html", this, state)!$
|
||||
$!nav("transparent/osx.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Tutorials</li>
|
||||
$!nav("tutorials/30second.html", this, state)!$
|
||||
$!nav("tutorials/gamecenter.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Scripting mitmproxy</li>
|
||||
$!nav("scripting/inlinescripts.html", this, state)!$
|
||||
$!nav("scripting/libmproxy.html", this, state)!$
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="span9">
|
||||
<div class="page-header">
|
||||
<h1>@!this.title!@</h1>
|
||||
</div>
|
||||
$!body!$
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<footer>
|
||||
<p>@!copyright!@</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
771
doc-src/_transparent.graffle/data.plist
Normal file
@@ -0,0 +1,771 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>ActiveLayerIndex</key>
|
||||
<integer>0</integer>
|
||||
<key>ApplicationVersion</key>
|
||||
<array>
|
||||
<string>com.omnigroup.OmniGraffle.MacAppStore</string>
|
||||
<string>139.16</string>
|
||||
</array>
|
||||
<key>AutoAdjust</key>
|
||||
<true/>
|
||||
<key>BackgroundGraphic</key>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{0, 0}, {559.19998741149902, 782.79998779296875}}</string>
|
||||
<key>Class</key>
|
||||
<string>SolidGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>2</integer>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>BaseZoom</key>
|
||||
<integer>0</integer>
|
||||
<key>CanvasOrigin</key>
|
||||
<string>{0, 0}</string>
|
||||
<key>ColumnAlign</key>
|
||||
<integer>1</integer>
|
||||
<key>ColumnSpacing</key>
|
||||
<real>36</real>
|
||||
<key>CreationDate</key>
|
||||
<string>2013-01-02 19:31:53 +0000</string>
|
||||
<key>Creator</key>
|
||||
<string>Aldo Cortesi</string>
|
||||
<key>DisplayScale</key>
|
||||
<string>1.000 cm = 1.000 cm</string>
|
||||
<key>GraphDocumentVersion</key>
|
||||
<integer>8</integer>
|
||||
<key>GraphicsList</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{101.18773396809897, 358.41662979125977}, {62, 12}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>FitText</key>
|
||||
<string>YES</string>
|
||||
<key>Flow</key>
|
||||
<string>Resize</string>
|
||||
<key>FontInfo</key>
|
||||
<dict>
|
||||
<key>Font</key>
|
||||
<string>Helvetica</string>
|
||||
<key>Size</key>
|
||||
<real>12</real>
|
||||
</dict>
|
||||
<key>ID</key>
|
||||
<integer>4079</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Pad</key>
|
||||
<integer>0</integer>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs20 \cf0 2: Redirection}</string>
|
||||
<key>VerticalPad</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Wrap</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{102.18775939941409, 405.16666666666663}, {78, 12}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>FitText</key>
|
||||
<string>YES</string>
|
||||
<key>Flow</key>
|
||||
<string>Resize</string>
|
||||
<key>FontInfo</key>
|
||||
<dict>
|
||||
<key>Font</key>
|
||||
<string>Helvetica</string>
|
||||
<key>Size</key>
|
||||
<real>12</real>
|
||||
</dict>
|
||||
<key>ID</key>
|
||||
<integer>4078</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Pad</key>
|
||||
<integer>0</integer>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs20 \cf0 3: HTTP Request}</string>
|
||||
<key>VerticalPad</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Wrap</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Class</key>
|
||||
<string>LineGraphic</string>
|
||||
<key>ControlPoints</key>
|
||||
<array>
|
||||
<string>{-29.333333333333343, 15.666671991348267}</string>
|
||||
<string>{-14, -7.3333333333333712}</string>
|
||||
</array>
|
||||
<key>ID</key>
|
||||
<integer>37</integer>
|
||||
<key>Points</key>
|
||||
<array>
|
||||
<string>{196.99999491373691, 331.83332316080725}</string>
|
||||
<string>{198.00000508626303, 402.49998982747394}</string>
|
||||
</array>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Bezier</key>
|
||||
<true/>
|
||||
<key>HeadArrow</key>
|
||||
<string>FilledArrow</string>
|
||||
<key>Legacy</key>
|
||||
<true/>
|
||||
<key>LineType</key>
|
||||
<integer>1</integer>
|
||||
<key>TailArrow</key>
|
||||
<string>0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{205.34387397766082, 289.3333333333328}, {84, 52.666667938232422}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>4076</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Color</key>
|
||||
<dict>
|
||||
<key>b</key>
|
||||
<string>0.547829</string>
|
||||
<key>g</key>
|
||||
<string>1</string>
|
||||
<key>r</key>
|
||||
<string>0.790866</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;\red37\green17\blue0;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs24 \cf2 router}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Class</key>
|
||||
<string>LineGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>4075</integer>
|
||||
<key>Points</key>
|
||||
<array>
|
||||
<string>{304.061024983724, 422.16667167345679}</string>
|
||||
<string>{348.49764506022132, 422.16667167345696}</string>
|
||||
<string>{365.83097839355469, 421.50000500679027}</string>
|
||||
<string>{417.16433715820312, 421.16667175292963}</string>
|
||||
</array>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>HeadArrow</key>
|
||||
<string>FilledArrow</string>
|
||||
<key>Legacy</key>
|
||||
<true/>
|
||||
<key>TailArrow</key>
|
||||
<string>0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{321.11267089843761, 405.16706339518225}, {49, 12}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>FitText</key>
|
||||
<string>YES</string>
|
||||
<key>Flow</key>
|
||||
<string>Resize</string>
|
||||
<key>FontInfo</key>
|
||||
<dict>
|
||||
<key>Font</key>
|
||||
<string>Helvetica</string>
|
||||
<key>Size</key>
|
||||
<real>12</real>
|
||||
</dict>
|
||||
<key>ID</key>
|
||||
<integer>4067</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Pad</key>
|
||||
<integer>0</integer>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs20 \cf0 4: Request}</string>
|
||||
<key>VerticalPad</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Wrap</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{101.18773682912195, 295.66660690307623}, {62, 12}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>FitText</key>
|
||||
<string>YES</string>
|
||||
<key>Flow</key>
|
||||
<string>Resize</string>
|
||||
<key>FontInfo</key>
|
||||
<dict>
|
||||
<key>Font</key>
|
||||
<string>Helvetica</string>
|
||||
<key>Size</key>
|
||||
<real>12</real>
|
||||
</dict>
|
||||
<key>ID</key>
|
||||
<integer>4058</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Pad</key>
|
||||
<integer>0</integer>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs20 \cf0 1: Connection}</string>
|
||||
<key>VerticalPad</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Wrap</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Class</key>
|
||||
<string>LineGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>4041</integer>
|
||||
<key>Points</key>
|
||||
<array>
|
||||
<string>{85.896713256836037, 421.41666793823208}</string>
|
||||
<string>{199.00002034505209, 421.16666666666669}</string>
|
||||
</array>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>HeadArrow</key>
|
||||
<string>FilledArrow</string>
|
||||
<key>Legacy</key>
|
||||
<true/>
|
||||
<key>TailArrow</key>
|
||||
<string>0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Class</key>
|
||||
<string>LineGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>31</integer>
|
||||
<key>Points</key>
|
||||
<array>
|
||||
<string>{84.896687825520857, 314.66666126251221}</string>
|
||||
<string>{129.33330790201822, 314.66666126251238}</string>
|
||||
<string>{146.66664123535153, 313.99999459584569}</string>
|
||||
<string>{198, 313.66666134198505}</string>
|
||||
</array>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>HeadArrow</key>
|
||||
<string>FilledArrow</string>
|
||||
<key>Legacy</key>
|
||||
<true/>
|
||||
<key>TailArrow</key>
|
||||
<string>0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{430.83098347981803, 515.99999999999989}, {36, 14}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>FitText</key>
|
||||
<string>YES</string>
|
||||
<key>Flow</key>
|
||||
<string>Resize</string>
|
||||
<key>ID</key>
|
||||
<integer>4026</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Pad</key>
|
||||
<integer>0</integer>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs24 \cf0 Server}</string>
|
||||
<key>VerticalPad</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Wrap</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{40.499999999999993, 486.66666666666663}, {31, 14}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>FitText</key>
|
||||
<string>YES</string>
|
||||
<key>Flow</key>
|
||||
<string>Resize</string>
|
||||
<key>ID</key>
|
||||
<integer>4025</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Pad</key>
|
||||
<integer>0</integer>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs24 \cf0 Client}</string>
|
||||
<key>VerticalPad</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>Wrap</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{417.16432189941418, 323.90565299479198}, {63.333332061767578, 185.52200317382812}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>4004</integer>
|
||||
<key>ImageID</key>
|
||||
<integer>6</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{205.34386889139773, 289.33333333333331}, {84, 248.66667175292969}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>4023</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Color</key>
|
||||
<dict>
|
||||
<key>b</key>
|
||||
<string>0</string>
|
||||
<key>g</key>
|
||||
<string>0.463735</string>
|
||||
<key>r</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Text</key>
|
||||
<dict>
|
||||
<key>Text</key>
|
||||
<string>{\rtf1\ansi\ansicpg1252\cocoartf1187\cocoasubrtf340
|
||||
\cocoascreenfonts1{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
|
||||
{\colortbl;\red255\green255\blue255;\red37\green17\blue0;}
|
||||
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
|
||||
|
||||
\f0\fs24 \cf2 mitmproxy}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Bounds</key>
|
||||
<string>{{4.6666666467984399, 351.33332316080771}, {102.66666412353516, 130.66667175292969}}</string>
|
||||
<key>Class</key>
|
||||
<string>ShapedGraphic</string>
|
||||
<key>ID</key>
|
||||
<integer>134</integer>
|
||||
<key>ImageID</key>
|
||||
<integer>3</integer>
|
||||
<key>Shape</key>
|
||||
<string>Rectangle</string>
|
||||
<key>Style</key>
|
||||
<dict>
|
||||
<key>fill</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>shadow</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
<key>stroke</key>
|
||||
<dict>
|
||||
<key>Draws</key>
|
||||
<string>NO</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>GridInfo</key>
|
||||
<dict/>
|
||||
<key>GuidesLocked</key>
|
||||
<string>NO</string>
|
||||
<key>GuidesVisible</key>
|
||||
<string>YES</string>
|
||||
<key>HPages</key>
|
||||
<integer>1</integer>
|
||||
<key>ImageCounter</key>
|
||||
<integer>7</integer>
|
||||
<key>ImageLinkBack</key>
|
||||
<array>
|
||||
<dict/>
|
||||
<dict/>
|
||||
</array>
|
||||
<key>ImageList</key>
|
||||
<array>
|
||||
<string>image6.tiff</string>
|
||||
<string>image3.icns</string>
|
||||
</array>
|
||||
<key>KeepToScale</key>
|
||||
<false/>
|
||||
<key>Layers</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>Lock</key>
|
||||
<string>NO</string>
|
||||
<key>Name</key>
|
||||
<string>Layer 1</string>
|
||||
<key>Print</key>
|
||||
<string>YES</string>
|
||||
<key>View</key>
|
||||
<string>YES</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>LayoutInfo</key>
|
||||
<dict>
|
||||
<key>Animate</key>
|
||||
<string>NO</string>
|
||||
<key>circoMinDist</key>
|
||||
<real>18</real>
|
||||
<key>circoSeparation</key>
|
||||
<real>0.0</real>
|
||||
<key>layoutEngine</key>
|
||||
<string>dot</string>
|
||||
<key>neatoSeparation</key>
|
||||
<real>0.0</real>
|
||||
<key>twopiSeparation</key>
|
||||
<real>0.0</real>
|
||||
</dict>
|
||||
<key>LinksVisible</key>
|
||||
<string>NO</string>
|
||||
<key>MagnetsVisible</key>
|
||||
<string>NO</string>
|
||||
<key>MasterSheets</key>
|
||||
<array/>
|
||||
<key>ModificationDate</key>
|
||||
<string>2013-01-03 04:13:10 +0000</string>
|
||||
<key>Modifier</key>
|
||||
<string>Aldo Cortesi</string>
|
||||
<key>NotesVisible</key>
|
||||
<string>NO</string>
|
||||
<key>Orientation</key>
|
||||
<integer>2</integer>
|
||||
<key>OriginVisible</key>
|
||||
<string>NO</string>
|
||||
<key>PageBreaks</key>
|
||||
<string>YES</string>
|
||||
<key>PrintInfo</key>
|
||||
<dict>
|
||||
<key>NSBottomMargin</key>
|
||||
<array>
|
||||
<string>float</string>
|
||||
<string>41</string>
|
||||
</array>
|
||||
<key>NSHorizonalPagination</key>
|
||||
<array>
|
||||
<string>coded</string>
|
||||
<string>BAtzdHJlYW10eXBlZIHoA4QBQISEhAhOU051bWJlcgCEhAdOU1ZhbHVlAISECE5TT2JqZWN0AIWEASqEhAFxlwCG</string>
|
||||
</array>
|
||||
<key>NSLeftMargin</key>
|
||||
<array>
|
||||
<string>float</string>
|
||||
<string>18</string>
|
||||
</array>
|
||||
<key>NSPaperSize</key>
|
||||
<array>
|
||||
<string>size</string>
|
||||
<string>{595.19998741149902, 841.79998779296875}</string>
|
||||
</array>
|
||||
<key>NSPrintReverseOrientation</key>
|
||||
<array>
|
||||
<string>int</string>
|
||||
<string>0</string>
|
||||
</array>
|
||||
<key>NSRightMargin</key>
|
||||
<array>
|
||||
<string>float</string>
|
||||
<string>18</string>
|
||||
</array>
|
||||
<key>NSTopMargin</key>
|
||||
<array>
|
||||
<string>float</string>
|
||||
<string>18</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>PrintOnePage</key>
|
||||
<false/>
|
||||
<key>ReadOnly</key>
|
||||
<string>NO</string>
|
||||
<key>RowAlign</key>
|
||||
<integer>1</integer>
|
||||
<key>RowSpacing</key>
|
||||
<real>36</real>
|
||||
<key>SheetTitle</key>
|
||||
<string>Canvas 1</string>
|
||||
<key>SmartAlignmentGuidesActive</key>
|
||||
<string>YES</string>
|
||||
<key>SmartDistanceGuidesActive</key>
|
||||
<string>YES</string>
|
||||
<key>UniqueID</key>
|
||||
<integer>1</integer>
|
||||
<key>UseEntirePage</key>
|
||||
<false/>
|
||||
<key>VPages</key>
|
||||
<integer>1</integer>
|
||||
<key>WindowInfo</key>
|
||||
<dict>
|
||||
<key>CurrentSheet</key>
|
||||
<integer>0</integer>
|
||||
<key>ExpandedCanvases</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Canvas 1</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Frame</key>
|
||||
<string>{{295, 141}, {974, 874}}</string>
|
||||
<key>ListView</key>
|
||||
<true/>
|
||||
<key>OutlineWidth</key>
|
||||
<integer>142</integer>
|
||||
<key>RightSidebar</key>
|
||||
<false/>
|
||||
<key>ShowRuler</key>
|
||||
<true/>
|
||||
<key>Sidebar</key>
|
||||
<true/>
|
||||
<key>SidebarWidth</key>
|
||||
<integer>120</integer>
|
||||
<key>VisibleRegion</key>
|
||||
<string>{{0, 208}, {550, 469.33333333333337}}</string>
|
||||
<key>Zoom</key>
|
||||
<real>1.5</real>
|
||||
<key>ZoomValues</key>
|
||||
<array>
|
||||
<array>
|
||||
<string>Canvas 1</string>
|
||||
<real>1.5</real>
|
||||
<real>1</real>
|
||||
</array>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
doc-src/_transparent.graffle/image3.icns
Normal file
BIN
doc-src/_transparent.graffle/image6.tiff
Normal file
1096
doc-src/_transparent_https.graffle/data.plist
Normal file
BIN
doc-src/_transparent_https.graffle/image3.icns
Normal file
BIN
doc-src/_transparent_https.graffle/image6.tiff
Normal file
@@ -1,42 +1,83 @@
|
||||
<a href="http://github.com/cortesi/mitmproxy"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://d3nwyuy0nl342s.cloudfront.net/img/e6bef7a091f5f3138b8cd40bc3e114258dd68ddf/687474703a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f7265645f6161303030302e706e67" alt="Fork me on GitHub"></a>
|
||||
<div class="yui-t7" id="doc">
|
||||
<div style="" id="hd">
|
||||
<h1><a href="@!urlTo("/index.html")!@">mitmproxy</a> </h1>
|
||||
<div class="HorizontalNavBar">
|
||||
<ul>
|
||||
<li class="inactive"><a href="@!urlTo("/index.html")!@">home</a></li>
|
||||
<li class="active"><a href="@!urlTo("doc/index.html")!@">docs</a></li>
|
||||
<li class="inactive"><a href="@!urlTo("/about.html")!@">about</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<br>
|
||||
<p>an SSL-capable intercepting proxy</p>
|
||||
</div>
|
||||
<div id="bd">
|
||||
<div id="yui-main">
|
||||
<div style="" class="yui-b">
|
||||
<!--(block nav)-->
|
||||
<div id="nav">
|
||||
<!--(block pb)-->
|
||||
<a href="@!urlTo(previous)!@">prev</a>
|
||||
<!--(end)-->
|
||||
<!--(block nb)-->
|
||||
<a href="@!urlTo(next)!@">next</a>
|
||||
<!--(end)-->
|
||||
$!pb if previous and not previous.parent.root else "prev"!$ |
|
||||
<a href="@!urlTo('doc/index.html')!@">index</a> |
|
||||
$!nb if next and not next.parent.root else "next"!$
|
||||
</div>
|
||||
<!--(end)-->
|
||||
$!nav if this.title!="docs" else ""!$
|
||||
$!title if this.title!="docs" else "<h1>mitmproxy docs</h1>"!$
|
||||
$!body!$
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="" id="ft">
|
||||
<p>Copyright 2011 Aldo Cortesi</p>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</a>
|
||||
<a class="brand" href="@!urlTo("/index.html")!@">mitmproxy</a>
|
||||
<div class="nav">
|
||||
<ul class="nav">
|
||||
<li $!'class="active"' if this.match("/index.html", True) else ""!$> <a href="@!top!@/index.html">home</a> </li>
|
||||
<li $!'class="active"' if this.under("/doc") else ""!$><a href="@!top!@/doc/index.html">docs</a></li>
|
||||
<li $!'class="active"' if this.under("/about.html") else ""!$><a href="@!top!@/about.html">about</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
$!ga!$
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
|
||||
<div class="span3">
|
||||
<div class="well sidebar-nav">
|
||||
<ul class="nav nav-list">
|
||||
$!nav(idxpath, this, state)!$
|
||||
$!nav("install.html", this, state)!$
|
||||
$!nav("howmitmproxy.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Tools</li>
|
||||
$!nav("mitmproxy.html", this, state)!$
|
||||
$!nav("mitmdump.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Features</li>
|
||||
$!nav("anticache.html", this, state)!$
|
||||
$!nav("clientreplay.html", this, state)!$
|
||||
$!nav("filters.html", this, state)!$
|
||||
$!nav("proxyauth.html", this, state)!$
|
||||
$!nav("replacements.html", this, state)!$
|
||||
$!nav("serverreplay.html", this, state)!$
|
||||
$!nav("setheaders.html", this, state)!$
|
||||
$!nav("sticky.html", this, state)!$
|
||||
$!nav("reverseproxy.html", this, state)!$
|
||||
$!nav("upstreamcerts.html", this, state)!$
|
||||
|
||||
<li class="nav-header">SSL interception</li>
|
||||
$!nav("ssl.html", this, state)!$
|
||||
$!nav("certinstall/firefox.html", this, state)!$
|
||||
$!nav("certinstall/osx.html", this, state)!$
|
||||
$!nav("certinstall/windows7.html", this, state)!$
|
||||
$!nav("certinstall/ios.html", this, state)!$
|
||||
$!nav("certinstall/android.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Transparent Proxying</li>
|
||||
$!nav("transparent.html", this, state)!$
|
||||
$!nav("transparent/linux.html", this, state)!$
|
||||
$!nav("transparent/osx.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Tutorials</li>
|
||||
$!nav("tutorials/30second.html", this, state)!$
|
||||
$!nav("tutorials/gamecenter.html", this, state)!$
|
||||
|
||||
<li class="nav-header">Scripting mitmproxy</li>
|
||||
$!nav("scripting/inlinescripts.html", this, state)!$
|
||||
$!nav("scripting/libmproxy.html", this, state)!$
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span9">
|
||||
<div class="page-header">
|
||||
<h1>@!this.title!@</h1>
|
||||
</div>
|
||||
$!body!$
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<footer>
|
||||
<p>@!copyright!@</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
Please send any comments, suggestions and bug reports to <a href="mailto:$!docMaintainerEmail!$">$!docMaintainerEmail!$</a>.
|
||||
|
||||
__mitmproxy__ is licensed under Version 3 of the Gnu General Public License,
|
||||
the full text of which can be found in the LICENSE file in the source
|
||||
distribution.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
When the __anticache__ option is passed to mitmproxy, it removes headers
|
||||
(__if-none-match__ and __if-modified-since__) that might elicit a
|
||||
304-not-modified response from the server. This is useful when you want to make
|
||||
sure you capture an HTTP exchange in its totality, and during [client
|
||||
replay](@!urlTo("clientreplay.html")!@).
|
||||
|
||||
BIN
doc-src/certinstall/android-settingssecurityinstallca.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
doc-src/certinstall/android-settingssecuritymenu.png
Normal file
|
After Width: | Height: | Size: 74 KiB |
BIN
doc-src/certinstall/android-settingssecurityuserinstalledca.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
doc-src/certinstall/android-shellwgetmitmproxyca.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
46
doc-src/certinstall/android.html
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
The proxy situation on Android is [an
|
||||
embarrasment](http://code.google.com/p/android/issues/detail?id=1273). It's
|
||||
scarcely credible, but Android didn't have a global proxy setting at all until
|
||||
quite recently, and it's still not supported on many common Android versions.
|
||||
In the meantime the app ecosystem has grown used to life without this basic
|
||||
necessity, and many apps merrily ignore it even if it's there. This situation
|
||||
is improving, but in many circumstances using [transparent
|
||||
mode](@!urlTo("transparent.html")!@) is mandatory for testing Android apps.
|
||||
|
||||
We used an Asus Transformer Prime TF201 with Android 4.0.3 in the examples
|
||||
below - your device may differ, but the broad process should be similar.
|
||||
|
||||
|
||||
## Getting the certificate onto the device
|
||||
|
||||
First we need to get the __mitmproxy-ca-cert.cer__ file into the
|
||||
__/sdcard/Downloads__ folder on the device. There are a number of ways to do
|
||||
this. If you have the Android Developer Tools installed, you can use [__adb
|
||||
push__](http://developer.android.com/tools/help/adb.html) to accomplish this.
|
||||
Depending on your device, you could also transfer the file using external media
|
||||
like an SD Card. In this example, we're using wget from within a terminal
|
||||
emulator to transfer the certificate from a local HTTP server:
|
||||
|
||||
<img src="android-shellwgetmitmproxyca.png"/>
|
||||
|
||||
|
||||
## Installing the certificate
|
||||
|
||||
Once we have the certificate on the local disk, we need to import it into the
|
||||
list of trusted CAs. Go to Settings -> Security -> Credential Storage,
|
||||
and select "Install from storage":
|
||||
|
||||
<img src="android-settingssecuritymenu.png"/>
|
||||
|
||||
The certificate in /sdcard/Downloads is automatically located and offered for
|
||||
installation. Installing the cert will delete the download file from the local
|
||||
disk:
|
||||
|
||||
<img src="android-settingssecurityinstallca.png"/>
|
||||
|
||||
Afterwards, you should see the certificate listed in the Trusted Credentials
|
||||
store:
|
||||
|
||||
<img src="android-settingssecurityuserinstalledca.png"/>
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
|
||||
How to install the __mitmproxy__ certificate authority in Firefox:
|
||||
|
||||
### 1. If needed, copy the ~/.mitmproxy/mitmproxy-ca-cert.pem file to the target.
|
||||
<ol class="tlist">
|
||||
<li> If needed, copy the ~/.mitmproxy/mitmproxy-ca-cert.pem file to the target. </li>
|
||||
|
||||
### 2: Open preferences, click on "Advanced", then select"Encryption":
|
||||
<li>Open preferences, click on "Advanced", then select"Encryption":
|
||||
<img src="@!urlTo('firefox3.jpg')!@"/>
|
||||
</li>
|
||||
|
||||
<img src="@!urlTo('firefox3.jpg')!@"/>
|
||||
<li> Click "View Certificates", "Import", and select the certificate file:
|
||||
<img src="@!urlTo('firefox3-import.jpg')!@"/>
|
||||
</li>
|
||||
|
||||
### 3: Click "View Certificates", "Import", and select the certificate file:
|
||||
<li>Tick "Trust this CS to identify web sites", and click "Ok":
|
||||
<img src="@!urlTo('firefox3-trust.jpg')!@"/>
|
||||
</li>
|
||||
|
||||
<img src="@!urlTo('firefox3-import.jpg')!@"/>
|
||||
<li> You should now see the mitmproxy certificate listed in the Authorities
|
||||
tab.</li>
|
||||
|
||||
### 4: Tick "Trust this CS to identify web sites", and click "Ok":
|
||||
|
||||
<img src="@!urlTo('firefox3-trust.jpg')!@"/>
|
||||
|
||||
You should now see the mitmproxy certificate listed in the Authorities tab.
|
||||
</ol>
|
||||
|
||||
|
||||
@@ -5,4 +5,6 @@ pages = [
|
||||
Page("osx.html", "OSX"),
|
||||
Page("windows7.html", "Windows 7"),
|
||||
Page("ios.html", "IOS"),
|
||||
Page("ios-simulator.html", "IOS Simulator"),
|
||||
Page("android.html", "Android"),
|
||||
]
|
||||
|
||||
23
doc-src/certinstall/ios-simulator.html
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
How to install the __mitmproxy__ certificate authority in the IOS simulator:
|
||||
|
||||
<ol class="tlist">
|
||||
|
||||
<li> First, check out the <a
|
||||
href="https://github.com/ADVTOOLS/ADVTrustStore">ADVTrustStore</a> tool
|
||||
from github.</li>
|
||||
|
||||
<li> Now, run the following command:
|
||||
|
||||
<pre class="terminal">./iosCertTrustManager.py -a ~/.mitmproxy/mitmproxy-ca-cert.pem</pre>
|
||||
|
||||
</li>
|
||||
|
||||
</ol>
|
||||
|
||||
|
||||
Note that although the IOS simulator has its own certificate store, it shares
|
||||
the proxy settings of the host operating system. You will therefore to have
|
||||
configure your OSX host's proxy settings to use the mitmproxy instance you want
|
||||
to test with.
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
|
||||
How to install the __mitmproxy__ certificate authority on IOS devices:
|
||||
|
||||
### 1: Set up the Mail app on the device to receive email.
|
||||
<ol class="tlist">
|
||||
<li>Set up the Mail app on the device to receive email.</li>
|
||||
|
||||
### 2: Mail the mitmproxy-ca-cert.pem file to the device, and tap on the attachment.
|
||||
<li>Mail the mitmproxy-ca-cert.pem file to the device, and tap on the attachment.</li>
|
||||
|
||||
### 3: You will be prompted to install a profile. Click "Install":
|
||||
<li>You will be prompted to install a profile. Click "Install":
|
||||
|
||||
<img src="@!urlTo('ios-profile.png')!@"/>
|
||||
<img src="@!urlTo('ios-profile.png')!@"/></li>
|
||||
|
||||
### 4: Accept the warning by clicking "Install" again:
|
||||
<li>Accept the warning by clicking "Install" again:
|
||||
|
||||
<img src="@!urlTo('ios-warning.png')!@"/>
|
||||
<img src="@!urlTo('ios-warning.png')!@"/></li>
|
||||
|
||||
### 5: The certificate should now be trusted:
|
||||
<li>The certificate should now be trusted:
|
||||
|
||||
<img src="@!urlTo('ios-installed.png')!@"/>
|
||||
<img src="@!urlTo('ios-installed.png')!@"/></li>
|
||||
|
||||
</ol>
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
|
||||
How to install the __mitmproxy__ certificate authority in OSX:
|
||||
|
||||
### 1: Open Finder, and double-click on the mitmproxy-ca-cert.pem file.
|
||||
<ol class="tlist">
|
||||
|
||||
<li>Open Finder, and double-click on the mitmproxy-ca-cert.pem file.</li>
|
||||
|
||||
### 2: You will be prompted to add the certificate. Click "Always Trust":
|
||||
<li>You will be prompted to add the certificate. Click "Always Trust":
|
||||
|
||||
<img src="@!urlTo('osx-addcert-alwaystrust.png')!@"/>
|
||||
<img src="@!urlTo('osx-addcert-alwaystrust.png')!@"/>
|
||||
</li>
|
||||
|
||||
You may be prompted for your password. You should now see the mitmproxy cert
|
||||
listed under "Certificates".
|
||||
<li> You may be prompted for your password. You should now see the
|
||||
mitmproxy cert listed under "Certificates".</li>
|
||||
</ol>
|
||||
|
||||
|
||||
@@ -1,19 +1,32 @@
|
||||
|
||||
How to install the __mitmproxy__ certificate authority in Windows 7:
|
||||
|
||||
### 1: Copy the ~/.mitmproxy/mitmproxy-ca-cert.p12 file to the target system.
|
||||
<ol class="tlist">
|
||||
|
||||
### 2: Double-click the certificate file. You should see a certificate import wizard:
|
||||
<li> Copy the ~/.mitmproxy/mitmproxy-ca-cert.p12 file to the target system. </li>
|
||||
|
||||
<img src="@!urlTo('win7-wizard.png')!@"/>
|
||||
<li>
|
||||
Double-click the certificate file. You should see a certificate import wizard:
|
||||
|
||||
### 3: Click "Next" until you're prompted for the certificate store:
|
||||
<img src="@!urlTo('win7-wizard.png')!@"/>
|
||||
</li>
|
||||
|
||||
<img src="@!urlTo('win7-certstore.png')!@"/>
|
||||
<li>
|
||||
Click "Next" until you're prompted for the certificate store:
|
||||
|
||||
### 4: Select "Place all certificates in the following store", and select "Trusted Root Certification Authorities":
|
||||
<img src="@!urlTo('win7-certstore.png')!@"/>
|
||||
|
||||
<img src="@!urlTo('win7-certstore-trustedroot.png')!@"/>
|
||||
</li>
|
||||
|
||||
### 5: Click "Next" and "Finish".
|
||||
|
||||
<li>
|
||||
<p>Select "Place all certificates in the following store", and select "Trusted Root Certification Authorities":</p>
|
||||
|
||||
<img src="@!urlTo('win7-certstore-trustedroot.png')!@"/>
|
||||
|
||||
</li>
|
||||
|
||||
<li> Click "Next" and "Finish". </li>
|
||||
|
||||
</ol>
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
Client-side replay does what it says on the tin: you provide a previously saved
|
||||
HTTP conversation, and mitmproxy replays the client requests one by one. Note
|
||||
that mitmproxy serializes the requests, waiting for a response from the server
|
||||
before starting the next request. This might differ from the recorded
|
||||
conversation, where requests may have been made concurrently.
|
||||
|
||||
You may want to use client-side replay in conjunction with the __anticache__
|
||||
option. This will modify requests to remove headers (e.g. if-modified-since)
|
||||
that might cause a server to reply with a 304-not-modified.
|
||||
|
||||
BIN
doc-src/explicit.png
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
doc-src/explicit_https.png
Normal file
|
After Width: | Height: | Size: 77 KiB |
@@ -1,19 +0,0 @@
|
||||
|
||||
### Any tips for running mitmproxy on OSX?
|
||||
|
||||
You can use the OSX <b>open</b> program to create a simple and effective
|
||||
<b>~/.mailcap</b> file to view HTTP bodies:
|
||||
|
||||
<pre>
|
||||
application/*; /usr/bin/open -Wn %s
|
||||
audio/*; /usr/bin/open -Wn %s
|
||||
image/*; /usr/bin/open -Wn %s
|
||||
video/*; /usr/bin/open -Wn %s
|
||||
</pre>
|
||||
|
||||
|
||||
### I'd like to hack on mitmproxy. What should I work on?
|
||||
|
||||
There's a __todo__ file at the top of the source tree that outlines a variety
|
||||
of tasks, from simple to complex. If you don't have your own itch, feel free to
|
||||
scratch one of those!
|
||||
18
doc-src/features/anticache.html
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
When the __anticache__ option is passed to mitmproxy, it removes headers
|
||||
(__if-none-match__ and __if-modified-since__) that might elicit a
|
||||
304-not-modified response from the server. This is useful when you want to make
|
||||
sure you capture an HTTP exchange in its totality. It's also often used during
|
||||
[client replay](@!urlTo("clientreplay.html")!@), when you want to make sure the
|
||||
server responds with complete data.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th> <td>--anticache</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>o</b> then <b>a</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
22
doc-src/features/clientreplay.html
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
Client-side replay does what it says on the tin: you provide a previously saved
|
||||
HTTP conversation, and mitmproxy replays the client requests one by one. Note
|
||||
that mitmproxy serializes the requests, waiting for a response from the server
|
||||
before starting the next request. This might differ from the recorded
|
||||
conversation, where requests may have been made concurrently.
|
||||
|
||||
You may want to use client-side replay in conjunction with the
|
||||
[anticache](@!urlTo("anticache.html")!@) option, to make sure the server
|
||||
responds with complete data.
|
||||
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th> <td>-c path</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>c</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -2,13 +2,15 @@
|
||||
Many commands in __mitmproxy__ and __mitmdump__ take a filter expression.
|
||||
Filter expressions consist of the following operators:
|
||||
|
||||
<table>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<!--(for i in filt_help)-->
|
||||
<tr>
|
||||
<td class="filt_cmd">@!i[0]!@</td>
|
||||
<td class="filt_help">@!i[1]!@</td>
|
||||
</tr>
|
||||
<!--(end)-->
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
- Regexes are Python-style
|
||||
@@ -26,9 +28,9 @@ URL containing "google.com":
|
||||
|
||||
Requests whose body contains the string "test":
|
||||
|
||||
~r ~b test
|
||||
~q ~b test
|
||||
|
||||
Anything but requests with a text/html content type:
|
||||
|
||||
!(~r & ~t \"text/html\")
|
||||
!(~q & ~t \"text/html\")
|
||||
|
||||
14
doc-src/features/index.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from countershape import Page
|
||||
|
||||
pages = [
|
||||
Page("anticache.html", "Anticache"),
|
||||
Page("clientreplay.html", "Client-side replay"),
|
||||
Page("filters.html", "Filter expressions"),
|
||||
Page("setheaders.html", "Set Headers"),
|
||||
Page("serverreplay.html", "Server-side replay"),
|
||||
Page("sticky.html", "Sticky cookies and auth"),
|
||||
Page("proxyauth.html", "Proxy Authentication"),
|
||||
Page("replacements.html", "Replacements"),
|
||||
Page("reverseproxy.html", "Reverse proxy mode"),
|
||||
Page("upstreamcerts.html", "Upstream Certs"),
|
||||
]
|
||||
26
doc-src/features/proxyauth.html
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
Asks the user for authentication before they are permitted to use the proxy.
|
||||
Authentication headers are stripped from the flows, so they are not passed to
|
||||
upstream servers. For now, only HTTP Basic authentication is supported. The
|
||||
proxy auth options are ignored if the proxy is in transparent or reverse proxy
|
||||
mode.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th>
|
||||
<td>
|
||||
<ul>
|
||||
<li>--nonanonymous</li>
|
||||
|
||||
<li>--singleuser USER</li>
|
||||
|
||||
<li>--htpasswd PATH</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
74
doc-src/features/replacements.html
Normal file
@@ -0,0 +1,74 @@
|
||||
Mitmproxy lets you specify an arbitrary number of patterns that define text
|
||||
replacements within flows. Each pattern has 3 components: a filter that defines
|
||||
which flows a replacement applies to, a regular expression that defines what
|
||||
gets replaced, and a target value that defines what is substituted in.
|
||||
|
||||
Replace hooks fire when either a client request or a server response is
|
||||
received. Only the matching flow component is affected: so, for example, if a
|
||||
replace hook is triggered on server response, the replacement is only run on
|
||||
the Response object leaving the Request intact. You control whether the hook
|
||||
triggers on the request, response or both using the filter pattern. If you need
|
||||
finer-grained control than this, it's simple to create a script using the
|
||||
replacement API on Flow components.
|
||||
|
||||
Replacement hooks are extremely handy in interactive testing of applications.
|
||||
For instance you can use a replace hook to replace the text "XSS" with a
|
||||
complicated XSS exploit, and then "inject" the exploit simply by interacting
|
||||
with the application through the browser. When used with tools like Firebug and
|
||||
mitmproxy's own interception abilities, replacement hooks can be an amazingly
|
||||
flexible and powerful feature.
|
||||
|
||||
|
||||
## On the command-line
|
||||
|
||||
The replacement hook command-line options use a compact syntax to make it easy
|
||||
to specify all three components at once. The general form is as follows:
|
||||
|
||||
/patt/regex/replacement
|
||||
|
||||
Here, __patt__ is a mitmproxy filter expression, __regex__ is a valid Python
|
||||
regular expression, and __replacement__ is a string literal. The first
|
||||
character in the expression (__/__ in this case) defines what the separation
|
||||
character is. Here's an example of a valid expression that replaces "foo" with
|
||||
"bar" in all requests:
|
||||
|
||||
:~q:foo:bar
|
||||
|
||||
In practice, it's pretty common for the replacement literal to be long and
|
||||
complex. For instance, it might be an XSS exploit that weighs in at hundreds or
|
||||
thousands of characters. To cope with this, there's a variation of the
|
||||
replacement hook specifier that lets you load the replacement text from a file.
|
||||
So, you might start __mitmdump__ as follows:
|
||||
|
||||
<pre class="terminal">
|
||||
mitmdump --replace-from-file :~q:foo:~/xss-exploit
|
||||
</pre>
|
||||
|
||||
This will load the replacement text from the file __~/xss-exploit__.
|
||||
|
||||
Both the _--replace_ and _--replace-from-file_ flags can be passed multiple
|
||||
times.
|
||||
|
||||
|
||||
## Interactively
|
||||
|
||||
The _R_ shortcut key in mitmproxy lets you add and edit replacement hooks using
|
||||
a built-in editor. The context-sensitive help (_h_) has complete usage
|
||||
information.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th>
|
||||
<td>
|
||||
<ul>
|
||||
<li>--replace</li>
|
||||
<li>--replace-from-file</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>R</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
17
doc-src/features/reverseproxy.html
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
In reverse proxy mode, mitmproxy acts as a standard HTTP server and forwards
|
||||
all requests to the specified upstream server. Note that the displayed URL for
|
||||
flows in this mode will use the value of the __Host__ header field from the
|
||||
request, not the reverse proxy server.
|
||||
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th> <td>-P http[s]://hostname[:port]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>P</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -1,4 +1,7 @@
|
||||
|
||||
- command-line: _-S path_
|
||||
- mitmproxy shortcut: _S_
|
||||
|
||||
Server-side replay lets us replay server responses from a saved HTTP
|
||||
conversation.
|
||||
|
||||
@@ -8,10 +11,9 @@ Matching requests with responses
|
||||
By default, __mitmproxy__ excludes request headers when matching incoming
|
||||
requests with responses from the replay file. This works in most circumstances,
|
||||
and makes it possible to replay server responses in situations where request
|
||||
headers would naturally vary, e.g. using a different user agent. The
|
||||
__--rheader__ option to both __mitmproxy__ and __mitmdump__ allows you to
|
||||
override this behaviour by specifying individual headers that should be
|
||||
included in matching.
|
||||
headers would naturally vary, e.g. using a different user agent. The _--rheader
|
||||
headername_ command-line option allows you to override this behaviour by
|
||||
specifying individual headers that should be included in matching.
|
||||
|
||||
|
||||
Response refreshing
|
||||
@@ -27,8 +29,7 @@ recording. So, if they were in the past at the time of recording, they will be
|
||||
in the past at the time of replay, and vice versa. Cookie expiry times are
|
||||
updated in a similar way.
|
||||
|
||||
You can turn off response refreshing using the __norefresh__ option, available
|
||||
both on the command-line and using the "options" keyboard shortcut within
|
||||
__mitmproxy__.
|
||||
You can turn off response refreshing using the _--norefresh_ argument, or using
|
||||
the _o_ options shortcut within __mitmproxy__.
|
||||
|
||||
|
||||
18
doc-src/features/setheaders.html
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
This feature lets you specify a set of headers to be added to requests or
|
||||
responses, based on a filter pattern. You can specify these either on the
|
||||
command-line, or through an interactive editor in mitmproxy.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th>
|
||||
<td>
|
||||
--setheader PATTERN
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>H</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
60
doc-src/features/sticky.html
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
## Sticky cookies
|
||||
|
||||
When the sticky cookie option is set, __mitmproxy__ will add the cookie most
|
||||
recently set by the server to any cookie-less request. Consider a service that
|
||||
sets a cookie to track the session after authentication. Using sticky cookies,
|
||||
you can fire up mitmproxy, and authenticate to a service as you usually would
|
||||
using a browser. After authentication, you can request authenticated resources
|
||||
through mitmproxy as if they were unauthenticated, because mitmproxy will
|
||||
automatically add the session tracking cookie to requests. Among other things,
|
||||
this lets you script interactions with authenticated resources (using tools
|
||||
like wget or curl) without having to worry about authentication.
|
||||
|
||||
Sticky cookies are especially powerful when used in conjunction with [client
|
||||
replay](@!urlTo("clientreplay.html")!@) - you can record the authentication
|
||||
process once, and simply replay it on startup every time you need to interact
|
||||
with the secured resources.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th>
|
||||
<td>
|
||||
<ul>
|
||||
<li>-t FILTER</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>t</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
## Sticky auth
|
||||
|
||||
The sticky auth option is analogous to the sticky cookie option, in that HTTP
|
||||
__Authorization__ headers are simply replayed to the server once they have been
|
||||
seen. This is enough to allow you to access a server resource using HTTP Basic
|
||||
authentication through the proxy. Note that __mitmproxy__ doesn't (yet) support
|
||||
replay of HTTP Digest authentication.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th>
|
||||
<td>
|
||||
<ul>
|
||||
<li>-u FILTER</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>mitmproxy shortcut</th> <td><b>u</b></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
21
doc-src/features/upstreamcerts.html
Normal file
@@ -0,0 +1,21 @@
|
||||
When mitmproxy receives a connection destined for an SSL-protected service, it
|
||||
freezes the connection before reading its request data, and makes a connection
|
||||
to the upstream server to "sniff" the contents of its SSL certificate. The
|
||||
information gained - the __Common Name__ and __Subject Alternative Names__ - is
|
||||
then used to generate the interception certificate, which is sent to the client
|
||||
so the connection can continue.
|
||||
|
||||
This rather intricate little dance lets us seamlessly generate correct
|
||||
certificates even if the client has specifed only an IP address rather than the
|
||||
hostname. It also means that we don't need to sniff additional data to generate
|
||||
certs in transparent mode.
|
||||
|
||||
Upstream cert sniffing is on by default, and can optionally be turned off.
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th width="20%">command-line</th> <td>--no-upstream-cert</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
360
doc-src/howmitmproxy.html
Normal file
@@ -0,0 +1,360 @@
|
||||
|
||||
|
||||
Mitmproxy is an enormously flexible tool. Knowing exactly how the proxying
|
||||
process works will help you deploy it creatively, and take into account its
|
||||
fundamental assumptions and how to work around them. This document explains
|
||||
mitmproxy's proxy mechanism in detail, starting with the simplest unencrypted
|
||||
explicit proxying, and working up to the most complicated interaction -
|
||||
transparent proxying of SSL-protected traffic[^ssl] in the presence of
|
||||
[SNI](http://en.wikipedia.org/wiki/Server_Name_Indication).
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Explicit HTTP</h1>
|
||||
</div>
|
||||
|
||||
Configuring the client to use mitmproxy as an explicit proxy is the simplest
|
||||
and most reliable way to intercept traffic. The proxy protocol is codified in
|
||||
the [HTTP RFC](http://www.ietf.org/rfc/rfc2068.txt), so the behaviour of both
|
||||
the client and the server is well defined, and usually reliable. In the
|
||||
simplest possible interaction with mitmproxy, a client connects directly to the
|
||||
proxy, and makes a request that looks like this:
|
||||
|
||||
<pre>GET http://example.com/index.html HTTP/1.1</pre>
|
||||
|
||||
This is a proxy GET request - an extended form of the vanilla HTTP GET request
|
||||
that includes a schema and host specification, and it includes all the
|
||||
information mitmproxy needs to proceed.
|
||||
|
||||
<img src="explicit.png"/>
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
|
||||
<td><b>1</b></td>
|
||||
|
||||
<td>The client connects to the proxy and makes a request.</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
|
||||
<td><b>2</b></td>
|
||||
|
||||
<td>Mitmproxy connects to the upstream server and simply forwards
|
||||
the request on.</td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Explicit HTTPS</h1>
|
||||
</div>
|
||||
|
||||
The process for an explicitly proxied HTTPS connection is quite different. The
|
||||
client connects to the proxy and makes a request that looks like this:
|
||||
|
||||
<pre>CONNECT example.com:443 HTTP/1.1</pre>
|
||||
|
||||
A conventional proxy can neither view nor manipulate an SSL-encrypted data
|
||||
stream, so a CONNECT request simply asks the proxy to open a pipe between the
|
||||
client and server. The proxy here is just a facilitator - it blindly forwards
|
||||
data in both directions without knowing anything about the contents. The
|
||||
negotiation of the SSL connection happens over this pipe, and the subsequent
|
||||
flow of requests and responses are completely opaque to the proxy.
|
||||
|
||||
## The MITM in mitmproxy
|
||||
|
||||
This is where mitmproxy's fundamental trick comes into play. The MITM in its
|
||||
name stands for Man-In-The-Middle - a reference to the process we use to
|
||||
intercept and interfere with these theoretically opaque data streams. The basic
|
||||
idea is to pretend to be the server to the client, and pretend to be the client
|
||||
to the server, while we sit in the middle decoding traffic from both sides. The
|
||||
tricky part is that the [Certificate
|
||||
Authority](http://en.wikipedia.org/wiki/Certificate_authority) system is
|
||||
designed to prevent exactly this attack, by allowing a trusted third-party to
|
||||
cryptographically sign a server's SSL certificates to verify that they are
|
||||
legit. If this signature doesn't match or is from a non-trusted party, a secure
|
||||
client will simply drop the connection and refuse to proceed. Despite the many
|
||||
shortcomings of the CA system as it exists today, this is usually fatal to
|
||||
attempts to MITM an SSL connection for analysis. Our answer to this conundrum
|
||||
is to become a trusted Certificate Authority ourselves. Mitmproxy includes a
|
||||
full CA implementation that generates interception certificates on the fly. To
|
||||
get the client to trust these certificates, we [register mitmproxy as a trusted
|
||||
CA with the device manually](@!urlTo("ssl.html")!@).
|
||||
|
||||
## Complication 1: What's the remote hostname?
|
||||
|
||||
To proceed with this plan, we need to know the domain name to use in the
|
||||
interception certificate - the client will verify that the certificate is for
|
||||
the domain it's connecting to, and abort if this is not the case. At first
|
||||
blush, it seems that the CONNECT request above gives us all we need - in this
|
||||
example, both of these values are "example.com". But what if the client had
|
||||
initiated the connection as follows:
|
||||
|
||||
<pre>CONNECT 10.1.1.1:443 HTTP/1.1</pre>
|
||||
|
||||
Using the IP address is perfectly legitimate because it gives us enough
|
||||
information to initiate the pipe, even though it doesn't reveal the remote
|
||||
hostname.
|
||||
|
||||
Mitmproxy has a cunning mechanism that smooths this over - [upstream
|
||||
certificate sniffing](@!urlTo("features/upstreamcerts.html")!@). As soon as we
|
||||
see the CONNECT request, we pause the client part of the conversation, and
|
||||
initiate a simultaneous connection to the server. We complete the SSL handshake
|
||||
with the server, and inspect the certificates it used. Now, we use the Common
|
||||
Name in the upstream SSL certificates to generate the dummy certificate for the
|
||||
client. Voila, we have the correct hostname to present to the client, even if
|
||||
it was never specified.
|
||||
|
||||
|
||||
## Complication 2: Subject Alternative Name
|
||||
|
||||
Enter the next complication. Sometimes, the certificate Common Name is not, in
|
||||
fact, the hostname that the client is connecting to. This is because of the
|
||||
optional [Subject Alternative
|
||||
Name](http://en.wikipedia.org/wiki/SubjectAltName) field in the SSL certificate
|
||||
that allows an arbitrary number of alternative domains to be specified. If the
|
||||
expected domain matches any of these, the client will proceed, even though the
|
||||
domain doesn't match the certificate Common Name. The answer here is simple:
|
||||
when extract the CN from the upstream cert, we also extract the SANs, and add
|
||||
them to the generated dummy certificate.
|
||||
|
||||
|
||||
## Complication 3: Server Name Indication
|
||||
|
||||
One of the big limitations of vanilla SSL is that each certificate requires its
|
||||
own IP address. This means that you couldn't do virtual hosting where multiple
|
||||
domains with independent certificates share the same IP address. In a world
|
||||
with a rapidly shrinking IPv4 address pool this is a problem, and we have a
|
||||
solution in the form of the [Server Name
|
||||
Indication](http://en.wikipedia.org/wiki/Server_Name_Indication) extension to
|
||||
the SSL and TLS protocols. This lets the client specify the remote server name
|
||||
at the start of the SSL handshake, which then lets the server select the right
|
||||
certificate to complete the process.
|
||||
|
||||
SNI breaks our upstream certificate sniffing process, because when we connect
|
||||
without using SNI, we get served a default certificate that may have nothing to
|
||||
do with the certificate expected by the client. The solution is another tricky
|
||||
complication to the client connection process. After the client connects, we
|
||||
allow the SSL handshake to continue until just _after_ the SNI value has been
|
||||
passed to us. Now we can pause the conversation, and initiate an upstream
|
||||
connection using the correct SNI value, which then serves us the correct
|
||||
upstream certificate, from which we can extract the expected CN and SANs.
|
||||
|
||||
There's another wrinkle here. Due to a limitation of the SSL library mitmproxy
|
||||
uses, we can't detect that a connection _hasn't_ sent an SNI request until it's
|
||||
too late for upstream certificate sniffing. In practice, we therefore make a
|
||||
vanilla SSL connection upstream to sniff non-SNI certificates, and then discard
|
||||
the connection if the client sends an SNI notification. If you're watching your
|
||||
traffic with a packet sniffer, you'll see two connections to the server when an
|
||||
SNI request is made, the first of which is immediately closed after the SSL
|
||||
handshake. Luckily, this is almost never an issue in practice.
|
||||
|
||||
## Putting it all together
|
||||
|
||||
Lets put all of this together into the complete explicitly proxied HTTPS flow.
|
||||
|
||||
<img src="explicit_https.png"/>
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b>1</b></td>
|
||||
<td>The client makes a connection to mitmproxy, and issues an HTTP
|
||||
CONNECT request.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>2</b></td>
|
||||
|
||||
<td>Mitmproxy responds with a 200 Connection Established, as if it
|
||||
has set up the CONNECT pipe.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>3</b></td>
|
||||
|
||||
<td>The client believes it's talking to the remote server, and
|
||||
initiates the SSL connection. It uses SNI to indicate the hostname
|
||||
it is connecting to.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><b>4</b></td>
|
||||
|
||||
<td>Mitmproxy connects to the server, and establishes an SSL
|
||||
connection using the SNI hostname indicated by the client.</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>5</b></td>
|
||||
|
||||
<td>The server responds with the matching SSL certificate, which
|
||||
contains the CN and SAN values needed to generate the interception
|
||||
certificate.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>6</b></td>
|
||||
|
||||
<td>Mitmproxy generates the interception cert, and continues the
|
||||
client SSL handshake paused in step 3.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>7</b></td>
|
||||
|
||||
<td>The client sends the request over the established SSL
|
||||
connection.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>7</b></td>
|
||||
|
||||
<td>Mitmproxy passes the request on to the server over the SSL
|
||||
connection initiated in step 4.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Transparent HTTP</h1>
|
||||
</div>
|
||||
|
||||
When a transparent proxy is used, the HTTP/S connection is redirected into a
|
||||
proxy at the network layer, without any client configuration being required.
|
||||
This makes transparent proxying ideal for those situations where you can't
|
||||
change client behaviour - proxy-oblivious Android applications being a common
|
||||
example.
|
||||
|
||||
To achieve this, we need to introduce two extra components. The first is a
|
||||
redirection mechanism that transparently reroutes a TCP connection destined for
|
||||
a server on the Internet to a listening proxy server. This usually takes the
|
||||
form of a firewall on the same host as the proxy server -
|
||||
[iptables](http://www.netfilter.org/) on Linux or
|
||||
[pf](http://en.wikipedia.org/wiki/PF_\(firewall\)) on OSX. Once the client has
|
||||
initiated the connection, it makes a vanilla HTTP request, which might look
|
||||
something like this:
|
||||
|
||||
<pre>GET /index.html HTTP/1.1</pre>
|
||||
|
||||
Note that this request differs from the explicit proxy variation, in that it
|
||||
omits the scheme and hostname. How, then, do we know which upstream host to
|
||||
forward the request to? The routing mechanism that has performed the
|
||||
redirection keeps track of the original destination for us. Each routing
|
||||
mechanism has a different way of exposing this data, so this introduces the
|
||||
second component required for working transparent proxying: a host module that
|
||||
knows how to retrieve the original destination address from the router. In
|
||||
mitmproxy, this takes the form of a built-in set of
|
||||
[modules](https://github.com/cortesi/mitmproxy/tree/master/libmproxy/platform)
|
||||
that know how to talk to each platform's redirection mechanism. Once we have
|
||||
this information, the process is fairly straight-forward.
|
||||
|
||||
<img src="transparent.png"/>
|
||||
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b>1</b></td>
|
||||
<td>The client makes a connection to the server.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>2</b></td>
|
||||
|
||||
<td>The router redirects the connection to mitmproxy, which is
|
||||
typically listening on a local port of the same host. Mitmproxy
|
||||
then consults the routing mechanism to establish what the original
|
||||
destination was.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>3</b></td>
|
||||
|
||||
<td>Now, we simply read the client's request...</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><b>4</b></td>
|
||||
|
||||
<td>... and forward it upstream.</td>
|
||||
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="page-header">
|
||||
<h1>Transparent HTTPS</h1>
|
||||
</div>
|
||||
|
||||
The first step is to determine whether we should treat an incoming connection
|
||||
as HTTPS. The mechanism for doing this is simple - we use the routing mechanism
|
||||
to find out what the original destination port is. By default, we treat all
|
||||
traffic destined for ports 443 and 8443 as SSL.
|
||||
|
||||
From here, the process is a merger of the methods we've described for
|
||||
transparently proxying HTTP, and explicitly proxying HTTPS. We use the routing
|
||||
mechanism to establish the upstream server address, and then proceed as for
|
||||
explicit HTTPS connections to establish the CN and SANs, and cope with SNI.
|
||||
|
||||
<img src="transparent_https.png"/>
|
||||
|
||||
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><b>1</b></td>
|
||||
<td>The client makes a connection to the server.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>2</b></td>
|
||||
|
||||
<td>The router redirects the connection to mitmproxy, which is
|
||||
typically listening on a local port of the same host. Mitmproxy
|
||||
then consults the routing mechanism to establish what the original
|
||||
destination was.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>3</b></td>
|
||||
|
||||
<td>The client believes it's talking to the remote server, and
|
||||
initiates the SSL connection. It uses SNI to indicate the hostname
|
||||
it is connecting to.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><b>4</b></td>
|
||||
|
||||
<td>Mitmproxy connects to the server, and establishes an SSL
|
||||
connection using the SNI hostname indicated by the client.</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>5</b></td>
|
||||
|
||||
<td>The server responds with the matching SSL certificate, which
|
||||
contains the CN and SAN values needed to generate the interception
|
||||
certificate.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>6</b></td>
|
||||
|
||||
<td>Mitmproxy generates the interception cert, and continues the
|
||||
client SSL handshake paused in step 3.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>7</b></td>
|
||||
|
||||
<td>The client sends the request over the established SSL
|
||||
connection.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>7</b></td>
|
||||
|
||||
<td>Mitmproxy passes the request on to the server over the SSL
|
||||
connection initiated in step 4.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
[^ssl]: I use "SSL" to refer to both SSL and TLS in the generic sense, unless otherwise specified.
|
||||
@@ -1,30 +1,4 @@
|
||||
|
||||
<ul class="docindex">
|
||||
<li><a href="@!urlTo("intro.html")!@">Introduction</a></li>
|
||||
<li><a href="@!urlTo("interception.html")!@">Interception</a></li>
|
||||
<li><a href="@!urlTo("clientreplay.html")!@">Client-side replay</a></li>
|
||||
<li><a href="@!urlTo("serverreplay.html")!@">Server-side replay</a></li>
|
||||
<li><a href="@!urlTo("sticky.html")!@">Sticky cookies and auth</a></li>
|
||||
<li><a href="@!urlTo("anticache.html")!@">Anticache</a></li>
|
||||
<li><a href="@!urlTo("filters.html")!@">Filter expressions</a></li>
|
||||
<li><a href="@!urlTo("scripts.html")!@">Scripting API</a></li>
|
||||
<li><a href="@!urlTo("ssl.html")!@">SSL</a></li>
|
||||
<ul>
|
||||
<li><a href="@!urlTo("certinstall/firefox.html")!@">Firefox</a></li>
|
||||
<li><a href="@!urlTo("certinstall/osx.html")!@">OSX</a></li>
|
||||
<li><a href="@!urlTo("certinstall/windows7.html")!@">Windows 7</a></li>
|
||||
<li><a href="@!urlTo("certinstall/ios.html")!@">iPhone/iPad</a></li>
|
||||
</ul>
|
||||
<li><a href="@!urlTo("library.html")!@">libmproxy</a></li>
|
||||
<li>Tutorials</li>
|
||||
<ul>
|
||||
<li> Client replay: a 30 second example [coming soon] </li>
|
||||
<li> Scripting: On-the-fly modifications to HTTP conversations [coming soon] </li>
|
||||
<li> Sticky cookies [coming soon] </li>
|
||||
<li> Breaking iPhone apps for fun and profit [coming soon] </li>
|
||||
</ul>
|
||||
<li><a href="@!urlTo("faq.html")!@">FAQ</a></li>
|
||||
<li><a href="@!urlTo("admin.html")!@">Administrivia</a></li>
|
||||
</ul>
|
||||
@!index_contents!@
|
||||
|
||||
|
||||
|
||||
@@ -1,43 +1,41 @@
|
||||
import os, sys
|
||||
import countershape
|
||||
from countershape import Page, Directory, PythonModule, markup
|
||||
import countershape.grok, countershape.template
|
||||
from countershape import Page, Directory, PythonModule, markup, model
|
||||
import countershape.template
|
||||
sys.path.insert(0, "..")
|
||||
from libmproxy import filt
|
||||
|
||||
MITMPROXY_SRC = "~/git/public/mitmproxy"
|
||||
|
||||
if ns.options.website:
|
||||
ns.title = countershape.template.Template(None, "<h1>@!this.title!@</h1>")
|
||||
ns.idxpath = "doc/index.html"
|
||||
this.layout = countershape.Layout("_websitelayout.html")
|
||||
else:
|
||||
ns.title = countershape.template.Template(None, "<h1>@!this.title!@</h1>")
|
||||
ns.idxpath = "index.html"
|
||||
this.layout = countershape.Layout("_layout.html")
|
||||
ns.docTitle = "mitmproxy"
|
||||
this.markup = markup.Markdown()
|
||||
|
||||
|
||||
ns.title = countershape.template.Template(None, "<h1>@!this.title!@</h1>")
|
||||
this.titlePrefix = "mitmproxy 0.9 - "
|
||||
this.markup = markup.Markdown(extras=["footnotes"])
|
||||
|
||||
ns.docMaintainer = "Aldo Cortesi"
|
||||
ns.docMaintainerEmail = "aldo@corte.si"
|
||||
ns.copyright = u"\u00a9 mitmproxy project, 2011"
|
||||
|
||||
ns.index = countershape.widgets.SiblingPageIndex('/index.html', divclass="pageindex")
|
||||
ns.copyright = u"\u00a9 mitmproxy project, 2013"
|
||||
|
||||
def mpath(p):
|
||||
p = os.path.join(MITMPROXY_SRC, p)
|
||||
return os.path.expanduser(p)
|
||||
|
||||
ns.license = file(mpath("LICENSE")).read()
|
||||
ns.index_contents = file(mpath("README.mkd")).read()
|
||||
|
||||
|
||||
|
||||
top = os.path.abspath(os.getcwd())
|
||||
def example(s):
|
||||
d = file(mpath(s)).read()
|
||||
return countershape.template.pySyntax(d)
|
||||
|
||||
|
||||
d = file(mpath(s)).read().rstrip()
|
||||
extemp = """<div class="example">%s<div class="example_legend">(%s)</div></div>"""
|
||||
return extemp%(countershape.template.Syntax("py")(d), s)
|
||||
ns.example = example
|
||||
|
||||
|
||||
filt_help = []
|
||||
for i in filt.filt_unary:
|
||||
filt_help.append(
|
||||
@@ -61,22 +59,28 @@ filt_help.extend(
|
||||
]
|
||||
)
|
||||
ns.filt_help = filt_help
|
||||
|
||||
|
||||
|
||||
def nav(page, current, state):
|
||||
if current.match(page, False):
|
||||
pre = '<li class="active">'
|
||||
else:
|
||||
pre = "<li>"
|
||||
p = state.application.getPage(page)
|
||||
return pre + '<a href="%s">%s</a></li>'%(model.UrlTo(page), p.title)
|
||||
ns.nav = nav
|
||||
|
||||
pages = [
|
||||
Page("index.html", "docs"),
|
||||
Page("intro.html", "Introduction"),
|
||||
Page("interception.html", "Interception"),
|
||||
Page("clientreplay.html", "Client-side replay"),
|
||||
Page("serverreplay.html", "Server-side replay"),
|
||||
Page("sticky.html", "Sticky cookies and auth"),
|
||||
Page("anticache.html", "Anticache"),
|
||||
Page("filters.html", "Filter expressions"),
|
||||
Page("scripts.html", "External scripts"),
|
||||
Page("library.html", "libmproxy: mitmproxy as a library"),
|
||||
Page("ssl.html", "SSL"),
|
||||
Page("index.html", "Introduction"),
|
||||
Page("install.html", "Installation"),
|
||||
Page("mitmproxy.html", "mitmproxy"),
|
||||
Page("mitmdump.html", "mitmdump"),
|
||||
Page("howmitmproxy.html", "How mitmproxy works"),
|
||||
|
||||
Page("ssl.html", "Overview"),
|
||||
Directory("certinstall"),
|
||||
Page("faq.html", "FAQ"),
|
||||
Page("admin.html", "Administrivia")
|
||||
Directory("scripting"),
|
||||
Directory("tutorials"),
|
||||
Page("transparent.html", "Overview"),
|
||||
Directory("transparent"),
|
||||
]
|
||||
|
||||
52
doc-src/install.html
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
The preferred way to install mitmproxy - whether you're installing the latest
|
||||
release or from source - is to use [pip](http://www.pip-installer.org/). If you
|
||||
don't already have pip on your system, you can find installation instructions
|
||||
[here](http://www.pip-installer.org/en/latest/installing.html).
|
||||
|
||||
|
||||
## Installing the latest release
|
||||
|
||||
A single command will download and install the latest release of mitmproxy,
|
||||
along with all its dependencies:
|
||||
|
||||
<pre class="terminal">
|
||||
pip install mitmproxy
|
||||
</pre>
|
||||
|
||||
|
||||
## Installing from source
|
||||
|
||||
When installing from source, the easiest method is still to use pip. In this
|
||||
case run:
|
||||
|
||||
<pre class="terminal">
|
||||
pip install /path/to/source
|
||||
</pre>
|
||||
|
||||
Note that if you're installing current git master, you will also have to
|
||||
install the current git master of [netlib](http://github.com/cortesi/netlib) by
|
||||
hand.
|
||||
|
||||
## OSX
|
||||
|
||||
- If you're running a Python interpreter installed with homebrew (or similar),
|
||||
you may have to install some dependencies by hand.
|
||||
- Make sure that XCode is installed from the App Store, and that the
|
||||
command-line tools have been downloaded (XCode/Preferences/Downloads).
|
||||
- Now use __pip__ to do the installation, as above.
|
||||
|
||||
There are a few bits of customization you might want to do to make mitmproxy
|
||||
comfortable to use on OSX. The default color scheme is optimized for a dark
|
||||
background terminal, but you can select a palette for a light terminal
|
||||
background with the --palette option. You can use the OSX <b>open</b> program
|
||||
to create a simple and effective <b>~/.mailcap</b> file to view request and
|
||||
response bodies:
|
||||
|
||||
<pre class="terminal">
|
||||
application/*; /usr/bin/open -Wn %s
|
||||
audio/*; /usr/bin/open -Wn %s
|
||||
image/*; /usr/bin/open -Wn %s
|
||||
video/*; /usr/bin/open -Wn %s
|
||||
</pre>
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
__mitmproxy__'s interception functionality lets you pause an HTTP request or
|
||||
response, inspect and modify it, and then accept it to send it on to the server
|
||||
or client. Because this is an interactive function, it's only present in
|
||||
__mitmproxy__, not in __mitmdump__.
|
||||
|
||||
|
||||
### 1: Set an interception pattern
|
||||
|
||||
<img src="@!urlTo('intercept-filt.png')!@"/>
|
||||
|
||||
We press __i__ to set an interception pattern. In this case, the __~q__ filter
|
||||
pattern tells __mitmproxy__ to intercept all requests. For complete filter
|
||||
syntax, see the [Filter expressions](@!urlTo("filters.html")!@) section of this
|
||||
document, or the built-in help function in __mitmproxy__.
|
||||
|
||||
### 2: Intercepted connections are indicated with a red exclamation mark:
|
||||
|
||||
<img src="@!urlTo('intercept-mid.png')!@"/>
|
||||
|
||||
### 3: You can now view and modify the request:
|
||||
|
||||
<img src="@!urlTo('intercept-options.png')!@"/>
|
||||
|
||||
In this case, we viewed the request by selecting it, pressed __e__ for "edit"
|
||||
and __m__ for "method" to change the HTTP request method.
|
||||
|
||||
### 4: Accept the intercept to continue
|
||||
|
||||
<img src="@!urlTo('intercept-result.png')!@"/>
|
||||
|
||||
Finally, we press __a__ to accept the modified request, which is then sent on
|
||||
to the server. In this case, we changed the request from an HTTP GET to to
|
||||
OPTIONS, and Google's server has responded with a 405 "Method not allowed".
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
@!index_contents!@
|
||||
|
||||
|
||||
68
doc-src/mitmdump.html
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
__mitmdump__ is the command-line companion to mitmproxy. It provides
|
||||
tcpdump-like functionality to let you view, record, and programmatically
|
||||
transform HTTP traffic. See the _--help_ flag output for complete
|
||||
documentation.
|
||||
|
||||
|
||||
|
||||
# Examples
|
||||
|
||||
|
||||
## Saving traffic
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -w outfile
|
||||
</pre>
|
||||
|
||||
Start up mitmdump in proxy mode, and write all traffic to __outfile__.
|
||||
|
||||
|
||||
## Filtering saved traffic
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -nr infile -w outfile "~m post"
|
||||
</pre>
|
||||
|
||||
Start mitmdump without binding to the proxy port (_-n_), read all flows from
|
||||
infile, apply the specified filter expression (only match POSTs), and write to
|
||||
outfile.
|
||||
|
||||
|
||||
## Client replay
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -nc outfile
|
||||
</pre>
|
||||
|
||||
Start mitmdump without binding to the proxy port (_-n_), then replay all
|
||||
requests from outfile (_-c filename_). Flags combine in the obvious way, so
|
||||
you can replay requests from one file, and write the resulting flows to
|
||||
another:
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -nc srcfile -w dstfile
|
||||
</pre>
|
||||
|
||||
See the [Client-side Replay](@!urlTo("clientreplay.html")!@) section for more information.
|
||||
|
||||
|
||||
## Running a script
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -s examples/add_header.py
|
||||
</pre>
|
||||
|
||||
This runs the __add_header.py__ example script, which simply adds a new header
|
||||
to all responses.
|
||||
|
||||
|
||||
## Scripted data transformation
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -ns examples/add_header.py -r srcfile -w dstfile
|
||||
</pre>
|
||||
|
||||
This command loads flows from __srcfile__, transforms it according to the
|
||||
specified script, then writes it back to __dstfile__.
|
||||
|
||||
115
doc-src/mitmproxy.html
Normal file
@@ -0,0 +1,115 @@
|
||||
|
||||
__mitmproxy__ is a console tool that allows interactive examination and
|
||||
modification of HTTP traffic. It differs from mitmdump in that all flows are
|
||||
kept in memory, which means that it's intended for taking and manipulating
|
||||
small-ish samples. Use the _?_ shortcut key to view, context-sensitive
|
||||
documentation from any __mitmproxy__ screen.
|
||||
|
||||
## Flow list
|
||||
|
||||
The flow list shows an index of captured flows in chronological order.
|
||||
|
||||
<img src="@!urlTo("screenshots/mitmproxy.png")!@"/>
|
||||
|
||||
- __1__: A GET request, returning a 302 Redirect response.
|
||||
- __2__: A GET request, returning 16.75kb of text/html data.
|
||||
- __3__: A replayed request.
|
||||
- __4__: Intercepted flows are indicated with orange text. The user may edit
|
||||
these flows, and then accept them (using the _a_ key) to continue. In this
|
||||
case, the request has been intercepted on the way to the server.
|
||||
- __5__: A response intercepted from the server on the way to the client.
|
||||
- __6__: The event log can be toggled on and off using the _e_ shortcut key. This
|
||||
pane shows events and errors that may not result in a flow that shows up in the
|
||||
flow pane.
|
||||
- __7__: Flow count.
|
||||
- __8__: Various information on mitmproxy's state. In this case, we have an
|
||||
interception pattern set to ".*".
|
||||
- __9__: Bind address indicator - mitmproxy is listening on port 8080 of all
|
||||
interfaces.
|
||||
|
||||
|
||||
## Flow view
|
||||
|
||||
The __Flow View__ lets you inspect and manipulate a single flow:
|
||||
|
||||
<img src="@!urlTo("screenshots/mitmproxy-flowview.png")!@"/>
|
||||
|
||||
- __1__: Flow summary.
|
||||
- __2__: The Request/Response tabs, showing you which part of the flow you are
|
||||
currently viewing. In the example above, we're viewing the Response. Hit _tab_
|
||||
to switch between the Response and the Request.
|
||||
- __3__: Headers.
|
||||
- __4__: Body.
|
||||
- __5__: View Mode indicator. In this case, we're viewing the body in __hex__
|
||||
mode. The other available modes are __pretty__, which uses a number of
|
||||
heuristics to show you a friendly view of various content types, and __raw__,
|
||||
which shows you exactly what's there without any changes. You can change modes
|
||||
using the _m_ key.
|
||||
|
||||
|
||||
|
||||
## Grid Editor
|
||||
|
||||
Much of the data that we'd like to interact with in mitmproxy is structured.
|
||||
For instance, headers, queries and form data can all be thought of as a list of
|
||||
key/value pairs. Mitmproxy has a built-in editor that lays this type of data
|
||||
out in a grid for easy manipulation.
|
||||
|
||||
At the moment, the Grid Editor is used in four parts of mitmproxy:
|
||||
|
||||
- Editing request or response headers (_e_ for edit, then _h_ for headers in flow view)
|
||||
- Editing a query string (_e_ for edit, then _q_ for query in flow view)
|
||||
- Editing a URL-encoded form (_e_ for edit, then _f_ for form in flow view)
|
||||
- Editing replacement patterns (_R_ globally)
|
||||
|
||||
If there is is no data, an empty editor will be started to let you add some.
|
||||
Here is the editor showing the headers from a request:
|
||||
|
||||
<img src="@!urlTo("screenshots/mitmproxy-kveditor.png")!@"/>
|
||||
|
||||
To edit, navigate to the key or value you want to modify using the arrow or vi
|
||||
navigation keys, and press enter. The background color will change to show that
|
||||
you are in edit mode for the specified field:
|
||||
|
||||
<img src="@!urlTo("screenshots/mitmproxy-kveditor-editmode.png")!@"/>
|
||||
|
||||
Modify the field as desired, then press escape to exit edit mode when you're
|
||||
done. You can also add a row (_a_ key), delete a row (_d_ key), spawn an
|
||||
external editor on a field (_e_ key). Be sure to consult the context-sensitive
|
||||
help (_?_ key) for more.
|
||||
|
||||
|
||||
# Example: Interception
|
||||
|
||||
__mitmproxy__'s interception functionality lets you pause an HTTP request or
|
||||
response, inspect and modify it, and then accept it to send it on to the server
|
||||
or client.
|
||||
|
||||
|
||||
### 1: Set an interception pattern
|
||||
|
||||
<img src="@!urlTo('mitmproxy-intercept-filt.png')!@"/>
|
||||
|
||||
We press _i_ to set an interception pattern. In this case, the __~q__ filter
|
||||
pattern tells __mitmproxy__ to intercept all requests. For complete filter
|
||||
syntax, see the [Filter expressions](@!urlTo("filters.html")!@) section of this
|
||||
document, or the built-in help function in __mitmproxy__.
|
||||
|
||||
### 2: Intercepted connections are indicated with orange text:
|
||||
|
||||
<img src="@!urlTo('mitmproxy-intercept-mid.png')!@"/>
|
||||
|
||||
### 3: You can now view and modify the request:
|
||||
|
||||
<img src="@!urlTo('mitmproxy-intercept-options.png')!@"/>
|
||||
|
||||
In this case, we viewed the request by selecting it, pressed _e_ for "edit"
|
||||
and _m_ for "method" to change the HTTP request method.
|
||||
|
||||
### 4: Accept the intercept to continue:
|
||||
|
||||
<img src="@!urlTo('mitmproxy-intercept-result.png')!@"/>
|
||||
|
||||
Finally, we press _a_ to accept the modified request, which is then sent on to
|
||||
the server. In this case, we changed the request from an HTTP GET to
|
||||
OPTIONS, and Google's server has responded with a 405 "Method not allowed".
|
||||
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 40 KiB |
BIN
doc-src/screenshots/mitmproxy-flowview.png
Normal file
|
After Width: | Height: | Size: 308 KiB |
BIN
doc-src/screenshots/mitmproxy-intercept-filt.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
doc-src/screenshots/mitmproxy-intercept-mid.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
doc-src/screenshots/mitmproxy-intercept-options.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
doc-src/screenshots/mitmproxy-intercept-result.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
doc-src/screenshots/mitmproxy-kveditor-editmode.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
doc-src/screenshots/mitmproxy-kveditor.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
doc-src/screenshots/mitmproxy.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
6
doc-src/scripting/index.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from countershape import Page
|
||||
|
||||
pages = [
|
||||
Page("inlinescripts.html", "Inline Scripts"),
|
||||
Page("libmproxy.html", "libmproxy")
|
||||
]
|
||||
137
doc-src/scripting/inlinescripts.html
Normal file
@@ -0,0 +1,137 @@
|
||||
__mitmproxy__ has a powerful scripting API that allows you to modify flows
|
||||
on-the-fly or rewrite previously saved flows locally.
|
||||
|
||||
The mitmproxy scripting API is event driven - a script is simply a Python
|
||||
module that exposes a set of event methods. Here's a complete mitmproxy script
|
||||
that adds a new header to every HTTP response before it is returned to the
|
||||
client:
|
||||
|
||||
$!example("examples/add_header.py")!$
|
||||
|
||||
The first argument to each event method is an instance of ScriptContext that
|
||||
lets the script interact with the global mitmproxy state. The __response__
|
||||
event also gets an instance of Flow, which we can use to manipulate the
|
||||
response itself.
|
||||
|
||||
We can now run this script using mitmdump or mitmproxy as follows:
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -s add_header.py
|
||||
</pre>
|
||||
|
||||
The new header will be added to all responses passing through the proxy.
|
||||
|
||||
|
||||
|
||||
## Events
|
||||
|
||||
### start(ScriptContext)
|
||||
|
||||
Called once on startup, before any other events.
|
||||
|
||||
|
||||
### clientconnect(ScriptContext, ClientConnect)
|
||||
|
||||
Called when a client initiates a connection to the proxy. Note that
|
||||
a connection can correspond to multiple HTTP requests.
|
||||
|
||||
|
||||
### request(ScriptContext, Flow)
|
||||
|
||||
Called when a client request has been received. The __Flow__ object is
|
||||
guaranteed to have a non-None __request__ attribute.
|
||||
|
||||
|
||||
### response(ScriptContext, Flow)
|
||||
|
||||
Called when a server response has been received. The __Flow__ object is
|
||||
guaranteed to have non-None __request__ and __response__ attributes.
|
||||
|
||||
|
||||
### error(ScriptContext, Flow)
|
||||
|
||||
Called when a flow error has occurred, e.g. invalid server responses, or
|
||||
interrupted connections. This is distinct from a valid server HTTP error
|
||||
response, which is simply a response with an HTTP error code. The __Flow__
|
||||
object is guaranteed to have non-None __request__ and __error__ attributes.
|
||||
|
||||
|
||||
### clientdisconnect(ScriptContext, ClientDisconnect)
|
||||
|
||||
Called when a client disconnects from the proxy.
|
||||
|
||||
### done(ScriptContext)
|
||||
|
||||
Called once on script shutdown, after any other events.
|
||||
|
||||
|
||||
## API
|
||||
|
||||
The main classes you will deal with in writing mitmproxy scripts are:
|
||||
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>libmproxy.flow.ClientConnection</th>
|
||||
<td>Describes a client connection.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.ClientDisconnection</th>
|
||||
<td>Describes a client disconnection.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.Error</th>
|
||||
<td>A communications error.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.Flow</th>
|
||||
<td>A collection of objects representing a single HTTP transaction.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.Headers</th>
|
||||
<td>HTTP headers for a request or response.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.ODict</th>
|
||||
|
||||
<td>A dictionary-like object for managing sets of key/value data. There
|
||||
is also a variant called CaselessODict that ignores key case for some
|
||||
calls (used mainly for headers).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.Response</th>
|
||||
<td>An HTTP response.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.Request</th>
|
||||
<td>An HTTP request.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.flow.ScriptContext</th>
|
||||
<td> A handle for interacting with mitmproxy's from within scripts. </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>libmproxy.certutils.SSLCert</th>
|
||||
<td>Exposes information SSL certificates.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
The canonical API documentation is the code. You can view the API documentation
|
||||
using pydoc (which is installed with Python by default), like this:
|
||||
|
||||
<pre class="terminal">
|
||||
> pydoc libmproxy.flow.Request
|
||||
</pre>
|
||||
|
||||
|
||||
## Running scripts on saved flows
|
||||
|
||||
Sometimes, we want to run a script on __Flow__ objects that are already
|
||||
complete. This happens when you start a script, and then load a saved set of
|
||||
flows from a file (see the "scripted data transformation" example on the
|
||||
[mitmdump](@!urlTo("mitmdump.html")!@) page). It also happens when you run a
|
||||
one-shot script on a single flow through the _|_ (pipe) shortcut in mitmproxy.
|
||||
|
||||
In this case, there are no client connections, and the events are run in the
|
||||
following order: __start__, __request__, __response__, __error__, __done__. If
|
||||
the flow doesn't have a __response__ or __error__ associated with it, the
|
||||
matching event will be skipped.
|
||||
@@ -8,5 +8,5 @@ this lets you log in to a site using your browser, and then make subsequent
|
||||
requests using a tool like __curl__, which will then seem to be part of the
|
||||
authenticated session.
|
||||
|
||||
$!example("examples/stickycookies.py")!$
|
||||
$!example("examples/stickycookies")!$
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
Both __mitmproxy__ and __mitmdump__ allow you to modify requests and responses
|
||||
with external scripts. This is often done through the __--reqscript__ and
|
||||
__--respscript__ options
|
||||
|
||||
|
||||
The script interface is simple - scripts simply read,
|
||||
modify and return a single __libmproxy.flow.Flow__ object, using the methods
|
||||
defined in the __libmproxy.script__ module. Scripts must be executable.
|
||||
|
||||
$!example("examples/simple_script")!$
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,22 +1,27 @@
|
||||
|
||||
The first time __mitmproxy__ or __mitmdump__ is started, the following set of
|
||||
certificate files for a dummy Certificate Authority are created in the config
|
||||
directory (~/.mitmproxy by default):
|
||||
The first time __mitmproxy__ or __mitmdump__ is run, a set of certificate files
|
||||
for the mitmproxy Certificate Authority are created in the config directory
|
||||
(~/.mitmproxy by default). The files are as follows:
|
||||
|
||||
<table>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td>mitmproxy-ca.pem</td>
|
||||
<td class="nowrap">mitmproxy-ca.pem</td>
|
||||
<td>The private key and certificate in PEM format.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>mitmproxy-ca-cert.pem</td>
|
||||
<td class="nowrap">mitmproxy-ca-cert.pem</td>
|
||||
<td>The certificate in PEM format. Use this to distribute to most
|
||||
non-Windows platforms.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>mitmproxy-ca-cert.p12</td>
|
||||
<td class="nowrap">mitmproxy-ca-cert.p12</td>
|
||||
<td>The certificate in PKCS12 format. For use on Windows.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="nowrap">mitmproxy-ca-cert.cer</td>
|
||||
<td>Same file as .pem, but with an extension expected by some Android
|
||||
devices.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
This CA is used for on-the-fly generation of dummy certificates for SSL
|
||||
@@ -24,16 +29,9 @@ interception. Since your browser won't trust the __mitmproxy__ CA out of the
|
||||
box (and rightly so), you will see an SSL cert warning every time you visit a
|
||||
new SSL domain through __mitmproxy__. When you're testing a single site through
|
||||
a browser, just accepting the bogus SSL cert manually is not too much trouble,
|
||||
but there are a number of cases where you will want to configure your testing
|
||||
system or browser to trust the __mitmproxy__ CA as a signing root authority:
|
||||
|
||||
- If you are testing non-browser software that checks SSL cert validity using
|
||||
the system certificate store.
|
||||
- You are testing an app that makes non-interactive (JSONP, script src, etc.)
|
||||
requests to SSL resources. Another workaround in this case is to manually visit
|
||||
the page through the browser, and add a certificate exception.
|
||||
- You just don't want to deal with the hassle of continuously adding cert
|
||||
exceptions.
|
||||
but there are a many circumstances where you will want to configure your
|
||||
testing system or browser to trust the __mitmproxy__ CA as a signing root
|
||||
authority.
|
||||
|
||||
|
||||
Installing the mitmproxy CA
|
||||
@@ -43,4 +41,6 @@ Installing the mitmproxy CA
|
||||
* [OSX](@!urlTo("certinstall/osx.html")!@)
|
||||
* [Windows 7](@!urlTo("certinstall/windows7.html")!@)
|
||||
* [iPhone/iPad](@!urlTo("certinstall/ios.html")!@)
|
||||
* [IOS Simulator](@!urlTo("certinstall/ios-simulator.html")!@)
|
||||
* [Android](@!urlTo("certinstall/android.html")!@)
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
|
||||
When the __stickycookie__ option is set, __mitmproxy__ will add the cookie most
|
||||
recently set by the server to any cookie-less request. Consider a service that
|
||||
sets a cookie to track the session after authentication. Using sticky cookies,
|
||||
you can fire up mitmproxy, and authenticate to a service as you usually would
|
||||
using a browser. After authentication, you can request authenticated resources
|
||||
through mitmproxy as if they were unauthenticated, because mitmproxy will
|
||||
automatically add the session tracking cookie to requests. Among other things,
|
||||
this lets you script interactions with authenticated resources (using tools
|
||||
like wget or curl) without having to worry about authentication.
|
||||
|
||||
Sticky cookies are especially powerful when used in conjunction with [client
|
||||
replay](@!urlTo("clientreplay.html")!@) - you can record the authentication
|
||||
process once, and simply replay it on startup every time you need to interact
|
||||
with the secured resources.
|
||||
|
||||
|
||||
## Sticky auth
|
||||
|
||||
The __stickyauth__ option is analogous to the __stickycookie__ option, in that
|
||||
HTTP __Authorization__ headers are simply replayed to the server once they have
|
||||
been seen. This is enough to allow you to access a server resource using HTTP
|
||||
Basic authentication through the proxy. Note that __mitmproxy__ doesn't (yet)
|
||||
support replay of HTTP Digest authentication.
|
||||
19
doc-src/transparent.html
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
When a transparent proxy is used, traffic is redirected into a proxy at the
|
||||
network layer, without any client configuration being required. This makes
|
||||
transparent proxying ideal for those situations where you can't change client
|
||||
behaviour - proxy-oblivious Android applications being a common example.
|
||||
|
||||
To set up transparent proxying, we need two new components. The first is a
|
||||
redirection mechanism that transparently reroutes a TCP connection destined for
|
||||
a server on the Internet to a listening proxy server. This usually takes the
|
||||
form of a firewall on the same host as the proxy server -
|
||||
[iptables](http://www.netfilter.org/) on Linux or
|
||||
[pf](http://en.wikipedia.org/wiki/PF_\(firewall\)) on OSX. When the proxy
|
||||
receives a redirected connection, it sees a vanilla HTTP request, without a
|
||||
host specification. This is where the second new component comes in - a host
|
||||
module that allows us to query the redirector for the original destination of
|
||||
the TCP connection.
|
||||
|
||||
At the moment, mitmproxy supports transparent proxying on OSX Lion and above,
|
||||
and all current flavors of Linux.
|
||||
BIN
doc-src/transparent.png
Normal file
|
After Width: | Height: | Size: 68 KiB |
6
doc-src/transparent/index.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from countershape import Page
|
||||
|
||||
pages = [
|
||||
Page("osx.html", "OSX"),
|
||||
Page("linux.html", "Linux"),
|
||||
]
|
||||
40
doc-src/transparent/linux.html
Normal file
@@ -0,0 +1,40 @@
|
||||
On Linux, mitmproxy integrates with the iptables redirection mechanism to
|
||||
achieve transparent mode.
|
||||
|
||||
<ol class="tlist">
|
||||
|
||||
<li> <a href="@!urlTo("ssl.html")!@">Install the mitmproxy
|
||||
certificates on the test device</a>. </li>
|
||||
|
||||
<li> Enable IP forwarding:
|
||||
|
||||
<pre class="terminal">sysctl -w net.ipv4.ip_forward=1</pre>
|
||||
|
||||
You may also want to consider enabling this permanently in
|
||||
<b>/etc/sysctl.conf</b>.
|
||||
|
||||
</li>
|
||||
|
||||
<li> Create an iptables ruleset that redirects the desired traffic to the
|
||||
mitmproxy port. Details will differ according to your setup, but the
|
||||
ruleset should look something like this:
|
||||
|
||||
<pre class="terminal">iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
|
||||
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 8080</pre>
|
||||
|
||||
</li>
|
||||
|
||||
<li> Fire up mitmproxy. You probably want a command like this:
|
||||
|
||||
<pre class="terminal">mitmproxy -T --host</pre>
|
||||
|
||||
The <b>-T</b> flag turns on transparent mode, and the <b>--host</b>
|
||||
argument tells mitmproxy to use the value of the Host header for URL
|
||||
display.
|
||||
|
||||
</li>
|
||||
|
||||
<li> Finally, configure your test device to use the host on which mitmproxy is
|
||||
running as the default gateway.</li>
|
||||
|
||||
</ol>
|
||||
69
doc-src/transparent/osx.html
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
|
||||
OSX Lion integrated the [pf](http://www.openbsd.org/faq/pf/) packet filter from
|
||||
the OpenBSD project, which mitmproxy uses to implement transparent mode on OSX.
|
||||
Note that this means we don't support transparent mode for earlier versions of
|
||||
OSX.
|
||||
|
||||
<ol class="tlist">
|
||||
|
||||
<li> <a href="@!urlTo("ssl.html")!@">Install the mitmproxy
|
||||
certificates on the test device</a>. </li>
|
||||
|
||||
<li> Enable IP forwarding:
|
||||
|
||||
<pre class="terminal">sudo sysctl -w net.inet.ip.forwarding=1</pre>
|
||||
</li>
|
||||
|
||||
<li> Place the following two lines in a file called, say, <b>pf.conf</b>:
|
||||
|
||||
<pre class="terminal">rdr on en2 inet proto tcp to any port 80 -> 127.0.0.1 port 8080
|
||||
rdr on en2 inet proto tcp to any port 443 -> 127.0.0.1 port 8080
|
||||
</pre>
|
||||
|
||||
These rules tell pf to redirect all traffic destined for port 80 or 443
|
||||
to the local mitmproxy instance running on port 8080. You should
|
||||
replace <b>en2</b> with the interface on which your test device will
|
||||
appear.
|
||||
|
||||
</li>
|
||||
|
||||
<li> Configure pf with the rules:
|
||||
|
||||
<pre class="terminal">sudo pfctl -f pf.conf</pre>
|
||||
|
||||
</li>
|
||||
|
||||
<li> And now enable it:
|
||||
|
||||
<pre class="terminal">sudo pfctl -e</pre>
|
||||
|
||||
</li>
|
||||
|
||||
<li> Configure sudoers to allow mitmproxy to access pfctl. Edit the file
|
||||
<b>/etc/sudoers</b> on your system as root. Add the following line to the end
|
||||
of the file:
|
||||
|
||||
<pre>ALL ALL=NOPASSWD: /sbin/pfctl -s state</pre>
|
||||
|
||||
Note that this allows any user on the system to run the command
|
||||
"/sbin/pfctl -s state" as root without a password. This only allows
|
||||
inspection of the state table, so should not be an undue security risk. If
|
||||
you're special feel free to tighten the restriction up to the user running
|
||||
mitmproxy.</li>
|
||||
|
||||
<li> Fire up mitmproxy. You probably want a command like this:
|
||||
|
||||
<pre class="terminal">mitmproxy -T --host</pre>
|
||||
|
||||
The <b>-T</b> flag turns on transparent mode, and the <b>--host</b>
|
||||
argument tells mitmproxy to use the value of the Host header for URL
|
||||
display.
|
||||
|
||||
</li>
|
||||
|
||||
<li> Finally, configure your test device to use the host on which mitmproxy is
|
||||
running as the default gateway.</li>
|
||||
|
||||
|
||||
</ol>
|
||||
BIN
doc-src/transparent_https.png
Normal file
|
After Width: | Height: | Size: 78 KiB |
61
doc-src/tutorials/30second.html
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
My local cafe is serviced by a rickety and unreliable wireless network,
|
||||
generously sponsored with ratepayers' money by our city council. After
|
||||
connecting, you are redirected to an SSL-protected page that prompts you for a
|
||||
username and password. Once you've entered your details, you are free to enjoy
|
||||
the intermittent dropouts, treacle-like speeds and incorrectly configured
|
||||
transparent proxy.
|
||||
|
||||
I tend to automate this kind of thing at the first opportunity, on the theory
|
||||
that time spent now will be more than made up in the long run. In this case, I
|
||||
might use [Firebug](http://getfirebug.com/) to ferret out the form post
|
||||
parameters and target URL, then fire up an editor to write a little script
|
||||
using Python's [urllib](http://docs.python.org/library/urllib.html) to simulate
|
||||
a submission. That's a lot of futzing about. With mitmproxy we can do the job
|
||||
in literally 30 seconds, without having to worry about any of the details.
|
||||
Here's how.
|
||||
|
||||
## 1. Run mitmdump to record our HTTP conversation to a file.
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -w wireless-login
|
||||
</pre>
|
||||
|
||||
## 2. Point your browser at the mitmdump instance.
|
||||
|
||||
I use a tiny Firefox addon called [Toggle
|
||||
Proxy](https://addons.mozilla.org/en-us/firefox/addon/toggle-proxy-51740/) to
|
||||
switch quickly to and from mitmproxy. I'm assuming you've already [configured
|
||||
your browser with mitmproxy's SSL certificate
|
||||
authority](http://mitmproxy.org/doc/ssl.html).
|
||||
|
||||
## 3. Log in as usual.
|
||||
|
||||
|
||||
And that's it! You now have a serialized version of the login process in the
|
||||
file wireless-login, and you can replay it at any time like this:
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmdump -c wireless-login
|
||||
</pre>
|
||||
|
||||
## Embellishments
|
||||
|
||||
We're really done at this point, but there are a couple of embellishments we
|
||||
could make if we wanted. I use [wicd](http://wicd.sourceforge.net/) to
|
||||
automatically join wireless networks I frequent, and it lets me specify a
|
||||
command to run after connecting. I used the client replay command above and
|
||||
voila! - totally hands-free wireless network startup.
|
||||
|
||||
We might also want to prune requests that download CSS, JS, images and so
|
||||
forth. These add only a few moments to the time it takes to replay, but they're
|
||||
not really needed and I somehow feel compelled to trim them anyway. So, we fire up
|
||||
the mitmproxy console tool on our serialized conversation, like so:
|
||||
|
||||
<pre class="terminal">
|
||||
> mitmproxy -r wireless-login
|
||||
</pre>
|
||||
|
||||
We can now go through and manually delete (using the __d__ keyboard shortcut)
|
||||
everything we want to trim. When we're done, we use __w__ to save the
|
||||
conversation back to the file.
|
||||
122
doc-src/tutorials/gamecenter.html
Normal file
@@ -0,0 +1,122 @@
|
||||
|
||||
## The setup
|
||||
|
||||
In this tutorial, I'm going to show you how simple it is to creatively
|
||||
interfere with Apple Game Center traffic using mitmproxy. To set things up, I
|
||||
registered my mitmproxy CA certificate with my iPhone - there's a [step by step
|
||||
set of instructions](@!urlTo("certinstall/ios.html")!@) elsewhere in this manual. I then
|
||||
started mitmproxy on my desktop, and configured the iPhone to use it as a
|
||||
proxy.
|
||||
|
||||
|
||||
## Taking a look at the Game Center traffic
|
||||
|
||||
Lets take a first look at the Game Center traffic. The game I'll use in this
|
||||
tutorial is [Super Mega
|
||||
Worm](http://itunes.apple.com/us/app/super-mega-worm/id388541990?mt=8) - a
|
||||
great little retro-apocalyptic sidescroller for the iPhone:
|
||||
|
||||
<center>
|
||||
<img src="@!urlTo("tutorials/supermega.png")!@"/>
|
||||
</center>
|
||||
|
||||
After finishing a game (take your time), watch the traffic flowing through
|
||||
mitmproxy:
|
||||
|
||||
<center>
|
||||
<img src="@!urlTo("tutorials/one.png")!@"/>
|
||||
</center>
|
||||
|
||||
We see a bunch of things we might expect - initialisation, the retrieval of
|
||||
leaderboards and so forth. Then, right at the end, there's a POST to this
|
||||
tantalising URL:
|
||||
|
||||
<pre>
|
||||
https://service.gc.apple.com/WebObjects/GKGameStatsService.woa/wa/submitScore
|
||||
</pre>
|
||||
|
||||
The contents of the submission are particularly interesting:
|
||||
|
||||
<!--(block|syntax("xml"))-->
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>scores</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>category</key>
|
||||
<string>SMW_Adv_USA1</string>
|
||||
<key>context</key>
|
||||
<integer>0</integer>
|
||||
<key>score-value</key>
|
||||
<integer>0</integer>
|
||||
<key>timestamp</key>
|
||||
<integer>1363515361321</integer>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
<!--(end)-->
|
||||
|
||||
This is a [property list](http://en.wikipedia.org/wiki/Property_list),
|
||||
containing an identifier for the game, a score (55, in this case), and a
|
||||
timestamp. Looks pretty simple to mess with.
|
||||
|
||||
|
||||
## Modifying and replaying the score submission
|
||||
|
||||
Lets edit the score submission. First, select it in mitmproxy, then press
|
||||
__enter__ to view it. Make sure you're viewing the request, not the response -
|
||||
you can use __tab__ to flick between the two. Now press __e__ for edit. You'll
|
||||
be prompted for the part of the request you want to change - press __b__ for
|
||||
body. Your preferred editor (taken from the EDITOR environment variable) will
|
||||
now fire up. Lets bump the score up to something a bit more ambitious:
|
||||
|
||||
<!--(block|syntax("xml"))-->
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>scores</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>category</key>
|
||||
<string>SMW_Adv_USA1</string>
|
||||
<key>context</key>
|
||||
<integer>0</integer>
|
||||
<key>score-value</key>
|
||||
<integer>2200272667</integer>
|
||||
<key>timestamp</key>
|
||||
<integer>1363515361321</integer>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
<!--(end)-->
|
||||
|
||||
Save the file and exit your editor.
|
||||
|
||||
The final step is to replay this modified request. Simply press __r__ for
|
||||
replay.
|
||||
|
||||
## The glorious result and some intrigue
|
||||
|
||||
<center>
|
||||
<img src="@!urlTo("tutorials/leaderboard.png")!@"/>
|
||||
</center>
|
||||
|
||||
And that's it - according to the records, I am the greatest Super Mega Worm
|
||||
player of all time.
|
||||
|
||||
There's a curious addendum to this tale. When I first wrote this tutorial, all
|
||||
the top competitors' scores were the same: 2,147,483,647 (this is no longer the
|
||||
case, beacause there are now so many fellow cheaters using this tutorial). If
|
||||
you think that number seems familiar, you're right: it's 2^31-1, the maximum
|
||||
value you can fit into a signed 32-bit int. Now let me tell you another
|
||||
peculiar thing about Super Mega Worm - at the end of every game, it submits
|
||||
your highest previous score to the Game Center, not your current score. This
|
||||
means that it stores your highscore somewhere, and I'm guessing that it reads
|
||||
that stored score back into a signed integer. So, if you _were_ to cheat by the
|
||||
relatively pedestrian means of modifying the saved score on your jailbroken
|
||||
phone, then 2^31-1 might well be the maximum score you could get. Then again,
|
||||
if the game itself stores its score in a signed 32-bit int, you could get the
|
||||
same score through perfect play, effectively beating the game. So, which is it
|
||||
in this case? I'll leave that for you to decide.
|
||||
|
||||
6
doc-src/tutorials/index.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from countershape import Page
|
||||
|
||||
pages = [
|
||||
Page("30second.html", "Client playback: a 30 second example"),
|
||||
Page("gamecenter.html", "Setting highscores on Apple's GameCenter"),
|
||||
]
|
||||
BIN
doc-src/tutorials/leaderboard.png
Normal file
|
After Width: | Height: | Size: 438 KiB |
BIN
doc-src/tutorials/one.png
Normal file
|
After Width: | Height: | Size: 138 KiB |
BIN
doc-src/tutorials/supermega.png
Normal file
|
After Width: | Height: | Size: 91 KiB |
9
examples/README
Normal file
@@ -0,0 +1,9 @@
|
||||
add_header.py Simple script that just adds a header to every request.
|
||||
dup_and_replay.py Duplicates each request, changes it, and then replays the modified request.
|
||||
flowbasic Basic use of mitmproxy as a library.
|
||||
modify_form.py Modify all form submissions to add a parameter.
|
||||
modify_querystring.py Modify all query strings to add a parameters.
|
||||
proxapp How to embed a WSGI app in a mitmproxy server
|
||||
stub.py Script stub with a method definition for every event.
|
||||
stickycookies An example of writing a custom proxy with libmproxy.
|
||||
upsidedownternet.py Rewrites traffic to turn PNGs upside down.
|
||||
2
examples/add_header.py
Normal file
@@ -0,0 +1,2 @@
|
||||
def response(context, flow):
|
||||
flow.response.headers["newheader"] = ["foo"]
|
||||
4
examples/dup_and_replay.py
Normal file
@@ -0,0 +1,4 @@
|
||||
def request(ctx, flow):
|
||||
f = ctx.duplicate_flow(flow)
|
||||
f.request.path = "/changed"
|
||||
ctx.replay_request(f)
|
||||
39
examples/flowbasic
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
This example shows how to build a proxy based on mitmproxy's Flow
|
||||
primitives.
|
||||
|
||||
Note that request and response messages are not automatically replied to,
|
||||
so we need to implement handlers to do this.
|
||||
"""
|
||||
import os
|
||||
from libmproxy import proxy, flow
|
||||
|
||||
class MyMaster(flow.FlowMaster):
|
||||
def run(self):
|
||||
try:
|
||||
flow.FlowMaster.run(self)
|
||||
except KeyboardInterrupt:
|
||||
self.shutdown()
|
||||
|
||||
def handle_request(self, r):
|
||||
f = flow.FlowMaster.handle_request(self, r)
|
||||
if f:
|
||||
r.reply()
|
||||
return f
|
||||
|
||||
def handle_response(self, r):
|
||||
f = flow.FlowMaster.handle_response(self, r)
|
||||
if f:
|
||||
r.reply()
|
||||
print f
|
||||
return f
|
||||
|
||||
|
||||
config = proxy.ProxyConfig(
|
||||
cacert = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem")
|
||||
)
|
||||
state = flow.State()
|
||||
server = proxy.ProxyServer(config, 8080)
|
||||
m = MyMaster(server, state)
|
||||
m.run()
|
||||
50
examples/iframe_injector
Executable file
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Zap encoding in requests and inject iframe after body tag in html responses.
|
||||
Usage:
|
||||
iframe_injector http://someurl/somefile.html
|
||||
"""
|
||||
from libmproxy import controller, proxy
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
class InjectingMaster(controller.Master):
|
||||
def __init__(self, server, iframe_url):
|
||||
controller.Master.__init__(self, server)
|
||||
self._iframe_url = iframe_url
|
||||
|
||||
def run(self):
|
||||
try:
|
||||
return controller.Master.run(self)
|
||||
except KeyboardInterrupt:
|
||||
self.shutdown()
|
||||
|
||||
def handle_request(self, msg):
|
||||
if 'Accept-Encoding' in msg.headers:
|
||||
msg.headers["Accept-Encoding"] = 'none'
|
||||
msg.reply()
|
||||
|
||||
def handle_response(self, msg):
|
||||
if msg.content:
|
||||
c = msg.replace('<body>', '<body><iframe src="%s" frameborder="0" height="0" width="0"></iframe>' % self._iframe_url)
|
||||
if c > 0:
|
||||
print 'Iframe injected!'
|
||||
msg.reply()
|
||||
|
||||
|
||||
def main(argv):
|
||||
if len(argv) != 2:
|
||||
print "Usage: %s IFRAME_URL" % argv[0]
|
||||
sys.exit(1)
|
||||
iframe_url = argv[1]
|
||||
config = proxy.ProxyConfig(
|
||||
cacert = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem")
|
||||
)
|
||||
server = proxy.ProxyServer(config, 8080)
|
||||
print 'Starting proxy...'
|
||||
m = InjectingMaster(server, iframe_url)
|
||||
m.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
8
examples/modify_form.py
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
def request(context, flow):
|
||||
if "application/x-www-form-urlencoded" in flow.request.headers["content-type"]:
|
||||
frm = flow.request.get_form_urlencoded()
|
||||
frm["mitmproxy"] = ["rocks"]
|
||||
flow.request.set_form_urlencoded(frm)
|
||||
|
||||
|
||||
7
examples/modify_querystring.py
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
def request(context, flow):
|
||||
q = flow.request.get_query()
|
||||
if q:
|
||||
q["mitmproxy"] = ["rocks"]
|
||||
flow.request.set_query(q)
|
||||
|
||||
47
examples/proxapp
Executable file
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
This example shows how to graft a WSGI app onto mitmproxy. In this
|
||||
instance, we're using the Bottle framework (http://bottlepy.org/) to expose
|
||||
a single simplest-possible page.
|
||||
"""
|
||||
import bottle
|
||||
import os
|
||||
from libmproxy import proxy, flow
|
||||
|
||||
@bottle.route('/')
|
||||
def index():
|
||||
return 'Hi!'
|
||||
|
||||
|
||||
class MyMaster(flow.FlowMaster):
|
||||
def run(self):
|
||||
try:
|
||||
flow.FlowMaster.run(self)
|
||||
except KeyboardInterrupt:
|
||||
self.shutdown()
|
||||
|
||||
def handle_request(self, r):
|
||||
f = flow.FlowMaster.handle_request(self, r)
|
||||
if f:
|
||||
r.reply()
|
||||
return f
|
||||
|
||||
def handle_response(self, r):
|
||||
f = flow.FlowMaster.handle_response(self, r)
|
||||
if f:
|
||||
r.reply()
|
||||
print f
|
||||
return f
|
||||
|
||||
|
||||
config = proxy.ProxyConfig(
|
||||
cacert = os.path.expanduser("~/.mitmproxy/mitmproxy-ca.pem")
|
||||
)
|
||||
state = flow.State()
|
||||
server = proxy.ProxyServer(config, 8080)
|
||||
# Register the app using the magic domain "proxapp" on port 80. Requests to
|
||||
# this domain and port combination will now be routed to the WSGI app instance.
|
||||
server.apps.add(bottle.app(), "proxapp", 80)
|
||||
m = MyMaster(server, state)
|
||||
m.run()
|
||||
|
||||