From 47de698aab2d5a698628d43f5740beae2b70f35d Mon Sep 17 00:00:00 2001 From: Austin Lane Date: Thu, 28 Feb 2013 12:55:19 -0600 Subject: [PATCH] Added document import/export functionality. Fixed some file loading issues. --- README.md | 9 +- build/jar/BurpNotesExtension.jar | Bin 25489 -> 27204 bytes src/burp/BurpExtender.java | 77 +++++-- .../trustwave/burp/ButtonTabComponent.java | 10 +- .../burp/NotesExtensionOperations.java | 217 ++++++++++++++++-- 5 files changed, 269 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 6f981fc..9582b84 100644 --- a/README.md +++ b/README.md @@ -32,11 +32,14 @@ interface from source, then click "Open". 5. Click "Next" to load the plugin. -Within the Notes tab, there are four options: +Within the Notes tab, you can: - Save Notes: Save any currently open documents to a file. - Load Notes: Load a previously saved set of notes from a file. -- Add Text: Add a tab with a new text document. -- Add Spreadsheet: Add a tab with a new spreadsheet. +- New Text: Add a tab with a new text document. +- Import Text: Load the contents of a text document. +- New Spreadsheet: Add a tab with a new spreadsheet. +- Import Spreadsheet: Load the contents of a CSV document. +- You can also export individual notes tabs to an external file. From other tabs in Burp, right clicking in areas where a user can normally interact with HTTP Responses and Requests, such as the Proxy History or Site Map diff --git a/build/jar/BurpNotesExtension.jar b/build/jar/BurpNotesExtension.jar index e38b42ca1dbafc2f26fafe59672e7f7af62ad466..b11fda418fcb49e0350ce5359e0f61689eaa4b88 100644 GIT binary patch delta 12290 zcmZX4by(fr(k|}q?rz14yB2qMDehKmz9dvUm&o^!tM{_f2m zc_*1S$vl}SvsTu;$-|HX^N^^j3eYe}5D*9u5Z|o~lTjI=~Q$?qk8D?RSBIjextZr!GXm>-E|>gx6-e@5vyT z<3y4!f;+-0ZU95Pge=lkYRHjO#zNIcb?95%B>~Y`ZxK?0>rPAD8m{61#xUtmKxs&O zi|a?g&!SBj@AXPCous|-?2rzqp>!Zp36A15s9>`=M8jWCRaMjU3IsBh=?(C=Wp?pF zEyMum$S_6({&2HU?iG3y0&m8}Jy|SA>%pQk_^9?uB9ZN%3iW9Stp*KW@BxGz~8~4#3boVhHgn$ER6}zYoBKxRGT+0V&=cx#|!zhsvE!FF# zi56xl4k<7h4>4mkFu^3^(l~5R7KgQ_d1Lur>9%i@=(pX03BNi{L29!p}HFPg$+Wb>?ciCu>DTuT7? z?TUkfLXT|g)UyoC`t?%ing)USkIOD z7&5=#Jb${;z+_DtcK45%>Ku)tJoyNS`Qd>wzWez$Jm$k?YFHa|#Ayr36VIAWP z+nW@EV0auee<HzcRvsv;t)r=69#RY@B0CP;7$)%3)Hu@A_Nu~KxoLA8uF?+Y6z!-Wh4EQKZk77_ zM69$aAV=OTKZ$NObRR3k_>MkDt}-|pcn{?%eqriwD_8k~mCmR%w25sy8CGHM{UB0m zq)h|q+X_X`R;T$eY?#G~@b*{*uulNv;q`J+&KAdSqq)Pob%?KamSug(Bsn$mx@5{2 zrElh+#>@gerB=yAfwfkB8wzI#GN76399W383iTwrJjC3N1KN>Fd`Z8UZ(CbS3*RIZ z+tJcM-KtS@rOETmdLp=fWow(WHU4n^5;Z}W;aLCt%{3ySoIhz8ztE-{K<^QGu_E=b z7DX1n*GZAX z3!f3+IDGmo?ZQ>;lMOhS)(Jp;0oCSpNH(m>@!kz!bs{HWDU|WUzfx~Oprvs%(qn*X zwB{3NCnX8aIKh@_q+<(IZ^T^pE78ueoIEs`gwF}AFA{RJdrFfCgRU2Uz zH$LsF_S#uh^A28SJH+CozRtduEa;_~<3!WM~( zX@ro-cd#BKo|vxn2Nrj5>&sUiF!wnh>4`wy+Yhuf_}{_JDr;R)q{h|B;5`=;>eq{H zgGT#~drmK9spB*kR-;U#D9|7WDHGKa9vQ_uJhF>57<6y}Fe%{#9IB$+~Ucl3| zreHhU{<`4Z>sgN9`47>z*N2Zm&@H%qK)wPq1o}`uT6|mFQXY>@#i$5H z44~1szJ?gWhX6f5Xhi*2VCuLYe-^Ob-Hoqi8yD3qJ7qUJ2ASy5Rjt3$M@ijy$ptYT z*M`_b=j^#L;sC&@_XGlt_K;1qGa6H*5B*yNUIv!$z^Mf#+)R* zj#F~Us^8uCr;x707_cUMC}wxKc`t$L3f|GNdTA=(E5bmg3LehPELn06lX7~g6;^J* z5O&pci&!eaOg_*Oomoza>t~nw3a+tcEms@eD83vM$9}ZpNGp6{;u19X=QLLBl=imz z5HaOCrUGVQo-k|{S1*0*VF_$al6Q2QHx9ixkx*KzDQ*V>eSm*8`&cxJbX0A4oy@3Z zU!(j+x$IiNfPsk$Uo1}2z@b3gE<^c(Zb1*}=cy6ENK}Zc$$2Oxy<_56B7t0SiD7Y} z%KU!dEJw%-(sp9L^qFXJ{~#1;1q}8j4K=D7ZmdAHg?z8|lve+zAJew6*G=Lp#XCwJ zw4NQ{9ny}<9pP4glSz@DNCA;PRDtG3f*kWnEddr%@*V8iWt?k@#AO zswzsdHwi}2{1blSjQEm2XkP6yG~vCjC*)c2!4sXy;$>jFzIe=CBByyg$83z0)17GM zO;}0E*hz5~nzmR)j1O#;q>xsO@>XfMA$I|W))!M^=*!|*ve4)?bt@0HP{;Lp6Hu3N zbRuKnf*7?6sD3B%;+kB+nT4(41St~I8_>d1tsYsARMi|=x*q{RbLbCQY^u~r??odYGwHgNdf~^`hBAyw2$Rhmq_PgsP}3%!#Ew^7=}$b_#sW@3EVjr@fliq8e# z;P|(3j~TfUdH@JH*kuzv?}6&8hnu+;zEK)6FSI8+){p1iAWpN^o zm&%inQspeJ#uip^6)@bJ(9I4=K@N+oZ~b#&u@X0ha*iSkmGeo6?EU`j3247U==hnJ zjj(^CiFSnuHw$AA(|9oyaR(q;gvsa=Q+!2fZDu7i=*8yQ-C1WW@eSomKqS}8JGY2T z0SmUMIF&eeHxB{+S$sLrHCg%~As|ShAs|@aC(staB~)6#eT6Ee92mmDFo*UQ z?i&f4evsIwkC3*ImoninYUCm6`sKLi%I2%#;7)zP^zJSEn0dTtc#$Ayi6~bwiBuxS zG@;zfY%VhLr-SozQHYM7MWHd>+kNdQhy{%1@B0(JLHa>{VXXy<#~Jf6wTlllk!~bw zYK4h_ZSTmsHLaHb z@9d#f00g7B;HL(-)2l@MR?l_qns?SKG_Y0~I@cyG>DxGse79)hep+KklTgYJ>Wk#E;j5*4D zA6L@EyK9wy=x&#VSygSa`B5H>16S{%|B>(dLDVrww117daxl2cI8X_#Hx-3W8+7IVTB6DHi;Lx~P&*mCntRvQ9eD2d>&18f9PoCJ-J|@REk#c@oo|sC z(@A9aU4?q$6^>-{Ae4!0b~;E{=n!BwGhV3DFMe}v6EsMP8kxK|gNY}rx2yZHY>Ob_ z+D5LwpI|>ghC6OMECv`S(1?;~s@U(Ft$kS*5$_X6pGfZtr*iRI9*#h0f~%{i&ob1K zquN|zP!IP2XC5Ayw(;GlchRsnXAH)86x}+`He)os!@Q&!2d0|KZujYDc_H9fj(%Bz z?TKX=35{WTPT}TIsGMTvAXB{;sR%>2nv15>bt&s>Nl25&Srvz)Wn2aYbtz)*VKl|d zoYm4$at}i`F?UQunUXzsN=ymn2(}(JOWRW%;2w)?BY~dy1AZO&qzS z#9dk=H+6ASfmF;FI6{!*!D5KPF}A^kKajGAVS`KcuH$;@eUvw;a`AnFgFkH32B%-f z#OS~p_a8$!Zz|zBBX-1l!<_ZMFs$ z9gX=uB9L(N=+J)$5(Nag5hSLFgPW_uviIP>X5-F->h+X;#?pI}=!ZcE^6mp|V$$E6 zsP>Q#TtzPs@wZCo4W$c7(gQ@n;WvUfB3qC_i+C8;kYaFE6(*0UM&Z^{-P-^pr|AZuq}q=gJgmJN7tbi+SOMy*jl;|7iHSNkrU z7VaRm<+y_Thzkv={i&m(W`CN+*vih%f>|ZYKn!W!$Cgt|C;IfsQ@j=nCyJNX6$-ZN z9qB_t5~RF)uNQOxAMRXjcHzief?@Z}o?Tmcv+7hLa_YJA0joaq?JgoAih5*eZoQe> z%h2bTxY&L@Gb*Mu74OW|P{P~Wxne}2{>xLF9Vy?SQP<01qqu4_>0%2b{|)9o=k}jG zzV5;SvgKm#3wR}@zjhHCIXjn07Jz%{u^Pbw%kE`w%Qh+i|DPIZgo-knjLq`uBx#ES zG+JVzhlE`Gu?kY42;63tg@$LUPL*lpb92%ZdWLeG?)cxaRN~i;BS}A%>$%E`J|LOu zo$3LG@>Y?wE zH!yOy+$xo`9` z86NsR#NQBZbN&jOCE<`D?#(Gjtp#7Mehc4bU@%%M1zJ%2cGD4?N7>|+?wRZYu z&lr`YebM>m@=YwBt)czxE>FdI#D2gTUK0wdv3seGd$fe;$;CkK02yFi!nHZin7 z7Y{;5>5d?@@HZ_$B0uzXi}NNV+0p&F7I zH}|V3fd1tNUGnP#_8m)x182A{S^a%Z{M~!Gow!+D2a}yWyRX^a_TU>k?Gl@9WPe+8 z7#*d!ZRQHVN@PpA-K$sd`J<;TReaw32bG1`OCtI^o#V#UHj~?81blBpOa^R}@}2zI z1%^{hAeIsDB>`-NfnzuiFW6FBvC3R&xGkFAr^2FtfJ^AJ%j(=^!C`8(`C7?moF|%o zAA=K|i}J4(E%qonljU5Jf3R)~^=hvkI*v9f7hPomWZG8Ye$TYGg%a=vHiqe_gkKlF zt&<|Q;$3VUS@M~^RLQk^2_FB{*3#!TE@xk+&lXtQ{T$U`qI_g<(I115-opIil3uWZ z3Y%{3%9Yd}iP6u4>-%~$kYZ6qE9}jC2Wza|sv}O$NZ81hq!YaCh^~*hWYdf`Gqjkb zjxE^?NFgE@ke$DnUXefMR`N$#I=mHZi-KzL!jAr0VvFj*JDnO3x=wea&a@(S*X`v+ zPWtCGfZaeaXhuq9bduM!dKDY~cL0aD`Dpj$D5QvEVU6X-Y0<3ONNl8fLBzQ4^JMdM z-I(nI>p-2%1P;<20Vk*c`JW*RZWW2jx3sT8`hPwdAx!i*6})&bb$Lpb!GnP4 zWrKj=c>lccfIkSx0eWBjH5YD04<@dR>Colipip2)q}YGZz^E0%AXr0Fth6T7WwaKdn{0qN*b#S#aMC?)cu5;yUZ{CZ4 zAmB&m`MTd(>p`wx+Ii>o?qMW3ZDHyvFFB~SB#vy$YL8?aQ0u>NWOzW0zC_Src;HJ; z*deicFuM8aLBJ#ixmcIB2vyyXVNhD22CqVf{NYP{;?k9XEiYlmdgP-yIqSZ4s6p{e zg?mnWUol;87b7H{2DE^=Ff~>g4}nFm|!l#9$Cg?9 z?i{J^jTxO%w|N=Y*#-rReM;GV(|gbVT>9O2!gZ@0+&wX{jm2KWqrB$Nlfs=ZJp}bO z6F*aiiaK0~Q+7+Hb!iazOQi`}UdW<$jc>MFt@sra%sp6$wCPQrS--a6@HP1b+|U_Y zT+oj_07SY>cAty=13q=39X|*4=KYy*>?q6@?N29q)(a)aF(y0|GQW_7Bj>p{3mrxc z9N3&9d@k$F`*_ch)4f>~Y90&!;L6x#bCGVjj}1o-d>n@Z3~tsCJr_50Szj!HUL$Ze zxbF?>vYZum1mOTWN2SI0xxE|d8iA{uPX=5qrpzekI$5z@ zB@jGzk!?xEq&@YL>`_tliIlG+3FG8uRd2svc4eXe_O) zY;AXxbvIZ`0H3Bi588@PY6@VfIL8jia5yVd%A1_0{n>BoQaU}&&(0t{{C#w~Qn!#H z>a6ZOg9GrYtuJkLl=Yrk{L>XO*|qO@x-zL3KJL}*?A@Y+KjY-+v@-KEvY>i>avyvO zTh-LyeY*^^tmgG|tCy6`l4FPn&>9RyX{8v74vrrxI;1Nxoltl@sdH33TO6R^)@q&k z6kGj~2D{&JMvjGJprK_yrrg&g?b?8Hm_zYcA(Ze0U52DSNiJC|8GF$1nryQ|uL%_r z77^`*Usl{J6yMZp!7jF#ny)U?iZ&j>7UeLuyy@mXBX0DBd0V8pgvMPBAZ0XKFzX*~ z%)N-2D4B;i5ZZ#94xu@>C5OL~Q$2+$c7Kc!nhjB${maNboV~n)vB2ym&!DiI+sevy zK>dd#$XhS7_wmha1H`Ymh7pf$zLnPbE7|NACF>{%Dk8<7cc$uuA5YM84*|u6CO~g& zY*_wd1Jd!K3|ZvuE>+1SU~1Ffz(Sj5g(S8B+Dm(}OLow1rjPqzO}kY>;?CTt-Meng zx}h+qsjceXMs}45uJWwvobS5|>R^ouiq!0gjs4ZIgHa-NwKG|glUfdJmac|Pal*?h zl30-K@3+*`)osl*T$7B~n{8GOquaW;BP)4!PwA4YbvaI}m0i^`fSnoeB4kU>U-iHw z>xSfIxOi%&NZ@T~cjM|@@li+^u7<^&(G}#WLzP_jHBMF5+N=i>osH|^?zu|dq>x_m z75Z&vS5*G;bKvA|_r*2cn^sKs|VbrTG z=bJvE4wQeRck@cds3>89{5IPMIpval;O#hwz0tOf_t(6&4KBOp1w-K+k4vr|6;wv1 z$)BS7sd?+Zv=$Q9Osbqk*}$fLWEp&vh6MV5sXue#hW)Rve8l%7WwbArv!s@~%xy%kz^nY2Q}WPYpFH zXVNnC<&d*H;<~Er8%wlHSwA-VI>OFj@sE4Bai^}w|In@J3qlns02|gN;ZAZjrmjBF zy+j4F_=UBxnfA|X%g<2Q8!;%D6oYviWl&A?oAA}x0amaazdpfH_s;m>sIn2r7NZ&i z<>2Ppt2Rx|O+5%;;@jYas}~k~>+1+4P_k{k7E|4zrp+bX%uo-k)aFtc#R zu-nXKl%WlkbCYE%X;$m0X<7x%n_cKT5{fFd-yWwt2}~e9u2h7`T(z#L?s= zAdyNl2B0--FbX0xep~fDHP^7mqiwQT4n&@U$^MP6THr|!p}va6E1KVBDi91xLJtYz z6L-baV{2UBg`LKq0+ws=9^RKMj#=p?Y6^}GB7bYj;WFi+Qdi9nt8UEDZ*S@?CZ9%E zax7{ZEk2){lQY%mD-xrD_<%VnF5C^J*W4(`064>SaG#Wh@>02rceQW!C|cSb^iS|{ ziOlCl;h4zdWY*ou|6}#78}u?8@&J)dJL>4+Ja>mX^Muse8crGYq1t`*q1CB|>_$a62PuhCBB84NOp0Q|a{uO4s`KVQk}$<9XembxP89R_p7yfGIoK@4E;tS=e!ye!oqIgSK&}K-c^OSdldo?O|Tl(V1A+Q&Ey*j z(v_&rcyQ!bL9XMlX!eI@-ABAaP(l!5QWr0@8A}r*j~bvw!Ewo~brk&B9Gi4Xj3{o+l!SGiH7BkN{5zD#~7pD%=`HAAg6s0ceDKSs;_ zh~Q#PwsfY#BVCRa3)*tTn_U!(7RLmsJSZeHIL?>}T8=y+?cdR{(#TuNX91d2(}c=L z)ZqeI+2eZWX%Y-vq^29(p6WDn%aXKmWprC*b|20QvEZIKm0EOPR&>M!=~q4$e4T7j zI~mO@9H_*U-ZbfJzQbDwZm4ha&!RVlCIKD zrC=RkX4D^S5XK{$3$*{1O9d!JVOxJ*i)7*CPAtJ55wY?elbK!Gs&#o z?L#Xv?Ni6R!C8#Fb!K~O-h<2s%$}|(!E_%2c%kBZX$Wnt{LNWsIQIA$sB*y|lg-53 zc{!F$wwGlsfz(f#E?#s~664ij0@mqpf>$1i_U?A}Z242wt#zQ{hq8`+h8VmV>J+-d z@PR9J%0%#$T*1+Y=^a4DYoP`pI#-pa+PC5rDL`vMMc{TR`|()$1-10GL<2Bh-hDdX zl3L{diOluT@4hcw;&vydz|IifeMhtx|E%mDZF)+L>qX+0T;eGm_OyLEup~bKeYKm( zCb8hK&09(S3r7RMU^_O#zdQ~@y3_y&mjlZUhlkjXmae?%TT zn5icSAUfhNpdKi=2rUkm$fG@FX#GY;a|bPDcMJe^^J9yAa+*~e9v+Tx~mCK>>j?N%C-X<`0;lCbbpDEAgV*(K6*yGxT`N^2^W$)<{vGDzu z9H0$gej#w68hwUqi-}qiUsPry-l`hTB=v*ppWl?eRI1v0{TY^JR-zLwHSTMQL%+%V zHmP`2xAgImd@RSo79N$tvo?t>S?shBKu6-DV&S^=j5!>n-<+iZacni~DhKZ~_)0mc znJ6gMod!rZCmj5ZVmQ^$Ws-{~ZKk3*!d5Z>SiZFKA{M`f-sUNIr5bH`^%pVaUkA~D z_BAq!gqyVdR~L5~Gg&Lp;Glvl9<=sduXa6;L!5q{xC*(EdYq)WFyIM^N~R0RWVPER z&am*Ql==`>pm=&Nk?udM5r=UZ7uVxgdGL~GSLQ_d^7iFphDb+q-H;R=V(I#E&I`%_ ztSDWd)}Psgc9|+~7h{p-8o&3NiLaZaI>k z)hMS(U}fR1%U@OcD1zITJ99S9 zxvY2a~Azv0P}VE@imzsRx^-M5F7}a_1#3p2kr{P{*I{#y`u>?{!YX&3^_cu0H zr=riSm%zf84Mkfs6AiA`V7WRc6#)}XJ>Po)$ZMNSD5By&6&Zq*Uav>w4l*_5Xig8r9m zYPDnhMk;3Zc>MS&z?zF2wHLSpG~*XXv{2nyXK%#rCWfEn028MVISN4%3qzdEYOu7h zc-!&er`HmMwYU@OOn4vf!8gnQ7gDR!ipn*}Z9|+3^yg;*fa;QUUC=hKNCzf!?eWD~ zRN~ymV+r=B>|qWOq}t=g9>Dul@+KFh)4Sc^N`kG!D+>3M0_Ok{`~%yRXAk#J$Qtaj z=W`&#UL&+-TFw{&`aCI~I8#T0)KJdN%^T&+(+l}Xo!D{c>kDYF9h~AnO7&28uLyHZ zUJDxkbh2;#&T0Vkbb6el)2(pHgwG-at}DKeabfU z=B@UNeIObBjNkj2mZXOg?GLrzdco#Yj%V#i;ykIB%jj2$ z>AgW0#=fN?-N@(}VJY|KFC>U;VVi zyNKg|w)f5ygqi1ue-MB?OjOYCLTjKt6Z5~YK8mS^Y>51z3R20DLyY{!1)B_XrMoSE@up{adN>zr+c&zeF9Qe-r;#*#H5- z^Iz6G76)fyyc0jNs4750;XwaOasF=s;y;>r|F{4J@BIRLAdWHC-w^)Mj`#;LitwF? z``(=(1AZ|^;eLOu|6d;d&BuT^6>nqzPgedL#^1yNTaAf{*8c6XaCUr8+CSZA#>7zX zO%P-gvcEZEF(HOx;{a}|5&IM4e@$w0ekgC9cT);TY=Hsf*Z#ksv2OV8_yBw{mxJ0f`Ac`y!v*?TV8FSU{VS6H E1J4>a^Z)<= delta 10434 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 diff --git a/src/burp/BurpExtender.java b/src/burp/BurpExtender.java index f88e4f7..d74fab4 100644 --- a/src/burp/BurpExtender.java +++ b/src/burp/BurpExtender.java @@ -13,6 +13,8 @@ package burp; import java.awt.Component; +import java.awt.BorderLayout; +import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -21,6 +23,7 @@ import java.util.List; import javax.swing.JButton; +import javax.swing.JComboBox; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -39,7 +42,6 @@ public class BurpExtender implements IBurpExtender, ITab, ActionListener, IExtensionStateListener, IContextMenuFactory { private NotesExtensionOperations ops; - private JButton btnAddText, btnAddSpreadsheet, btnLoadNotes, btnSaveNotes; public final String TAB_NAME = "Notes"; @@ -70,27 +72,62 @@ public void registerExtenderCallbacks(final IBurpExtenderCallbacks Callbacks) public void run(){ //Create our initial UI components ops.tabbedPane = new JTabbedPane(); - JPanel panel = new JPanel(); + JPanel panel = new JPanel(new BorderLayout()); + //Tab Management + ops.tabList = new JComboBox(); + ops.tabList.addItem("Choose..."); + ops.btnSaveTabAsTemplate = new JButton("Export Tab"); + ops.btnSaveTabAsTemplate.setActionCommand(NotesExtensionOperations.COMMAND_SAVE_TAB_AS_TEMPLATE); + ops.btnSaveTabAsTemplate.addActionListener(BurpExtender.this); + ops.btnRemoveTab = new JButton("Remove Tab"); + ops.btnRemoveTab.setActionCommand(NotesExtensionOperations.COMMAND_REMOVE_TAB); + ops.btnRemoveTab.addActionListener(BurpExtender.this); + //Add the save,load, and document buttons - btnAddText = new JButton("Add Text"); - btnAddText.setActionCommand(NotesExtensionOperations.COMMAND_ADD_TEXT); - btnAddText.addActionListener(BurpExtender.this); - btnAddSpreadsheet = new JButton("Add Spreadsheet"); - btnAddSpreadsheet.setActionCommand(NotesExtensionOperations.COMMAND_ADD_SPREADSHEET); - btnAddSpreadsheet.addActionListener(BurpExtender.this); - btnSaveNotes = new JButton("Save Notes"); - btnSaveNotes.setActionCommand(NotesExtensionOperations.COMMAND_SAVE_NOTES); - btnSaveNotes.addActionListener(BurpExtender.this); - btnLoadNotes = new JButton("Load Notes"); - btnLoadNotes.setActionCommand(NotesExtensionOperations.COMMAND_LOAD_NOTES); - btnLoadNotes.addActionListener(BurpExtender.this); + ops.btnAddText = new JButton("New Text"); + ops.btnAddText.setActionCommand(NotesExtensionOperations.COMMAND_ADD_TEXT); + ops.btnAddText.addActionListener(BurpExtender.this); + ops.btnAddSpreadsheet = new JButton("New Spreadsheet"); + ops.btnAddSpreadsheet.setActionCommand(NotesExtensionOperations.COMMAND_ADD_SPREADSHEET); + ops.btnAddSpreadsheet.addActionListener(BurpExtender.this); + ops.btnImportText = new JButton("Import Text"); + ops.btnImportText.setActionCommand(NotesExtensionOperations.COMMAND_IMPORT_TEXT); + ops.btnImportText.addActionListener(BurpExtender.this); + ops.btnImportSpreadsheet = new JButton("Import Spreadsheet"); + ops.btnImportSpreadsheet.setActionCommand(NotesExtensionOperations.COMMAND_IMPORT_SPREADSHEET); + ops.btnImportSpreadsheet.addActionListener(BurpExtender.this); + ops.btnSaveNotes = new JButton("Save Notes"); + ops.btnSaveNotes.setActionCommand(NotesExtensionOperations.COMMAND_SAVE_NOTES); + ops.btnSaveNotes.addActionListener(BurpExtender.this); + ops.btnLoadNotes = new JButton("Load Notes"); + ops.btnLoadNotes.setActionCommand(NotesExtensionOperations.COMMAND_LOAD_NOTES); + ops.btnLoadNotes.addActionListener(BurpExtender.this); //Make our panel with a grid layout for arranging the buttons - panel.setLayout(new GridLayout(3, 3)); - panel.add(btnSaveNotes); - panel.add(btnLoadNotes); - panel.add(btnAddText); - panel.add(btnAddSpreadsheet); + JPanel topPanel = new JPanel(); + topPanel.add(ops.tabList); + topPanel.add(ops.btnSaveTabAsTemplate); + topPanel.add(ops.btnRemoveTab); + topPanel.setPreferredSize(new Dimension(500,100)); + panel.add(topPanel, BorderLayout.PAGE_START); + JPanel spaceLeft = new JPanel(); + spaceLeft.setPreferredSize(new Dimension(300,200)); + panel.add(spaceLeft, BorderLayout.LINE_START); + JPanel buttonPanel = new JPanel(new GridLayout(3,2)); + buttonPanel.add(ops.btnSaveNotes); + buttonPanel.add(ops.btnLoadNotes); + buttonPanel.add(ops.btnAddText); + buttonPanel.add(ops.btnAddSpreadsheet); + buttonPanel.add(ops.btnImportText); + buttonPanel.add(ops.btnImportSpreadsheet); + buttonPanel.setPreferredSize(new Dimension(150,150)); + panel.add(buttonPanel, BorderLayout.CENTER); + JPanel spaceRight = new JPanel(); + spaceRight.setPreferredSize(new Dimension(300,200)); + panel.add(spaceRight, BorderLayout.LINE_END); + JPanel spaceBottom = new JPanel(); + spaceBottom.setPreferredSize(new Dimension(500,250)); + panel.add(spaceBottom, BorderLayout.PAGE_END); ops.tabbedPane.addTab("Main", panel); ops.callbacks.customizeUiComponent(ops.tabbedPane); @@ -122,7 +159,7 @@ public void extensionUnloaded() { //Unloading extension, prompt user to save data if they have any tabs if(ops.tabbedPane.getTabCount() > 1){ Object[] options = {"Yes", "No"}; - int n = JOptionPane.showOptionDialog(getUiComponent(), "Would you like to save your notes?", "Notes Tab", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); + int n = JOptionPane.showOptionDialog(ops.tabbedPane, "Would you like to save your notes?", "Notes Tab", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]); if(n == JOptionPane.YES_OPTION){ ops.SaveNotes(); } diff --git a/src/com/trustwave/burp/ButtonTabComponent.java b/src/com/trustwave/burp/ButtonTabComponent.java index 30ecea6..bf54aa3 100644 --- a/src/com/trustwave/burp/ButtonTabComponent.java +++ b/src/com/trustwave/burp/ButtonTabComponent.java @@ -50,14 +50,16 @@ @SuppressWarnings("serial") public class ButtonTabComponent extends JPanel { private final JTabbedPane pane; + private final NotesExtensionOperations ops; - public ButtonTabComponent(final JTabbedPane pane) { + public ButtonTabComponent(final JTabbedPane pane, final NotesExtensionOperations ops) { //unset default FlowLayout' gaps super(new FlowLayout(FlowLayout.LEFT, 0, 0)); if (pane == null) { throw new NullPointerException("TabbedPane is null"); } this.pane = pane; + this.ops = ops; setOpaque(false); //make JLabel read titles from JTabbedPane @@ -105,11 +107,7 @@ public TabButton() { public void actionPerformed(ActionEvent e) { int i = pane.indexOfTabComponent(ButtonTabComponent.this); if (i != -1) { - Object[] options = {"OK", "Cancel"}; - int n = JOptionPane.showOptionDialog(pane, "If you close this tab you will lose any unsaved data.", "Notes Tab", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); - if(n == JOptionPane.OK_OPTION){ - pane.remove(i); - } + ops.RemoveTab(i); } } diff --git a/src/com/trustwave/burp/NotesExtensionOperations.java b/src/com/trustwave/burp/NotesExtensionOperations.java index ef81fa3..bdabb61 100644 --- a/src/com/trustwave/burp/NotesExtensionOperations.java +++ b/src/com/trustwave/burp/NotesExtensionOperations.java @@ -16,6 +16,8 @@ import java.awt.event.ActionListener; import java.io.File; import java.io.FileReader; +import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; @@ -24,6 +26,7 @@ import java.util.List; import javax.swing.JButton; +import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JMenu; import javax.swing.JMenuItem; @@ -47,17 +50,26 @@ public class NotesExtensionOperations{ public IExtensionHelpers helpers; public PrintWriter stdout, errout; public JTabbedPane tabbedPane; - public JButton btnAddText, btnAddSpreadsheet, btnLoadNotes, btnSaveNotes; + public JComboBox tabList; + public JButton btnAddText, btnAddSpreadsheet, btnImportText, btnImportSpreadsheet, btnLoadNotes, btnSaveNotes, btnSaveTabAsTemplate, btnRemoveTab; public HashMap tabTypes; public IHttpRequestResponse[] messages; public byte selectedContext; + public ArrayList spreadsheetTemplateFile; + public String textTemplateFile; //KEYWORDS public static final String COMMAND_ADD_TEXT = "addText"; public static final String COMMAND_ADD_SPREADSHEET = "addSpreadsheet"; + public static final String COMMAND_IMPORT_TEXT = "importText"; + public static final String COMMAND_IMPORT_SPREADSHEET = "importSpreadsheet"; public static final String COMMAND_LOAD_NOTES = "loadNotes"; public static final String COMMAND_SAVE_NOTES = "saveNotes"; public static final String COMMAND_ADD_NEW_TEXT = "newTextDoc"; + public static final String COMMAND_SAVE_TAB_AS_TEMPLATE = "saveTabAsTemplate"; + public static final String COMMAND_REMOVE_TAB = "removeTab"; + public static final int TEMPLATE_TEXT = 1; + public static final int TEMPLATE_SPREADSHEET = 2; //Constructor /** @@ -75,8 +87,9 @@ public NotesExtensionOperations(IBurpExtenderCallbacks Callbacks){ * @param saveFile True - Show a Save Dialog. False - Show a Load Dialog. * @return The File chosen by the user. */ - public File GetFileFromDialog(boolean saveFile){ + public File GetFileFromDialog(boolean saveFile, String defaultName){ JFileChooser fc = new JFileChooser(); + if(defaultName != "") fc.setSelectedFile(new File(defaultName)); int returnVal; if(saveFile) returnVal = fc.showSaveDialog(tabbedPane); else returnVal = fc.showOpenDialog(tabbedPane); @@ -110,7 +123,7 @@ public void SaveNotes(){ ArrayList data = GetNotesData(); if(data.size() > 0) { File f; - if((f = GetFileFromDialog(true)) != null){ + if((f = GetFileFromDialog(true, "notes.txt")) != null){ try{ //Create our various Writers FileWriter fw = new FileWriter(f); @@ -135,7 +148,7 @@ public void LoadNotes(){ //Now pick file to load File file; try { - if((file = GetFileFromDialog(false)) != null){ + if((file = GetFileFromDialog(false, "")) != null){ ArrayList spreadData = new ArrayList(); if(file.exists() && file.isFile() && file.canRead()){ CSVReader reader = new CSVReader(new FileReader(file)); @@ -232,6 +245,7 @@ public void SetNotesData(ArrayList data){ //Start text object inText = true; inTitle = true; + current = ""; } else if(nextLine[j].equals("ENDTEXT")){ //End of text object, create the new textArea and add the tab inText = false; @@ -260,7 +274,7 @@ public void SetNotesData(ArrayList data){ inTitle = false; } else { spreadData.add(nextLine); - i = nextLine.length; //End this loop early, we are taking the whole line + j = nextLine.length; //End this loop early, we are taking the whole line } } } @@ -285,8 +299,10 @@ public Component GetInnerComponent(int tabIndex){ /** * Add a blank text tab to the Tabbed Pane. Will prompt the user for a name. */ - public void AddTextTab(){ - AddTextTab(""); + public void AddTextTab(boolean importFile){ + if(importFile) promptUseTemplate(TEMPLATE_TEXT); + if(textTemplateFile != null) AddTextTab(textTemplateFile); + else AddTextTab(""); } /** @@ -309,6 +325,8 @@ public void AddTextTab(String text, String name){ //Create a JTextArea for displaying plain text JTextArea newText = new JTextArea(5,30); newText.setText(text); + //Clear template for next file if it was used + textTemplateFile = null; //Set it in a scroll pane JScrollPane scrollWindow = new JScrollPane(newText); scrollWindow.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); @@ -318,16 +336,19 @@ public void AddTextTab(String text, String name){ newText.setBounds(tabbedPane.getBounds()); //Mark the tab as a TEXT tab tabTypes.put(name, "TEXT"); + tabList.addItem(name); tabbedPane.addTab(name, scrollWindow); - tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, new ButtonTabComponent(tabbedPane)); + tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, new ButtonTabComponent(tabbedPane, this)); } /** * Add a new blank spreadsheet to the Tabbed Pane. Will prompt the user for a name. */ - public void AddSpreadsheetTab(){ - AddSpreadsheetTab(null); + public void AddSpreadsheetTab(boolean importFile){ + if(importFile) promptUseTemplate(TEMPLATE_SPREADSHEET); + if(spreadsheetTemplateFile != null) AddSpreadsheetTab(spreadsheetTemplateFile); + else AddSpreadsheetTab(null); } /** @@ -373,8 +394,12 @@ public void AddSpreadsheetTab(ArrayList data, String name){ //Set this tab as a spreadsheet tabTypes.put(name, "SPREADSHEET"); + tabList.addItem(name); tabbedPane.addTab(name, scrollWindow); - tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, new ButtonTabComponent(tabbedPane)); + tabbedPane.setTabComponentAt(tabbedPane.getTabCount() - 1, new ButtonTabComponent(tabbedPane, this)); + + //Make sure the template is null at this point for the next new tab + spreadsheetTemplateFile = null; } /** @@ -401,11 +426,163 @@ public String getTabName(){ String newName = ""; while(newName == "" || tabTypes.containsKey(newName)) { - newName = JOptionPane.showInputDialog("Please enter a unique name for the document:"); + newName = JOptionPane.showInputDialog(tabbedPane, "Please enter a unique name for the document:"); } return newName; } + /** + * Prompt the user to choose a template file for a new spreadsheet. + * @return The name entered by the user. + */ + public void promptUseTemplate(int templateType){ + //Pick a file to import and fill in a new tab + File file; + try { + if(templateType == TEMPLATE_TEXT){ + if((file = GetFileFromDialog(false, "TEMPLATE.txt")) != null){ + textTemplateFile = ""; + if(file.exists() && file.isFile() && file.canRead()){ + FileReader input = new FileReader(file); + BufferedReader br = new BufferedReader(input); + String strLine; + //Read File Line By Line + while ((strLine = br.readLine()) != null) { + // Print the content on the console + textTemplateFile += strLine + "\n"; + } + //Close the input stream + br.close(); + } + } + } else if(templateType == TEMPLATE_SPREADSHEET){ + if((file = GetFileFromDialog(false, "TEMPLATE.csv")) != null){ + spreadsheetTemplateFile = new ArrayList(); + if(file.exists() && file.isFile() && file.canRead()){ + CSVReader reader = new CSVReader(new FileReader(file)); + String[] nextLine; + while((nextLine = reader.readNext()) != null){ + spreadsheetTemplateFile.add(nextLine); + } + reader.close(); + } + } + } + } catch (IOException exc) { + errout.println(exc.getMessage()); + } + } + + /** + * Remove the tab at the specified index + * @param index The index of the tab to remove. + */ + public void RemoveTab(int index){ + Object[] options = {"OK", "Cancel"}; + int n = JOptionPane.showOptionDialog(tabbedPane, "If you close this tab you will lose any unsaved data.", "Notes Tab", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); + if(n == JOptionPane.OK_OPTION){ + String name = tabbedPane.getTitleAt(index); + tabList.removeItem(name); + tabTypes.remove(name); + tabbedPane.remove(index); + } + } + + public void ClearAllTabs(){ + Object[] options = {"Yes", "No"}; + int n = JOptionPane.showOptionDialog(tabbedPane, "Do you want to clear all open tabs?", "Notes Tab", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); + if(n == JOptionPane.YES_OPTION){ + for(int i = tabbedPane.getTabCount() - 1; i > 0; i--){ + String name = tabbedPane.getTitleAt(i); + tabList.removeItem(name); + tabTypes.remove(name); + tabbedPane.remove(i); + } + } + } + + /** + * Save the content of the spreadsheet tab as a template CSV + * @param index The index of the tab to save. + */ + public void ExportTab(int index){ + String name = tabbedPane.getTitleAt(index); + String type = tabTypes.get(name); + if(type == "SPREADSHEET"){ + ExportSpreadsheetTab(index); + } else if(type == "TEXT"){ + ExportTextTab(index); + } + } + + public void ExportTextTab(int index){ + //Text tab + JTextArea textTab = (JTextArea) GetInnerComponent(index); + + if(textTab != null){ + //Text + String data = textTab.getText(); + + if(data != null ){ + File f; + if((f = GetFileFromDialog(true, "TEMPLATE.txt")) != null){ + try{ + // Create file + FileWriter fstream = new FileWriter(f); + BufferedWriter out = new BufferedWriter(fstream); + out.write(data); + //Close the output stream + out.close(); + } catch (Exception exc){//Catch exception if any + errout.println(exc.getMessage()); + } + } + } + } + } + + public void ExportSpreadsheetTab(int index){ + stdout.println("Exporting Tab Data"); + //ArrayList to store data we will write out + ArrayList data = new ArrayList(); + JTable table = (JTable) GetInnerComponent(index); + + if(table != null){ + //Data + int numColumns = table.getColumnCount(); + String[] row; + // Write cell data + for(int i=0;i 0) { + File f; + if((f = GetFileFromDialog(true, "TEMPLATE.csv")) != null){ + try{ + //Create our various Writers + FileWriter fw = new FileWriter(f); + CSVWriter writer = new CSVWriter(fw); + //Write out to file and close + writer.writeAll(data); + writer.close(); + fw.close(); + } catch(IOException exc){ + errout.println(exc.getMessage()); + } + } + } else { + //No notes could be found + } + } + } + //CONTEXT MENU OPERATIONS /** * Create menu items for a context menu on behalf of the Burp Extension's createMenuItems(). @@ -481,14 +658,24 @@ public static JMenuItem CreateMenuItem(String name, String command, ActionListen */ public void ParseAction(String cmd){ if(cmd.equals(COMMAND_ADD_TEXT)){ - AddTextTab(); + AddTextTab(false); } else if(cmd.equals(COMMAND_ADD_SPREADSHEET)){ - AddSpreadsheetTab(); + AddSpreadsheetTab(false); + } else if(cmd.equals(COMMAND_IMPORT_TEXT)){ + AddTextTab(true); + } else if(cmd.equals(COMMAND_IMPORT_SPREADSHEET)){ + AddSpreadsheetTab(true); } else if(cmd.equals(COMMAND_SAVE_NOTES)){ SaveNotes(); } else if(cmd.equals(COMMAND_LOAD_NOTES)){ + if(tabbedPane.getTabCount() > 1) ClearAllTabs(); LoadNotes(); - } else { + } else if(cmd.equals(COMMAND_SAVE_TAB_AS_TEMPLATE)){ + if(tabList.getSelectedIndex() > 0) ExportTab(tabList.getSelectedIndex()); + } else if(cmd.equals(COMMAND_REMOVE_TAB)){ + if(tabList.getSelectedIndex() > 0) RemoveTab(tabList.getSelectedIndex()); + } + else { ParseConCommand(cmd); } }