Compare commits
	
		
			369 Commits
		
	
	
		
			1.09d-r0
			...
			v1.09e-r5b
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					554f88c723 | ||
| 
						 | 
					4cd32d30c6 | ||
| 
						 | 
					d0da83182f | ||
| 
						 | 
					ec5f26e0cd | ||
| 
						 | 
					6110166af8 | ||
| 
						 | 
					6f10a04589 | ||
| 
						 | 
					e0c003fcb2 | ||
| 
						 | 
					944f44bc4b | ||
| 
						 | 
					58047d5386 | ||
| 
						 | 
					c0a06c9f3a | ||
| 
						 | 
					d0c041a0e2 | ||
| 
						 | 
					df060e2f4b | ||
| 
						 | 
					aea55dad45 | ||
| 
						 | 
					5442dbf441 | ||
| 
						 | 
					317476d9b5 | ||
| 
						 | 
					ad0acb7a69 | ||
| 
						 | 
					b66ae5d264 | ||
| 
						 | 
					d87706fa43 | ||
| 
						 | 
					cb25d12709 | ||
| 
						 | 
					dce536009e | ||
| 
						 | 
					656e785214 | ||
| 
						 | 
					35d50a6eb0 | ||
| 
						 | 
					786bb646c2 | ||
| 
						 | 
					72cc6ff768 | ||
| 
						 | 
					404e07e5c0 | ||
| 
						 | 
					1c7159ede9 | ||
| 
						 | 
					2378cd0d7c | ||
| 
						 | 
					b149bab761 | ||
| 
						 | 
					5ebd8e5e33 | ||
| 
						 | 
					db6b266a59 | ||
| 
						 | 
					7de28c5aba | ||
| 
						 | 
					ed79df0c6d | ||
| 
						 | 
					4949fede32 | ||
| 
						 | 
					bddef6442c | ||
| 
						 | 
					48a6d0a2ad | ||
| 
						 | 
					ac5f3c9ca5 | ||
| 
						 | 
					93e1cf1147 | ||
| 
						 | 
					a805787a95 | ||
| 
						 | 
					85315d0ecc | ||
| 
						 | 
					595a451f77 | ||
| 
						 | 
					914224e4fa | ||
| 
						 | 
					e350e8788c | ||
| 
						 | 
					ca5f6dc43c | ||
| 
						 | 
					0d4955622d | ||
| 
						 | 
					886daa6b27 | ||
| 
						 | 
					8fa0803474 | ||
| 
						 | 
					4cad70e750 | ||
| 
						 | 
					c29b789a2b | ||
| 
						 | 
					cd34896661 | ||
| 
						 | 
					1e02db86d6 | ||
| 
						 | 
					994741cbf5 | ||
| 
						 | 
					58844be6eb | ||
| 
						 | 
					2d899fa067 | ||
| 
						 | 
					060bf6a6ee | ||
| 
						 | 
					890f1bd704 | ||
| 
						 | 
					139abcaec6 | ||
| 
						 | 
					78a48b75b8 | ||
| 
						 | 
					3918b06b1f | ||
| 
						 | 
					40847ebe31 | ||
| 
						 | 
					34cac86a9b | ||
| 
						 | 
					d8598a53e0 | ||
| 
						 | 
					92d9eb1512 | ||
| 
						 | 
					1be7b33f6b | ||
| 
						 | 
					8464fa4f29 | ||
| 
						 | 
					eff9a96bd5 | ||
| 
						 | 
					bd4e321b0e | ||
| 
						 | 
					47aaedbfb5 | ||
| 
						 | 
					3043f8981d | ||
| 
						 | 
					cfd413f1f4 | ||
| 
						 | 
					30df03eec6 | ||
| 
						 | 
					5048f63204 | ||
| 
						 | 
					7557c0b9fd | ||
| 
						 | 
					9346f6bb32 | ||
| 
						 | 
					23d7efff53 | ||
| 
						 | 
					c7eb2bf873 | ||
| 
						 | 
					632121f3ec | ||
| 
						 | 
					f7feddcf1f | ||
| 
						 | 
					e745fee6e2 | ||
| 
						 | 
					bcc17d91bd | ||
| 
						 | 
					8c8a8e3968 | ||
| 
						 | 
					3c41550404 | ||
| 
						 | 
					76107b1207 | ||
| 
						 | 
					bb0c13b9d8 | ||
| 
						 | 
					405166ba9d | ||
| 
						 | 
					f5cb60770e | ||
| 
						 | 
					9958a73d4a | ||
| 
						 | 
					fd287b8da7 | ||
| 
						 | 
					9bea5b13e3 | ||
| 
						 | 
					aa6a728e8c | ||
| 
						 | 
					1c8431a3f9 | ||
| 
						 | 
					6a0eacd8f1 | ||
| 
						 | 
					d27976b737 | ||
| 
						 | 
					f312b50f0c | ||
| 
						 | 
					deb169fece | ||
| 
						 | 
					2df656211d | ||
| 
						 | 
					c86f9b3a4f | ||
| 
						 | 
					1c517dceb8 | ||
| 
						 | 
					bede68b60a | ||
| 
						 | 
					8ab7fe84dd | ||
| 
						 | 
					305946b552 | ||
| 
						 | 
					f1fdfa5205 | ||
| 
						 | 
					c1f7460c3e | ||
| 
						 | 
					1f92e449f5 | ||
| 
						 | 
					50aec43b38 | ||
| 
						 | 
					dc75565d7c | ||
| 
						 | 
					91b59c7c9f | ||
| 
						 | 
					e42b4c9654 | ||
| 
						 | 
					d6486d4b98 | ||
| 
						 | 
					5bdf93633f | ||
| 
						 | 
					81f582bb8b | ||
| 
						 | 
					7ba6a44888 | ||
| 
						 | 
					187d4c8f41 | ||
| 
						 | 
					58b0b666ce | ||
| 
						 | 
					8393694e6c | ||
| 
						 | 
					b99f82d3d7 | ||
| 
						 | 
					dfbfeb3fa3 | ||
| 
						 | 
					3c9a8341ae | ||
| 
						 | 
					8f69a60307 | ||
| 
						 | 
					14c2e64e2f | ||
| 
						 | 
					554338012e | ||
| 
						 | 
					3185cf1a9c | ||
| 
						 | 
					ed91d0db0b | ||
| 
						 | 
					dd7cb0a088 | ||
| 
						 | 
					874e1dbae8 | ||
| 
						 | 
					649c0739f6 | ||
| 
						 | 
					3db5ea4713 | ||
| 
						 | 
					96b5e1c10e | ||
| 
						 | 
					2bf5222505 | ||
| 
						 | 
					24d6909297 | ||
| 
						 | 
					1c3f4106dd | ||
| 
						 | 
					4b3f6657a8 | ||
| 
						 | 
					fd75737331 | ||
| 
						 | 
					195cdb8ad7 | ||
| 
						 | 
					a8e519660b | ||
| 
						 | 
					54047e8a26 | ||
| 
						 | 
					e84c5bacb1 | ||
| 
						 | 
					48037d667c | ||
| 
						 | 
					41682aab0a | ||
| 
						 | 
					9561c99711 | ||
| 
						 | 
					1fd538999f | ||
| 
						 | 
					a4396af352 | ||
| 
						 | 
					d7c403cf30 | ||
| 
						 | 
					089eb9bcb2 | ||
| 
						 | 
					178383d549 | ||
| 
						 | 
					f6e6d0e59c | ||
| 
						 | 
					30c1cc1e3f | ||
| 
						 | 
					e7f579862f | ||
| 
						 | 
					22fc984432 | ||
| 
						 | 
					33b3c78676 | ||
| 
						 | 
					0052641b86 | ||
| 
						 | 
					b5b67ed6c4 | ||
| 
						 | 
					08e0b6e72d | ||
| 
						 | 
					6e23b1ef22 | ||
| 
						 | 
					e0da7c6bf5 | ||
| 
						 | 
					138bd8adef | ||
| 
						 | 
					ab527368c0 | ||
| 
						 | 
					335c53360d | ||
| 
						 | 
					7b31f6ec5a | ||
| 
						 | 
					63a8791752 | ||
| 
						 | 
					e3ce7fe95a | ||
| 
						 | 
					ce6556496e | ||
| 
						 | 
					eab5e22c8c | ||
| 
						 | 
					827905e690 | ||
| 
						 | 
					7fe407d25e | ||
| 
						 | 
					b9d0f56e0f | ||
| 
						 | 
					5d06a8b62a | ||
| 
						 | 
					39c1f671d4 | ||
| 
						 | 
					4eb8c77304 | ||
| 
						 | 
					c933748077 | ||
| 
						 | 
					3347722d6d | ||
| 
						 | 
					56c35ac573 | ||
| 
						 | 
					68a61dfcd8 | ||
| 
						 | 
					664c260b99 | ||
| 
						 | 
					a07ce67c95 | ||
| 
						 | 
					6cd71b2bf5 | ||
| 
						 | 
					eb3001a57d | ||
| 
						 | 
					cfd44501d4 | ||
| 
						 | 
					62f7592e1d | ||
| 
						 | 
					5b07f5d726 | ||
| 
						 | 
					3c7cdd150a | ||
| 
						 | 
					3bafb4e022 | ||
| 
						 | 
					477bb87322 | ||
| 
						 | 
					6584303cdf | ||
| 
						 | 
					cbcb72158e | ||
| 
						 | 
					43c8c7d243 | ||
| 
						 | 
					9d31559916 | ||
| 
						 | 
					3483654830 | ||
| 
						 | 
					a74b162e37 | ||
| 
						 | 
					52dd73fa9f | ||
| 
						 | 
					548b92ffe9 | ||
| 
						 | 
					1df84ae7a3 | ||
| 
						 | 
					ba40179c82 | ||
| 
						 | 
					1add52a459 | ||
| 
						 | 
					2f105d30fd | ||
| 
						 | 
					e473940c26 | ||
| 
						 | 
					5f836c381f | ||
| 
						 | 
					7282fdae0b | ||
| 
						 | 
					df2a7412d3 | ||
| 
						 | 
					ae4cdeedbf | ||
| 
						 | 
					fe6115aefb | ||
| 
						 | 
					414dfa57b2 | ||
| 
						 | 
					193a39390c | ||
| 
						 | 
					43455959e2 | ||
| 
						 | 
					2d0e142a79 | ||
| 
						 | 
					27714c0cdf | ||
| 
						 | 
					37db758ee5 | ||
| 
						 | 
					faccbc10e5 | ||
| 
						 | 
					748bd493c4 | ||
| 
						 | 
					8616956df1 | ||
| 
						 | 
					e0da5470e2 | ||
| 
						 | 
					27e237c5e9 | ||
| 
						 | 
					22d4ebbea4 | ||
| 
						 | 
					586b7fc389 | ||
| 
						 | 
					63f6c1e5cf | ||
| 
						 | 
					2c128794ac | ||
| 
						 | 
					cf0e8a1926 | ||
| 
						 | 
					06bd468658 | ||
| 
						 | 
					7b6ff73fb9 | ||
| 
						 | 
					54231b23f3 | ||
| 
						 | 
					77ee958587 | ||
| 
						 | 
					69137b2212 | ||
| 
						 | 
					208f080bd2 | ||
| 
						 | 
					34b738e2fe | ||
| 
						 | 
					1664171794 | ||
| 
						 | 
					5690ff6c99 | ||
| 
						 | 
					e7a43ab7a6 | ||
| 
						 | 
					96fcc79c93 | ||
| 
						 | 
					b99272e850 | ||
| 
						 | 
					b04aba7644 | ||
| 
						 | 
					cef13eafa0 | ||
| 
						 | 
					37befe2c46 | ||
| 
						 | 
					dd84af3bfc | ||
| 
						 | 
					65a4d64925 | ||
| 
						 | 
					0b2d62917a | ||
| 
						 | 
					9fc7dca138 | ||
| 
						 | 
					b50c7e6cf6 | ||
| 
						 | 
					944bce14b8 | ||
| 
						 | 
					269952ee67 | ||
| 
						 | 
					d1ccd16987 | ||
| 
						 | 
					78a7c79376 | ||
| 
						 | 
					41c66ecb28 | ||
| 
						 | 
					b2f21094b5 | ||
| 
						 | 
					32666a0d86 | ||
| 
						 | 
					61afc4ed58 | ||
| 
						 | 
					9904946ce2 | ||
| 
						 | 
					78f76054ad | ||
| 
						 | 
					6e71b3fb66 | ||
| 
						 | 
					37a8b51a5f | ||
| 
						 | 
					02a43799a7 | ||
| 
						 | 
					a5994ebe63 | ||
| 
						 | 
					7319652db7 | ||
| 
						 | 
					35f91fd842 | ||
| 
						 | 
					801fd86db5 | ||
| 
						 | 
					afb376a3bc | ||
| 
						 | 
					3baaef19d4 | ||
| 
						 | 
					2e0e0c1d86 | ||
| 
						 | 
					c091c5aeda | ||
| 
						 | 
					74dd3b67e2 | ||
| 
						 | 
					2b3d090fd6 | ||
| 
						 | 
					d875f3fb2f | ||
| 
						 | 
					92f90eddc7 | ||
| 
						 | 
					3feae3b211 | ||
| 
						 | 
					03855a604a | ||
| 
						 | 
					b88000a5b4 | ||
| 
						 | 
					136ba783c8 | ||
| 
						 | 
					df6fb03245 | ||
| 
						 | 
					9509f5ae52 | ||
| 
						 | 
					c69177be6f | ||
| 
						 | 
					daaa7d4016 | ||
| 
						 | 
					d6914456dc | ||
| 
						 | 
					4c3efb6b52 | ||
| 
						 | 
					f6193103e2 | ||
| 
						 | 
					68a78c32e3 | ||
| 
						 | 
					241ea648ee | ||
| 
						 | 
					a7a4e45c8b | ||
| 
						 | 
					0b17c5dcda | ||
| 
						 | 
					60b79a9b8a | ||
| 
						 | 
					9dfd8bbadf | ||
| 
						 | 
					7bfd80a122 | ||
| 
						 | 
					8b6c6707c7 | ||
| 
						 | 
					d1ee19243f | ||
| 
						 | 
					3aca98d1e2 | ||
| 
						 | 
					b76c6063b0 | ||
| 
						 | 
					584b4321ca | ||
| 
						 | 
					b499d12768 | ||
| 
						 | 
					246f6f8132 | ||
| 
						 | 
					e07a350159 | ||
| 
						 | 
					ac05f5c93c | ||
| 
						 | 
					41cec5ffc3 | ||
| 
						 | 
					f5ca01c529 | ||
| 
						 | 
					6b115616b7 | ||
| 
						 | 
					611efe05ca | ||
| 
						 | 
					9e3d30e81e | ||
| 
						 | 
					ba20fd79e0 | ||
| 
						 | 
					37e6ea89b7 | ||
| 
						 | 
					a8457067b3 | ||
| 
						 | 
					6e82ca9ac2 | ||
| 
						 | 
					57a6e4f175 | ||
| 
						 | 
					7621ae0c98 | ||
| 
						 | 
					70b87adf62 | ||
| 
						 | 
					55e6bd42b1 | ||
| 
						 | 
					b5711591d5 | ||
| 
						 | 
					f29463ef6d | ||
| 
						 | 
					18b623548a | ||
| 
						 | 
					6c394c22da | ||
| 
						 | 
					738f9e7547 | ||
| 
						 | 
					d885fddfe6 | ||
| 
						 | 
					95a1713c8a | ||
| 
						 | 
					6661ffb580 | ||
| 
						 | 
					99b7a6ccf7 | ||
| 
						 | 
					c63865f043 | ||
| 
						 | 
					a00312df84 | ||
| 
						 | 
					9ec3374240 | ||
| 
						 | 
					81c8e17333 | ||
| 
						 | 
					cf576dcbfd | ||
| 
						 | 
					3cbaa09769 | ||
| 
						 | 
					89f795e953 | ||
| 
						 | 
					86c9ab40cf | ||
| 
						 | 
					681a7d17d5 | ||
| 
						 | 
					5a1d0ea51b | ||
| 
						 | 
					9aa3c02907 | ||
| 
						 | 
					0cfdfed476 | ||
| 
						 | 
					a205614d65 | ||
| 
						 | 
					db27bcbbe7 | ||
| 
						 | 
					943430cfce | ||
| 
						 | 
					6c55d2aec6 | ||
| 
						 | 
					7d3ecaca7e | ||
| 
						 | 
					f2e8de6938 | ||
| 
						 | 
					26090e87b3 | ||
| 
						 | 
					af82d9fec1 | ||
| 
						 | 
					86defbb144 | ||
| 
						 | 
					d0a5557807 | ||
| 
						 | 
					74788c77e0 | ||
| 
						 | 
					f77bdc4b9c | ||
| 
						 | 
					7f659178c5 | ||
| 
						 | 
					b67e8e6c85 | ||
| 
						 | 
					df4e7c0774 | ||
| 
						 | 
					8d5882cb81 | ||
| 
						 | 
					d540fda5b0 | ||
| 
						 | 
					d39957b8ca | ||
| 
						 | 
					7160bcc33f | ||
| 
						 | 
					36d8a0aa8d | ||
| 
						 | 
					0dec97fad1 | ||
| 
						 | 
					9da08e94ac | ||
| 
						 | 
					62b3fe61b6 | ||
| 
						 | 
					f2775fe0f0 | ||
| 
						 | 
					135168c1bb | ||
| 
						 | 
					6213c753fe | ||
| 
						 | 
					3f1b23dc82 | ||
| 
						 | 
					dda76323c6 | ||
| 
						 | 
					c41128401d | ||
| 
						 | 
					9a5fe131cd | ||
| 
						 | 
					e45fe2f279 | ||
| 
						 | 
					4698a948cc | ||
| 
						 | 
					35501c4c48 | ||
| 
						 | 
					dc28e5708d | ||
| 
						 | 
					d4f3f69129 | ||
| 
						 | 
					936bc7ed72 | ||
| 
						 | 
					8a59fbdb41 | ||
| 
						 | 
					76c6f56d73 | ||
| 
						 | 
					21b0c63422 | ||
| 
						 | 
					b447d2e5ad | ||
| 
						 | 
					f1de28e6c1 | ||
| 
						 | 
					2336255763 | ||
| 
						 | 
					a3022963c0 | ||
| 
						 | 
					396a035cfd | ||
| 
						 | 
					2001fd26f8 | ||
| 
						 | 
					9daf2d0448 | ||
| 
						 | 
					b2d14ff400 | 
							
								
								
									
										351
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										351
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,351 @@
 | 
			
		||||
name: Build keepass2android app
 | 
			
		||||
 | 
			
		||||
on: [push, pull_request]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  # macos:
 | 
			
		||||
  # Disabled. Does not work, maybe due to nuget version, see https://github.com/PhilippC/keepass2android/actions/runs/4297640426/jobs/7490853348
 | 
			
		||||
  # should work again when the Project solution is converted to sdk style .csproj files.
 | 
			
		||||
 | 
			
		||||
  #   runs-on: macos-12
 | 
			
		||||
 | 
			
		||||
  #   steps:
 | 
			
		||||
  #   - uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
  #   - name: Fetch submodules
 | 
			
		||||
  #     run: git submodule init && git submodule update
 | 
			
		||||
 | 
			
		||||
  #   - name: Setup Gradle
 | 
			
		||||
  #     uses: gradle/gradle-build-action@v2
 | 
			
		||||
 | 
			
		||||
  #   - name: Cache NuGet packages
 | 
			
		||||
  #     uses: actions/cache@v3
 | 
			
		||||
  #     with:
 | 
			
		||||
  #       path: ~/.nuget/packages
 | 
			
		||||
  #       key: ${{ runner.os }}-nuget-${{ hashFiles('src/**/*.csproj', 'src/**/packages.config') }}
 | 
			
		||||
  #       restore-keys: |
 | 
			
		||||
  #         ${{ runner.os }}-nuget-
 | 
			
		||||
 | 
			
		||||
  #   # As per https://github.com/actions/runner-images/blob/main/images/macos/macos-12-Readme.md#visual-studio-for-mac
 | 
			
		||||
  #   - name: Switch to Visual Studio 2019
 | 
			
		||||
  #     if: ${{ false }} # Not needed. We stay with the default 'Visual Studio 2022' of macos-12 runner.
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       mv "/Applications/Visual Studio.app" "/Applications/Visual Studio 2022.app"
 | 
			
		||||
  #       mv "/Applications/Visual Studio 2019.app" "/Applications/Visual Studio.app"
 | 
			
		||||
 | 
			
		||||
  #   # As of 2022-12-02, keepass2android doesn't build with Xamarin >= 12.1 because there is some issue with SamsungPass. Removing SamsungPass would make the build succeed.
 | 
			
		||||
  #   - name: Set default Xamarin SDK versions
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       # If using the github runner 'macos-12'
 | 
			
		||||
  #       #$VM_ASSETS/select-xamarin-sdk-v2.sh --mono=6.12 --android=11.3
 | 
			
		||||
  #       #$VM_ASSETS/select-xamarin-sdk-v2.sh --mono=6.12 --android=12.0
 | 
			
		||||
  #       #$VM_ASSETS/select-xamarin-sdk-v2.sh --mono=6.12 --android=12.1 # Build fails in this case, as of 2022-12-02 : Xamarin/Android/Xamarin.Android.D8.targets(79,5): error : java.lang.ArrayIndexOutOfBoundsException :  Index 4 out of bounds for length 4
 | 
			
		||||
  #       #$VM_ASSETS/select-xamarin-sdk-v2.sh --mono=6.12 --android=12.2 # Build fails in this case, as of 2022-12-02 : Xamarin/Android/Xamarin.Android.D8.targets(79,5): error : java.lang.ArrayIndexOutOfBoundsException :  Index 4 out of bounds for length 4
 | 
			
		||||
  #       #$VM_ASSETS/select-xamarin-sdk-v2.sh --mono=6.12 --android=12.3 # Build fails in this case, as of 2022-12-02
 | 
			
		||||
  #       $VM_ASSETS/select-xamarin-sdk-v2.sh --mono=6.12 --android=13.1
 | 
			
		||||
 | 
			
		||||
  #       # If using the github runner 'macos-11'
 | 
			
		||||
  #       #$VM_ASSETS/select-xamarin-sdk-v2.sh --mono=6.12 --android=11.0
 | 
			
		||||
  #       #$VM_ASSETS/select-xamarin-sdk-v2.sh --mono=6.12 --android=12.0
 | 
			
		||||
 | 
			
		||||
  #       # If using the github runner 'macos-10.15'
 | 
			
		||||
  #       # $VM_ASSETS/select-xamarin-sdk-v2.sh --mono=6.12 --android=11.2
 | 
			
		||||
 | 
			
		||||
  #   - name: Switch to JDK-11
 | 
			
		||||
  #     uses: actions/setup-java@v3
 | 
			
		||||
  #     with:
 | 
			
		||||
  #       java-version: '11'
 | 
			
		||||
  #       distribution: 'temurin'
 | 
			
		||||
 | 
			
		||||
  #   - name: Display java version
 | 
			
		||||
  #     run: java -version
 | 
			
		||||
 | 
			
		||||
  #   # Some components of Keepass2Android currently target android API 26 which are not available on the runner
 | 
			
		||||
  #   - name: Download android-26 API
 | 
			
		||||
  #     run: $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --install "platforms;android-26"
 | 
			
		||||
 | 
			
		||||
  #   - name: Build native dependencies
 | 
			
		||||
  #     run: make native
 | 
			
		||||
 | 
			
		||||
  #   - name: Build java dependencies
 | 
			
		||||
  #     run: make java
 | 
			
		||||
 | 
			
		||||
  #   - name: Install NuGet dependencies (net)
 | 
			
		||||
  #     run: make nuget Flavor=Net
 | 
			
		||||
 | 
			
		||||
  #   - name: Build keepass2android (net)
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       make msbuild Flavor=Net
 | 
			
		||||
 | 
			
		||||
  #   - name: Build APK (net)
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       make apk Flavor=Net
 | 
			
		||||
 | 
			
		||||
  #   - name: Archive production artifacts (net)
 | 
			
		||||
  #     uses: actions/upload-artifact@v3
 | 
			
		||||
  #     with:
 | 
			
		||||
  #       name: signed APK ('net' built on ${{ github.job }})
 | 
			
		||||
  #       path: |
 | 
			
		||||
  #         src/keepass2android/bin/*/*-Signed.apk
 | 
			
		||||
 | 
			
		||||
  #   - name: Install NuGet dependencies (nonet)
 | 
			
		||||
  #     run: make nuget Flavor=NoNet
 | 
			
		||||
 | 
			
		||||
  #   - name: Build keepass2android (nonet)
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       make msbuild Flavor=NoNet
 | 
			
		||||
 | 
			
		||||
  #   - name: Build APK (nonet)
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       make apk Flavor=NoNet
 | 
			
		||||
 | 
			
		||||
  #   - name: Archive production artifacts (nonet)
 | 
			
		||||
  #     uses: actions/upload-artifact@v3
 | 
			
		||||
  #     with:
 | 
			
		||||
  #       name: signed APK ('nonet' built on ${{ github.job }})
 | 
			
		||||
  #       path: |
 | 
			
		||||
  #         src/keepass2android/bin/*/*-Signed.apk
 | 
			
		||||
 | 
			
		||||
  #   - name: Perform "make distclean"
 | 
			
		||||
  #     run: make distclean
 | 
			
		||||
 | 
			
		||||
  # linux:
 | 
			
		||||
  # disabled. 
 | 
			
		||||
  # As per: xamarin/xamarin-android#7235 (comment)
 | 
			
		||||
  # > Unfortunately the Classic OSS Xamarin.Android packages for Linux are no longer being built and as such they are not available for the v13.0 tag.
 | 
			
		||||
  # we can re-enable this after porting to .net 6.0
 | 
			
		||||
 | 
			
		||||
  #   runs-on: ubuntu-22.04
 | 
			
		||||
 | 
			
		||||
  #   env:
 | 
			
		||||
  #       # Build Artifact of xamarin.android-oss dated 2021-02-02, master branch (= version 11.2.99) - *.deb cannot be installed because "lxd" package is not anymore shipped in current ubuntu version
 | 
			
		||||
  #       #xamarin_url: https://artprodcus3.artifacts.visualstudio.com/Ad0adf05a-e7d7-4b65-96fe-3f3884d42038/6fd3d886-57a5-4e31-8db7-52a1b47c07a8/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL3hhbWFyaW4vcHJvamVjdElkLzZmZDNkODg2LTU3YTUtNGUzMS04ZGI3LTUyYTFiNDdjMDdhOC9idWlsZElkLzM0NTE3L2FydGlmYWN0TmFtZS9JbnN0YWxsZXJzKy0rTGludXg1/content?format=zip
 | 
			
		||||
 | 
			
		||||
  #       # Build Artifact of xamarin.android-oss dated 2021-03-23, d16-9 branch (= version 11.2.2) - *.deb cannot be installed because "lxd" package is not anymore shipped in current ubuntu version
 | 
			
		||||
  #       #xamarin_url: https://artprodcus3.artifacts.visualstudio.com/Ad0adf05a-e7d7-4b65-96fe-3f3884d42038/6fd3d886-57a5-4e31-8db7-52a1b47c07a8/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL3hhbWFyaW4vcHJvamVjdElkLzZmZDNkODg2LTU3YTUtNGUzMS04ZGI3LTUyYTFiNDdjMDdhOC9idWlsZElkLzM3Njg0L2FydGlmYWN0TmFtZS9JbnN0YWxsZXJzKy0rTGludXg1/content?format=zip
 | 
			
		||||
 | 
			
		||||
  #       # Build Artifact of xamarin.android-oss dated 2021-07-21, master branch (= version 11.4.99)
 | 
			
		||||
  #       # xamarin_url: https://artprodcus3.artifacts.visualstudio.com/Ad0adf05a-e7d7-4b65-96fe-3f3884d42038/6fd3d886-57a5-4e31-8db7-52a1b47c07a8/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL3hhbWFyaW4vcHJvamVjdElkLzZmZDNkODg2LTU3YTUtNGUzMS04ZGI3LTUyYTFiNDdjMDdhOC9idWlsZElkLzQzNjU5L2FydGlmYWN0TmFtZS9pbnN0YWxsZXJzLXVuc2lnbmVkKy0rTGludXg1/content?format=zip
 | 
			
		||||
 | 
			
		||||
  #       # Build Artifact of xamarin.android-oss dated 2022-02-16, master branch (= version 12.2.99)
 | 
			
		||||
  #       xamarin_url: https://artprodcus3.artifacts.visualstudio.com/Ad0adf05a-e7d7-4b65-96fe-3f3884d42038/6fd3d886-57a5-4e31-8db7-52a1b47c07a8/_apis/artifact/cGlwZWxpbmVhcnRpZmFjdDovL3hhbWFyaW4vcHJvamVjdElkLzZmZDNkODg2LTU3YTUtNGUzMS04ZGI3LTUyYTFiNDdjMDdhOC9idWlsZElkLzU0OTUzL2FydGlmYWN0TmFtZS9pbnN0YWxsZXJzLXVuc2lnbmVkKy0rTGludXg1/content?format=zip
 | 
			
		||||
  #   steps:
 | 
			
		||||
  #   - uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
  #   - name: Fetch submodules
 | 
			
		||||
  #     run: git submodule init && git submodule update
 | 
			
		||||
 | 
			
		||||
  #   - name: Setup Gradle
 | 
			
		||||
  #     uses: gradle/gradle-build-action@v2
 | 
			
		||||
 | 
			
		||||
  #   - name: Cache NuGet packages
 | 
			
		||||
  #     uses: actions/cache@v3
 | 
			
		||||
  #     with:
 | 
			
		||||
  #       path: ~/.nuget/packages
 | 
			
		||||
  #       key: ${{ runner.os }}-nuget-${{ hashFiles('src/**/*.csproj', 'src/**/packages.config') }}
 | 
			
		||||
  #       restore-keys: |
 | 
			
		||||
  #         ${{ runner.os }}-nuget-
 | 
			
		||||
 | 
			
		||||
  #   - name: Cache Xamarin.Android packages
 | 
			
		||||
  #     id: xamarin_cache
 | 
			
		||||
  #     uses: actions/cache@v3
 | 
			
		||||
  #     with:
 | 
			
		||||
  #       path: ~/xamarin.android-oss
 | 
			
		||||
  #       key: ${{ runner.os }}-xamarin.android-oss-${{ env.xamarin_url }}
 | 
			
		||||
  #       restore-keys: |
 | 
			
		||||
  #         ${{ runner.os }}-xamarin.android-oss-${{ env.xamarin_url }}
 | 
			
		||||
 | 
			
		||||
  #   - name: Install Mono
 | 
			
		||||
  #     if: ${{ false }}  # disable for now since it is already installed on the runner which uses the same repo https://github.com/actions/runner-images/blob/main/images/linux/Ubuntu2204-Readme.md#language-and-runtime
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       sudo apt install gnupg ca-certificates &&
 | 
			
		||||
  #       sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF &&
 | 
			
		||||
  #       echo "deb https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list &&
 | 
			
		||||
  #       sudo apt update &&
 | 
			
		||||
  #       sudo apt-get -y -t stable-focal install mono-complete
 | 
			
		||||
 | 
			
		||||
  #   - name: Download & unpack Xamarin.Android
 | 
			
		||||
  #     if: steps.xamarin_cache.outputs.cache-hit != 'true'
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       set -x
 | 
			
		||||
  #       cd $HOME &&
 | 
			
		||||
  #       wget -O "installers-unsigned - Linux.zip" ${{ env.xamarin_url }} &&
 | 
			
		||||
  #       unzip "installers-unsigned - Linux.zip" &&
 | 
			
		||||
  #       mkdir -p xamarin.android-oss &&
 | 
			
		||||
  #       DIR=$(unzip -Z -1 installers-unsigned\ -\ Linux.zip   | cut -d '/' -f1 | sort -u) &&
 | 
			
		||||
  #       tar -xvf "$DIR"/xamarin.android-oss-*.tar.* --strip-components=1 -C xamarin.android-oss &&
 | 
			
		||||
  #       mv "$DIR"/*.deb xamarin.android-oss
 | 
			
		||||
 | 
			
		||||
  #   - name: Setup Xamarin.Android
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       cd $HOME &&
 | 
			
		||||
  #       sudo apt install -y ./xamarin.android-oss/*.deb &&
 | 
			
		||||
  #       echo "$HOME/xamarin.android-oss/bin/Release/bin" >> $GITHUB_PATH
 | 
			
		||||
 | 
			
		||||
  #   - name: Switch to JDK-11
 | 
			
		||||
  #     uses: actions/setup-java@v3
 | 
			
		||||
  #     with:
 | 
			
		||||
  #       java-version: '11'
 | 
			
		||||
  #       distribution: 'temurin'
 | 
			
		||||
 | 
			
		||||
  #   - name: Display java version
 | 
			
		||||
  #     run: java -version
 | 
			
		||||
 | 
			
		||||
  #   # Some components of Keepass2Android currently target android API 26 which are not available on the runner
 | 
			
		||||
  #   - name: Download android-26 API
 | 
			
		||||
  #     run: $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --install "platforms;android-26"
 | 
			
		||||
 | 
			
		||||
  #   - name: Install libzip4
 | 
			
		||||
  #     if: ${{ false }}  # disable for now since it is already installed on the runner
 | 
			
		||||
  #     run: sudo apt -y install libzip4
 | 
			
		||||
 | 
			
		||||
  #   - name: Build native dependencies
 | 
			
		||||
  #     run: make native
 | 
			
		||||
 | 
			
		||||
  #   - name: Build java dependencies
 | 
			
		||||
  #     run: make java
 | 
			
		||||
 | 
			
		||||
  #   - name: Install NuGet dependencies (net)
 | 
			
		||||
  #     run: make nuget Flavor=Net
 | 
			
		||||
 | 
			
		||||
  #   - name: Build keepass2android (net)
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       make msbuild Flavor=Net
 | 
			
		||||
 | 
			
		||||
  #   - name: Build APK (net)
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       make apk Flavor=Net
 | 
			
		||||
 | 
			
		||||
  #   - name: Archive production artifacts (net)
 | 
			
		||||
  #     uses: actions/upload-artifact@v3
 | 
			
		||||
  #     with:
 | 
			
		||||
  #       name: signed APK ('net' built on ${{ github.job }})
 | 
			
		||||
  #       path: |
 | 
			
		||||
  #         src/keepass2android/bin/*/*-Signed.apk
 | 
			
		||||
 | 
			
		||||
  #   - name: Install NuGet dependencies (nonet)
 | 
			
		||||
  #     run: make nuget Flavor=NoNet
 | 
			
		||||
 | 
			
		||||
  #   - name: Build keepass2android (nonet)
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       make msbuild Flavor=NoNet
 | 
			
		||||
 | 
			
		||||
  #   - name: Build APK (nonet)
 | 
			
		||||
  #     run: |
 | 
			
		||||
  #       make apk Flavor=NoNet
 | 
			
		||||
 | 
			
		||||
  #   - name: Archive production artifacts (nonet)
 | 
			
		||||
  #     uses: actions/upload-artifact@v3
 | 
			
		||||
  #     with:
 | 
			
		||||
  #       name: signed APK ('nonet' built on ${{ github.job }})
 | 
			
		||||
  #       path: |
 | 
			
		||||
  #         src/keepass2android/bin/*/*-Signed.apk
 | 
			
		||||
 | 
			
		||||
  #   - name: Perform "make distclean"
 | 
			
		||||
  #     run: make distclean
 | 
			
		||||
 | 
			
		||||
  windows:
 | 
			
		||||
 | 
			
		||||
    # on windows-2022 it builds with:
 | 
			
		||||
    #    Microsoft Visual Studio\2022\Enterprise
 | 
			
		||||
    #    Found Java SDK version 11.0.12
 | 
			
		||||
    #    Found Xamarin.Android 13.1.0.1
 | 
			
		||||
    #
 | 
			
		||||
    runs-on: windows-2022
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
    - uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
    - name: Setup Gradle
 | 
			
		||||
      uses: gradle/gradle-build-action@v2
 | 
			
		||||
 | 
			
		||||
    - name: Cache NuGet packages
 | 
			
		||||
      uses: actions/cache@v3
 | 
			
		||||
      with:
 | 
			
		||||
        path: ~/.nuget/packages
 | 
			
		||||
        key: ${{ runner.os }}-nuget-${{ hashFiles('src/**/*.csproj', 'src/**/packages.config') }}
 | 
			
		||||
        restore-keys: |
 | 
			
		||||
          ${{ runner.os }}-nuget-
 | 
			
		||||
 | 
			
		||||
    - name: Fetch submodules
 | 
			
		||||
      run: git submodule init && git submodule update
 | 
			
		||||
 | 
			
		||||
    # Workaround an issue when building on windows-2022. Error was
 | 
			
		||||
    #       D8 : OpenJDK 64-Bit Server VM warning : INFO: os::commit_memory(0x00000000ae400000, 330301440, 0) failed; error='The paging file is too small for this operation to complete' (DOS error/errno=1455) [D:\a\keepass2android\keepass2android\src\keepass2android\keepass2android-app.csproj]
 | 
			
		||||
    #       C:\Program Files\Microsoft Visual Studio\2022\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.D8.targets(81,5): error MSB6006: "java.exe" exited with code 1. [D:\a\keepass2android\keepass2android\src\keepass2android\keepass2android-app.csproj]
 | 
			
		||||
    - name: Configure Pagefile
 | 
			
		||||
      uses: al-cheb/configure-pagefile-action@v1.3
 | 
			
		||||
      with:
 | 
			
		||||
        minimum-size: 8GB
 | 
			
		||||
 | 
			
		||||
    - name: Add msbuild to PATH
 | 
			
		||||
      uses: microsoft/setup-msbuild@v1.1
 | 
			
		||||
      # If we want to also have nmake, use this instead
 | 
			
		||||
      #uses: ilammy/msvc-dev-cmd@v1
 | 
			
		||||
 | 
			
		||||
    - name: Switch to JDK-11
 | 
			
		||||
      uses: actions/setup-java@v3
 | 
			
		||||
      with:
 | 
			
		||||
        java-version: '11'
 | 
			
		||||
        distribution: 'temurin'
 | 
			
		||||
 | 
			
		||||
    - name: Display java version
 | 
			
		||||
      run: java -version
 | 
			
		||||
 | 
			
		||||
    # Some components of Keepass2Android currently target android API 26 which are not available on the runner
 | 
			
		||||
    - name: Download android-26 API
 | 
			
		||||
      shell: cmd
 | 
			
		||||
      run: |
 | 
			
		||||
        %ANDROID_SDK_ROOT%\cmdline-tools\latest\bin\sdkmanager --install "platforms;android-26"
 | 
			
		||||
 | 
			
		||||
    - name: Build native dependencies
 | 
			
		||||
      shell: cmd
 | 
			
		||||
      run: |
 | 
			
		||||
        make native
 | 
			
		||||
 | 
			
		||||
    - name: Build java dependencies
 | 
			
		||||
      shell: cmd
 | 
			
		||||
      run: |
 | 
			
		||||
        make java
 | 
			
		||||
 | 
			
		||||
    - name: Install NuGet dependencies (net)
 | 
			
		||||
      run: make nuget Flavor=Net
 | 
			
		||||
 | 
			
		||||
    - name: Build keepass2android (net)
 | 
			
		||||
      run: |
 | 
			
		||||
        make msbuild Flavor=Net
 | 
			
		||||
 | 
			
		||||
    - name: Build APK (net)
 | 
			
		||||
      run: |
 | 
			
		||||
        make apk Flavor=Net
 | 
			
		||||
 | 
			
		||||
    - name: Archive production artifacts (net)
 | 
			
		||||
      uses: actions/upload-artifact@v3
 | 
			
		||||
      with:
 | 
			
		||||
        name: signed APK ('net' built on ${{ github.job }})
 | 
			
		||||
        path: |
 | 
			
		||||
          src/keepass2android/bin/*/*-Signed.apk
 | 
			
		||||
 | 
			
		||||
    - name: Install NuGet dependencies (nonet)
 | 
			
		||||
      run: make nuget Flavor=NoNet
 | 
			
		||||
 | 
			
		||||
    - name: Build keepass2android (nonet)
 | 
			
		||||
      run: |
 | 
			
		||||
        make msbuild Flavor=NoNet
 | 
			
		||||
    - name: Test Autofill
 | 
			
		||||
      working-directory: ./src/Kp2aAutofillParserTest
 | 
			
		||||
      run: dotnet test
 | 
			
		||||
 | 
			
		||||
    - name: Build APK (nonet)
 | 
			
		||||
      run: |
 | 
			
		||||
        make apk Flavor=NoNet
 | 
			
		||||
 | 
			
		||||
    - name: Archive production artifacts (nonet)
 | 
			
		||||
      uses: actions/upload-artifact@v3
 | 
			
		||||
      with:
 | 
			
		||||
        name: signed APK ('nonet' built on ${{ github.job }})
 | 
			
		||||
        path: |
 | 
			
		||||
          src/keepass2android/bin/*/*-Signed.apk
 | 
			
		||||
 | 
			
		||||
    - name: Perform "make distclean"
 | 
			
		||||
      run: make distclean
 | 
			
		||||
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -7,6 +7,10 @@ PCtest
 | 
			
		||||
bin
 | 
			
		||||
obj
 | 
			
		||||
 | 
			
		||||
# Makefile-related files
 | 
			
		||||
/allow_git_clean
 | 
			
		||||
/stamp.nuget_*
 | 
			
		||||
 | 
			
		||||
Resource.designer.cs
 | 
			
		||||
R.java
 | 
			
		||||
 | 
			
		||||
@@ -105,7 +109,6 @@ Thumbs.db
 | 
			
		||||
/src/java/JavaFileStorageTest/gen/group/pals/android/lib/ui/filechooser/R.java
 | 
			
		||||
/src/java/JavaFileStorageTest/gen/keepass2android/javafilestorage/R.java
 | 
			
		||||
 | 
			
		||||
/src/TwofishCipher/Resources/Resource.Designer.cs
 | 
			
		||||
/src/BindingLibrary1
 | 
			
		||||
 | 
			
		||||
/src/PluginTOTP
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										361
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										361
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,361 @@
 | 
			
		||||
#!/usr/bin/make -f
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# This Makefile can be used on both unix-like (use make) & windows (with GNU make)
 | 
			
		||||
#
 | 
			
		||||
# append the Configuration variable to 'make' call with value to use in '/p:Configuration='
 | 
			
		||||
# of msbuild command.
 | 
			
		||||
#
 | 
			
		||||
# append the Flavor variable to 'make' call with value to use in '/p:Flavor='
 | 
			
		||||
# of msbuild command.
 | 
			
		||||
#
 | 
			
		||||
# Example:
 | 
			
		||||
#    make Configuration=Release Flavor=NoNet
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# Some targets:
 | 
			
		||||
#  - all: everything (including APK)
 | 
			
		||||
#  - native: build the native libs
 | 
			
		||||
#  - java: build the java libs
 | 
			
		||||
#  - nuget: restore NuGet packages
 | 
			
		||||
#  - msbuild: build the project
 | 
			
		||||
#  - apk: same as all
 | 
			
		||||
#
 | 
			
		||||
#  - distclean: run a 'git clean -xdff'. Remove everyhing that is not in the git tree.
 | 
			
		||||
#  - clean: all clean_* targets below
 | 
			
		||||
#  - clean_native: clean native lib
 | 
			
		||||
#  - clean_java: call clean target of java libs
 | 
			
		||||
#  - clean_nuget: cleanup the 'nuget restore'
 | 
			
		||||
#  - clean_msbuild: call clean target of msbuild
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
# Disable built-in rules to speed-up the Makefile processing.
 | 
			
		||||
# for example when running 'make java' on Windows it could take ~10 sec more than on linux to start building
 | 
			
		||||
# from what this option disables, the "clearing out the default list of suffixes for suffix rules"
 | 
			
		||||
# gives the most speed gain.
 | 
			
		||||
MAKEFLAGS += --no-builtin-rules
 | 
			
		||||
 | 
			
		||||
ifeq ($(OS),Windows_NT)     # is Windows_NT on XP, 2000, 7, Vista, 10...
 | 
			
		||||
    detected_OS := Windows
 | 
			
		||||
    WHICH := where
 | 
			
		||||
    RM := RMDIR /S /Q
 | 
			
		||||
    RMFILE := DEL
 | 
			
		||||
    CP := copy
 | 
			
		||||
    GRADLEW := gradlew.bat
 | 
			
		||||
    # Force use of cmd shell (don't use POSIX shell because the user may not have one installed)
 | 
			
		||||
    SHELL := cmd
 | 
			
		||||
else
 | 
			
		||||
    detected_OS := $(shell uname)
 | 
			
		||||
    WHICH := which
 | 
			
		||||
    RM := rm -rf
 | 
			
		||||
    RMFILE := $(RM)
 | 
			
		||||
    CP := cp
 | 
			
		||||
    GRADLEW := ./gradlew
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
$(info MAKESHELL: $(MAKESHELL))
 | 
			
		||||
$(info SHELL: $(SHELL))
 | 
			
		||||
$(info )
 | 
			
		||||
 | 
			
		||||
# On linux use xabuild, on Windows use MSBuild.exe, otherwise (macos?) use msbuild.
 | 
			
		||||
ifeq ($(detected_OS),Linux)
 | 
			
		||||
  MSBUILD_binary := xabuild
 | 
			
		||||
  MSBUILD := $(shell $(WHICH) $(MSBUILD_binary))
 | 
			
		||||
else ifeq ($(detected_OS),Windows)
 | 
			
		||||
  MSBUILD_binary := MSBuild.exe
 | 
			
		||||
  MSBUILD := $(shell $(WHICH) $(MSBUILD_binary) 2> nul)
 | 
			
		||||
  ifeq ($(MSBUILD),)
 | 
			
		||||
    # Additional heuristic to find MSBUILD_BINARY on Windows
 | 
			
		||||
    VSWHERE := "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
 | 
			
		||||
    VSWHERE_CHECK := $(shell @echo off & $(VSWHERE) 2> nul || echo VSWHERE_NOT_FOUND)
 | 
			
		||||
    ifneq ($(VSWHERE_CHECK),VSWHERE_NOT_FOUND)
 | 
			
		||||
      MSBUILD := $(shell @echo off & $(VSWHERE) -latest -prerelease -products * -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe)
 | 
			
		||||
      VS_INSTALL_PATH := $(shell @echo off & $(VSWHERE) -property installationPath)
 | 
			
		||||
    endif
 | 
			
		||||
  endif
 | 
			
		||||
else
 | 
			
		||||
  MSBUILD_binary := msbuild
 | 
			
		||||
  MSBUILD := $(shell $(WHICH) $(MSBUILD_binary))
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(MSBUILD),)
 | 
			
		||||
  $(info )
 | 
			
		||||
  $(info '$(MSBUILD_binary)' binary could not be found. Check it is in your PATH.)
 | 
			
		||||
  ifeq ($(detected_OS),Windows)
 | 
			
		||||
  ifneq ($(VSWHERE_CHECK),VSWHERE_NOT_FOUND)
 | 
			
		||||
    $(info )
 | 
			
		||||
    $(info You may retry after running in the command prompt:)
 | 
			
		||||
    $(info )
 | 
			
		||||
    $(info "$(VS_INSTALL_PATH)\VC\Auxiliary\Build\vcvarsall.bat" x86_amd64)
 | 
			
		||||
    $(info )
 | 
			
		||||
    $(info If this doesn't work, install/find the location of vcvarsall.bat)
 | 
			
		||||
    $(info or install and add msbuild.exe to your PATH)
 | 
			
		||||
    $(info )
 | 
			
		||||
  endif
 | 
			
		||||
  endif
 | 
			
		||||
  $(error )
 | 
			
		||||
endif
 | 
			
		||||
$(info MSBUILD: $(MSBUILD))
 | 
			
		||||
$(info )
 | 
			
		||||
 | 
			
		||||
ifeq ($(ANDROID_SDK_ROOT),)
 | 
			
		||||
  $(error set ANDROID_SDK_ROOT environment variable)
 | 
			
		||||
endif
 | 
			
		||||
$(info ANDROID_SDK_ROOT: $(ANDROID_SDK_ROOT))
 | 
			
		||||
 | 
			
		||||
ifeq ($(ANDROID_HOME),)
 | 
			
		||||
  $(error set ANDROID_HOME environment variable)
 | 
			
		||||
endif
 | 
			
		||||
$(info ANDROID_HOME: $(ANDROID_SDK_ROOT))
 | 
			
		||||
 | 
			
		||||
ifeq ($(ANDROID_NDK_ROOT),)
 | 
			
		||||
  $(error set ANDROID_NDK_ROOT environment variable)
 | 
			
		||||
endif
 | 
			
		||||
$(info ANDROID_NDK_ROOT: $(ANDROID_NDK_ROOT))
 | 
			
		||||
 | 
			
		||||
ifneq ($(Configuration),)
 | 
			
		||||
  MSBUILD_PARAM = -p:Configuration="$(Configuration)"
 | 
			
		||||
else
 | 
			
		||||
  $(warning Configuration environment variable not set.)
 | 
			
		||||
endif
 | 
			
		||||
ifneq ($(Flavor),)
 | 
			
		||||
  MSBUILD_PARAM += -p:Flavor="$(Flavor)"
 | 
			
		||||
else
 | 
			
		||||
  $(warning Flavor environment variable not set.)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifneq ($(KeyStore),)
 | 
			
		||||
  MSBUILD_PARAM += -p:AndroidKeyStore=True -p:AndroidSigningKeyStore="$(KeyStore)" -p:AndroidSigningStorePass=env:MyAndroidSigningStorePass -p:AndroidSigningKeyPass=env:MyAndroidSigningKeyPass
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(detected_OS),Windows)
 | 
			
		||||
  to_win_path=$(subst /,\,$(1))
 | 
			
		||||
  to_posix_path=$(subst \,/,$(1))
 | 
			
		||||
  define remove_dir
 | 
			
		||||
    if exist $(1) ( $(RM) $(1) )
 | 
			
		||||
  endef
 | 
			
		||||
  define remove_files
 | 
			
		||||
    $(foreach file,$(call to_win_path,$(1)), IF EXIST $(file) ( $(RMFILE) $(file) ) & )
 | 
			
		||||
  endef
 | 
			
		||||
else
 | 
			
		||||
  define remove_dir
 | 
			
		||||
    $(RM) $(1)
 | 
			
		||||
  endef
 | 
			
		||||
  define remove_files
 | 
			
		||||
    $(RMFILE) $(1)
 | 
			
		||||
  endef
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
# Recursive wildcard: https://stackoverflow.com/a/18258352
 | 
			
		||||
rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d))
 | 
			
		||||
 | 
			
		||||
$(info MSBUILD_PARAM: $(MSBUILD_PARAM))
 | 
			
		||||
$(info nuget path: $(shell $(WHICH) nuget))
 | 
			
		||||
$(info )
 | 
			
		||||
 | 
			
		||||
NATIVE_COMPONENTS := argon2
 | 
			
		||||
NATIVE_CLEAN_TARGETS := clean_argon2
 | 
			
		||||
 | 
			
		||||
OUTPUT_argon2 = src/java/argon2/libs/armeabi-v7a/libargon2.so \
 | 
			
		||||
	src/java/argon2/libs/arm64-v8a/libargon2.so \
 | 
			
		||||
	src/java/argon2/libs/x86/libargon2.so \
 | 
			
		||||
	src/java/argon2/libs/x86_64/libargon2.so
 | 
			
		||||
 | 
			
		||||
JAVA_COMPONENTS := \
 | 
			
		||||
	JavaFileStorageTest-AS \
 | 
			
		||||
	KP2ASoftkeyboard_AS \
 | 
			
		||||
	Keepass2AndroidPluginSDK2 \
 | 
			
		||||
	KP2AKdbLibrary
 | 
			
		||||
	#PluginQR # Doesn't seem required
 | 
			
		||||
JAVA_CLEAN_TARGETS := \
 | 
			
		||||
	clean_JavaFileStorageTest-AS \
 | 
			
		||||
	clean_KP2ASoftkeyboard_AS \
 | 
			
		||||
	clean_Keepass2AndroidPluginSDK2 \
 | 
			
		||||
	clean_KP2AKdbLibrary \
 | 
			
		||||
	clean_PluginQR
 | 
			
		||||
 | 
			
		||||
INPUT_android-filechooser-AS := $(filter-out $(filter %/app,$(wildcard src/java/android-filechooser-AS/*)),$(wildcard src/java/android-filechooser-AS/*)) \
 | 
			
		||||
	$(filter-out $(filter %/build,$(wildcard src/java/android-filechooser-AS/app/*)),$(wildcard src/java/android-filechooser-AS/app/*)) \
 | 
			
		||||
	$(call rwildcard,src/java/android-filechooser-AS/app/src,*)
 | 
			
		||||
 | 
			
		||||
INPUT_JavaFileStorage := $(filter-out $(filter %/app,$(wildcard src/java/JavaFileStorage/*)),$(wildcard src/java/JavaFileStorage/*)) \
 | 
			
		||||
	$(filter-out $(filter %/build,$(wildcard src/java/JavaFileStorage/app/*)),$(wildcard src/java/JavaFileStorage/app/*)) \
 | 
			
		||||
	$(wildcard src/java/JavaFileStorage/libs/*) \
 | 
			
		||||
	$(call rwildcard,src/java/JavaFileStorage/app/src,*) \
 | 
			
		||||
 | 
			
		||||
INPUT_JavaFileStorageTest-AS := $(filter-out $(filter %/app,$(wildcard src/java/JavaFileStorageTest-AS/*)),$(wildcard src/java/JavaFileStorageTest-AS/*)) \
 | 
			
		||||
	$(filter-out $(filter %/build,$(wildcard src/java/JavaFileStorageTest-AS/app/*)),$(wildcard src/java/JavaFileStorageTest-AS/app/*)) \
 | 
			
		||||
	$(call rwildcard,src/java/JavaFileStorageTest-AS/app/src,*) \
 | 
			
		||||
	$(INPUT_android-filechooser-AS) \
 | 
			
		||||
	$(INPUT_JavaFileStorage)
 | 
			
		||||
OUTPUT_JavaFileStorageTest-AS = src/java/android-filechooser-AS/app/build/outputs/aar/android-filechooser-debug.aar \
 | 
			
		||||
	src/java/android-filechooser-AS/app/build/outputs/aar/android-filechooser-release.aar \
 | 
			
		||||
	src/java/JavaFileStorage/app/build/outputs/aar/JavaFileStorage-debug.aar \
 | 
			
		||||
	src/java/JavaFileStorage/app/build/outputs/aar/JavaFileStorage-release.aar \
 | 
			
		||||
	src/java/JavaFileStorageTest-AS/app/build/outputs/apk/debug/app-debug.apk \
 | 
			
		||||
	src/java/JavaFileStorageTest-AS/app/build/outputs/apk/release/app-release-unsigned.apk
 | 
			
		||||
 | 
			
		||||
INPUT_KP2ASoftkeyboard_AS := $(wildcard src/java/KP2ASoftkeyboard_AS/*) \
 | 
			
		||||
	$(wildcard src/java/KP2ASoftkeyboard_AS/app/*) \
 | 
			
		||||
	$(call rwildcard,src/java/KP2ASoftkeyboard_AS/app/src,*)
 | 
			
		||||
OUTPUT_KP2ASoftkeyboard_AS = src/java/KP2ASoftkeyboard_AS/app/build/outputs/aar/app-debug.aar \
 | 
			
		||||
	src/java/KP2ASoftkeyboard_AS/app/build/outputs/aar/app-release.aar
 | 
			
		||||
 | 
			
		||||
INPUT_Keepass2AndroidPluginSDK2 := $(wildcard src/java/Keepass2AndroidPluginSDK2/*) \
 | 
			
		||||
	$(wildcard src/java/Keepass2AndroidPluginSDK2/app/*) \
 | 
			
		||||
	$(call rwildcard,src/java/Keepass2AndroidPluginSDK2/app/src,*)
 | 
			
		||||
OUTPUT_Keepass2AndroidPluginSDK2 = src/java/Keepass2AndroidPluginSDK2/app/build/outputs/aar/app-debug.aar \
 | 
			
		||||
	src/java/Keepass2AndroidPluginSDK2/app/build/outputs/aar/app-release.aar
 | 
			
		||||
 | 
			
		||||
INPUT_KP2AKdbLibrary := $(wildcard src/java/KP2AKdbLibrary/*) \
 | 
			
		||||
	$(wildcard src/java/KP2AKdbLibrary/app/*) \
 | 
			
		||||
	$(call rwildcard,src/java/KP2AKdbLibrary/app/src,*)
 | 
			
		||||
OUTPUT_KP2AKdbLibrary = src/java/KP2AKdbLibrary/app/build/outputs/aar/app-debug.aar \
 | 
			
		||||
	src/java/KP2AKdbLibrary/app/build/outputs/aar/app-release.aar
 | 
			
		||||
 | 
			
		||||
INPUT_PluginQR := $(wildcard src/java/PluginQR/*) \
 | 
			
		||||
	$(wildcard src/java/PluginQR/app/*) \
 | 
			
		||||
	$(call rwildcard,src/java/PluginQR/app/src,*) \
 | 
			
		||||
	$(INPUT_Keepass2AndroidPluginSDK2)
 | 
			
		||||
OUTPUT_PluginQR = src/java/Keepass2AndroidPluginSDK2/app/build/outputs/aar/Keepass2AndroidPluginSDK2-debug.aar \
 | 
			
		||||
	src/java/Keepass2AndroidPluginSDK2/app/build/outputs/aar/Keepass2AndroidPluginSDK2-release.aar \
 | 
			
		||||
	src/java/PluginQR/app/build/outputs/apk/debug/app-debug.apk \
 | 
			
		||||
	src/java/PluginQR/app/build/outputs/apk/debug/app-release-unsigned.apk
 | 
			
		||||
 | 
			
		||||
##### Targets definition
 | 
			
		||||
 | 
			
		||||
.PHONY: native $(NATIVE_COMPONENTS) clean_native $(NATIVE_CLEAN_TARGETS) \
 | 
			
		||||
	java $(JAVA_COMPONENTS) clean_java $(JAVA_CLEAN_TARGETS) \
 | 
			
		||||
	nuget clean_nuget \
 | 
			
		||||
	msbuild clean_msbuild \
 | 
			
		||||
	apk all clean
 | 
			
		||||
 | 
			
		||||
all: apk
 | 
			
		||||
 | 
			
		||||
##### Native Dependencies
 | 
			
		||||
 | 
			
		||||
native: $(NATIVE_COMPONENTS)
 | 
			
		||||
 | 
			
		||||
argon2: $(OUTPUT_argon2)
 | 
			
		||||
$(OUTPUT_argon2): $(wildcard src/java/argon2/phc-winner-argon2/src/*)  $(wildcard src/java/argon2/phc-winner-argon2/src/blake2/*)
 | 
			
		||||
	cd src/java/argon2 && $(ANDROID_NDK_ROOT)/ndk-build
 | 
			
		||||
 | 
			
		||||
##### Java Dependencies
 | 
			
		||||
 | 
			
		||||
java: $(JAVA_COMPONENTS)
 | 
			
		||||
 | 
			
		||||
JavaFileStorageTest-AS: $(OUTPUT_JavaFileStorageTest-AS)
 | 
			
		||||
KP2ASoftkeyboard_AS: $(OUTPUT_KP2ASoftkeyboard_AS)
 | 
			
		||||
Keepass2AndroidPluginSDK2: $(OUTPUT_Keepass2AndroidPluginSDK2)
 | 
			
		||||
KP2AKdbLibrary: $(OUTPUT_KP2AKdbLibrary)
 | 
			
		||||
PluginQR: $(OUTPUT_PluginQR)
 | 
			
		||||
 | 
			
		||||
$(OUTPUT_JavaFileStorageTest-AS): $(INPUT_JavaFileStorageTest-AS)
 | 
			
		||||
	$(call remove_files,$(OUTPUT_JavaFileStorageTest-AS))
 | 
			
		||||
	cd src/java/JavaFileStorageTest-AS && $(GRADLEW) assemble
 | 
			
		||||
$(OUTPUT_KP2ASoftkeyboard_AS): $(INPUT_KP2ASoftkeyboard_AS)
 | 
			
		||||
	$(call remove_files,$(OUTPUT_KP2ASoftkeyboard_AS))
 | 
			
		||||
	cd src/java/KP2ASoftkeyboard_AS && $(GRADLEW) assemble
 | 
			
		||||
$(OUTPUT_Keepass2AndroidPluginSDK2): $(INPUT_Keepass2AndroidPluginSDK2)
 | 
			
		||||
	$(call remove_files,$(OUTPUT_Keepass2AndroidPluginSDK2))
 | 
			
		||||
	cd src/java/Keepass2AndroidPluginSDK2 && $(GRADLEW) assemble
 | 
			
		||||
$(OUTPUT_KP2AKdbLibrary): $(INPUT_KP2AKdbLibrary)
 | 
			
		||||
	$(call remove_files,$(OUTPUT_KP2AKdbLibrary))
 | 
			
		||||
	cd src/java/KP2AKdbLibrary && $(GRADLEW) assemble
 | 
			
		||||
$(OUTPUT_PluginQR): $(INPUT_PluginQR)
 | 
			
		||||
	$(call remove_files,$(OUTPUT_PluginQR))
 | 
			
		||||
	cd src/java/PluginQR && $(GRADLEW) assemble
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
##### Nuget Dependencies
 | 
			
		||||
 | 
			
		||||
nuget: stamp.nuget_$(Flavor)
 | 
			
		||||
stamp.nuget_$(Flavor): src/KeePass.sln $(wildcard src/*/*.csproj) $(wildcard src/*/packages.config)
 | 
			
		||||
ifeq ($(shell $(WHICH) nuget),)
 | 
			
		||||
	$(error "nuget" command not found. Check it is in your PATH)
 | 
			
		||||
endif
 | 
			
		||||
	$(RMFILE) stamp.nuget_*
 | 
			
		||||
	nuget restore src/KeePass.sln
 | 
			
		||||
	$(MSBUILD) src/KeePass.sln -t:restore $(MSBUILD_PARAM) -p:RestorePackagesConfig=true
 | 
			
		||||
	@echo "" > stamp.nuget_$(Flavor)
 | 
			
		||||
 | 
			
		||||
#####
 | 
			
		||||
src/Kp2aBusinessLogic/Io/DropboxFileStorageKeys.cs:
 | 
			
		||||
ifeq ($(detected_OS),Windows)
 | 
			
		||||
	$(CP) src\Kp2aBusinessLogic\Io\DropboxFileStorageKeysDummy.cs src\Kp2aBusinessLogic\Io\DropboxFileStorageKeys.cs
 | 
			
		||||
else
 | 
			
		||||
	$(CP) src/Kp2aBusinessLogic/Io/DropboxFileStorageKeysDummy.cs $@
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
msbuild: native java nuget src/Kp2aBusinessLogic/Io/DropboxFileStorageKeys.cs
 | 
			
		||||
	$(MSBUILD) src/KeePass.sln -target:keepass2android-app -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -p:BuildProjectReferences=true $(MSBUILD_PARAM) -p:Platform="Any CPU" -m
 | 
			
		||||
 | 
			
		||||
apk: msbuild
 | 
			
		||||
	$(MSBUILD) src/keepass2android/keepass2android-app.csproj -p:AndroidSdkDirectory="$(ANDROID_SDK_ROOT)" -t:SignAndroidPackage $(MSBUILD_PARAM) -p:Platform=AnyCPU -m 
 | 
			
		||||
 | 
			
		||||
build_all: msbuild
 | 
			
		||||
 | 
			
		||||
##### Cleanup targets
 | 
			
		||||
 | 
			
		||||
clean_native: $(NATIVE_CLEAN_TARGETS)
 | 
			
		||||
clean_argon2:
 | 
			
		||||
	cd src/java/argon2 && $(ANDROID_NDK_ROOT)/ndk-build clean
 | 
			
		||||
 | 
			
		||||
clean_java: $(JAVA_CLEAN_TARGETS)
 | 
			
		||||
clean_JavaFileStorageTest-AS:
 | 
			
		||||
	cd src/java/JavaFileStorageTest-AS && $(GRADLEW) clean
 | 
			
		||||
clean_KP2ASoftkeyboard_AS:
 | 
			
		||||
	cd src/java/KP2ASoftkeyboard_AS && $(GRADLEW) clean
 | 
			
		||||
clean_Keepass2AndroidPluginSDK2:
 | 
			
		||||
	cd src/java/Keepass2AndroidPluginSDK2 && $(GRADLEW) clean
 | 
			
		||||
clean_KP2AKdbLibrary:
 | 
			
		||||
	cd src/java/KP2AKdbLibrary && $(GRADLEW) clean
 | 
			
		||||
clean_PluginQR:
 | 
			
		||||
	cd src/java/PluginQR && $(GRADLEW) clean
 | 
			
		||||
clean_rm:
 | 
			
		||||
	rm -rf src/*/obj
 | 
			
		||||
	rm -rf src/*/bin
 | 
			
		||||
	rm -rf src/java/*/app/build
 | 
			
		||||
	rm -rf src/java/argon2/obj
 | 
			
		||||
	rm -rf src/java/argon2/libs
 | 
			
		||||
	rm -rf src/packages
 | 
			
		||||
	rm -rf src/java/KP2AKdbLibrary/app/.cxx
 | 
			
		||||
	rm -rf src/java/KP2ASoftkeyboard_AS/app/.cxx
 | 
			
		||||
	rm -rf src/SamsungPass/Xamarin.SamsungPass/SamsungPass/bin
 | 
			
		||||
	rm -rf src/SamsungPass/Xamarin.SamsungPass/SamsungPass/obj
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
# https://learn.microsoft.com/en-us/nuget/consume-packages/package-restore-troubleshooting#other-potential-conditions
 | 
			
		||||
clean_nuget:
 | 
			
		||||
	cd src && $(call remove_dir,packages)
 | 
			
		||||
ifeq ($(detected_OS),Windows)
 | 
			
		||||
	DEL /S src\project.assets.json
 | 
			
		||||
	DEL /S src\*.nuget.*
 | 
			
		||||
else
 | 
			
		||||
	$(RM) src/*/obj/project.assets.json
 | 
			
		||||
	$(RM) src/*/obj/*.nuget.*
 | 
			
		||||
endif
 | 
			
		||||
	$(RMFILE) stamp.nuget_*
 | 
			
		||||
 | 
			
		||||
clean_msbuild:
 | 
			
		||||
	$(MSBUILD) src/KeePass.sln -target:clean $(MSBUILD_PARAM)
 | 
			
		||||
 | 
			
		||||
clean: clean_native clean_java clean_nuget clean_msbuild
 | 
			
		||||
 | 
			
		||||
distclean: clean
 | 
			
		||||
ifneq ("$(wildcard ./allow_git_clean)","")
 | 
			
		||||
ifeq ($(shell $(WHICH) git),)
 | 
			
		||||
	$(error "git" command not found. Check it is in your PATH)
 | 
			
		||||
endif
 | 
			
		||||
	git clean -xdff src
 | 
			
		||||
else
 | 
			
		||||
	$(warning 'git clean' skipped for safety reasons. See hint below:)
 | 
			
		||||
	$(info )
 | 
			
		||||
	$(info 'git clean' would delete all untracked files, those in '.gitignore' and those in '.git/info/exclude'.)
 | 
			
		||||
	$(info )
 | 
			
		||||
	$(info Check which files would be deleted by running: "git clean -n -xdff src")
 | 
			
		||||
	$(info If listed files are acceptable, you can enable the call to "git clean" by creating an empty file named 'allow_git_clean' next to the Makefile.)
 | 
			
		||||
	$(info )
 | 
			
		||||
endif
 | 
			
		||||
							
								
								
									
										239
									
								
								docs/Build.readme.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								docs/Build.readme.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,239 @@
 | 
			
		||||
# How to build Keepass2Android
 | 
			
		||||
 | 
			
		||||
## Overview
 | 
			
		||||
 | 
			
		||||
Keepass2Android is a Mono for Android app. This means that you need Xamarin's Mono for Android to build it. However, it also uses several components written in Java, so there are also Android-Studio projects involved. To make things even worse, parts of the keyboard and kdb-library are written in native code.
 | 
			
		||||
 | 
			
		||||
To build KP2A from scratch, you need:
 | 
			
		||||
- Xamarin's Mono for Android (also included in Visual Studio)
 | 
			
		||||
- Android SDK & NDK
 | 
			
		||||
 | 
			
		||||
Prior to building Keepass2Android, you need to build some of its components (from command line). Then you can build the full project either through Visual Studio, or through command line.
 | 
			
		||||
 | 
			
		||||
By using the command line, you can build on Windows, macOS or Linux.
 | 
			
		||||
 | 
			
		||||
## Prerequisites
 | 
			
		||||
 | 
			
		||||
### Common to all architectures
 | 
			
		||||
- Install Android SDK & NDK (either manually with Google's [sdkmanager](https://developer.android.com/studio/command-line/sdkmanager), or through Android Studio). Visual Studio also installs a version of it, but in the end the directory must be writable and in a path without spaces (see below) so as to be able to build the components.
 | 
			
		||||
- Fetch the main repository of Keepass2Android and all submodules
 | 
			
		||||
    - Note that VisualStudio can do this for you, otherwise run:
 | 
			
		||||
    - `git submodule init && git submodule update`
 | 
			
		||||
 | 
			
		||||
### On Windows or macOS
 | 
			
		||||
- Install Visual Studio (for example 2019) with Xamarin.Android (ie. with capability to build Android apps). This should provide the needed tools like
 | 
			
		||||
    - Xamarin.Android
 | 
			
		||||
    - MSBuild
 | 
			
		||||
    - Java JDK
 | 
			
		||||
- If you plan to build also from the command line:
 | 
			
		||||
    - Install the MSVC build tools of visual studio. They provide the `vcvarsall.bat` file which among other things adds MSBuild to the PATH.
 | 
			
		||||
    - Install [NuGet](https://www.nuget.org/downloads) to build also with "make". Alternatively, on Windows, if you use [chocolatey](https://chocolatey.org), run as administrator:
 | 
			
		||||
      - `choco install nuget.commandline`
 | 
			
		||||
    - Check that you have access to 'GNU make'.
 | 
			
		||||
      - On Windows, it is usually not available by default. But the Android NDK provides it. You can find it in `%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make.exe`.  Alternatively, on Windows, if you use [chocolatey](https://chocolatey.org), run as administrator:
 | 
			
		||||
        - `choco install make`
 | 
			
		||||
      - On macOS, it is usually only installed if you have developer command line tools installed or if you use [homebrew](https://brew.sh) or [macports](https://www.macports.org/). As an alternative it may be available in the Android NDK at `%ANDROID_NDK_ROOT%/prebuilt/darwin-x86_64/bin/make`.
 | 
			
		||||
 | 
			
		||||
### On Linux
 | 
			
		||||
- Install Java's JDK
 | 
			
		||||
    - On Debian, for example: `apt install default-jdk-headless`.
 | 
			
		||||
 | 
			
		||||
- Install [Mono](https://www.mono-project.com/)
 | 
			
		||||
    - This should provide `msbuild` & `xabuild` binary
 | 
			
		||||
    - On Debian, after having added the repo from above, install with `apt install -t <repo_name> mono-devel msbuild`. A value for `<repo_name>` could be `stable-buster` for example, depending on which one you chose. You could also install the `mono-complete` package if you prefer.
 | 
			
		||||
 | 
			
		||||
- Install Xamarin.Android
 | 
			
		||||
  - ~~Option 1: Use the mono-project [CI builds](https://dev.azure.com/xamarin/public/_build/latest?definitionId=48&branchName=main&stageName=Linux)~~ **NOTE:** KP2A now requires Xamarin.Android v13, which is newer than the current CI build; until a more recent CI build is available, this option is unfortunately no longer viable.
 | 
			
		||||
  - Option 2: [Build it from source](https://github.com/xamarin/xamarin-android/blob/master/Documentation/README.md#building-from-source)
 | 
			
		||||
 | 
			
		||||
- Install NuGet package of your distribution
 | 
			
		||||
    - On Debian/Ubuntu: `apt install nuget`
 | 
			
		||||
 | 
			
		||||
- Install [libzip](https://libzip.org/) for your distribution for some Xamarin.Android versions
 | 
			
		||||
  - This may not be relevant anymore: for example, with Xamarin.Android 11.4.99. this is not needed.
 | 
			
		||||
  - Some versions of Xamarin may require `libzip4`. If you are in this case:
 | 
			
		||||
    - On Debian/Ubuntu, install it with `apt install libzip4`.
 | 
			
		||||
    - Other distributions ship only `libzip5`. As a dirty workaround, it's possible to symlink `libzip.so.5` to `libzip.so.4`. Luckily, it appears to be working. For example:
 | 
			
		||||
      - `sudo ln -s /usr/lib/libzip.so.5 /usr/lib/libzip.so.4`
 | 
			
		||||
      - or `sudo ln -s /usr/lib64/libzip.so.5 /usr/lib/libzip.so.4`
 | 
			
		||||
 | 
			
		||||
## Building the required components:
 | 
			
		||||
 | 
			
		||||
This is done on the command line and requires the Android SDK & NDK and Java JDK.
 | 
			
		||||
 | 
			
		||||
### On Windows
 | 
			
		||||
- Setup your environment:
 | 
			
		||||
  - Set these environment variables for Android's SDK & NDK
 | 
			
		||||
    - `ANDROID_HOME` (for example `set ANDROID_HOME=C:\PATH\TO\android-sdk`)
 | 
			
		||||
    - `ANDROID_SDK_ROOT` (for example `set ANDROID_SDK_ROOT=C:\PATH\TO\android-sdk`)
 | 
			
		||||
    - `ANDROID_NDK_ROOT` (for example `set ANDROID_NDK_ROOT=C:\PATH\TO\android-sdk\ndk\version`)
 | 
			
		||||
    
 | 
			
		||||
    **Note:** Care must be taken when setting the above variables to **not** include a trailing backslash in the path. A trailing backslash may cause `make` to fail.
 | 
			
		||||
 | 
			
		||||
    **Note**: If the path to the Android SDK contains spaces, you **must** do one of these:
 | 
			
		||||
    - either put the Android SDK into a path without spaces.
 | 
			
		||||
    - or create a symlink to that path which doesn't contain spaces. Attention: this requires **administrator** priveleges. For example:
 | 
			
		||||
 | 
			
		||||
        ```
 | 
			
		||||
        IF NOT EXIST C:\Android ( MKDIR C:\Android ) && 
 | 
			
		||||
        MKLINK /D C:\Android\android-sdk "C:\Program Files (x86)\Android\android-sdk" 
 | 
			
		||||
        ```
 | 
			
		||||
    This is because [Android NDK doesn't support being installed in a path with spaces](https://github.com/android/ndk/issues/1400).
 | 
			
		||||
 | 
			
		||||
    **Note**: The Android SDK path will require to be writeable because during the build, some missing components might be downloaded & installed.
 | 
			
		||||
 | 
			
		||||
- If you have "GNU make" available on your windows system, you may build by using the Makefile. You can also find a `make` executable in `%ANDROID_NDK_ROOT%\prebuilt\windows-x86_64\bin\make.exe`. To use it, see the instructions for Linux/macOS. Basically, just run `make` or `mingw32-make` depending on which distribution of GNU make for windows you have installed.
 | 
			
		||||
 | 
			
		||||
- Otherwise proceed as below:
 | 
			
		||||
 | 
			
		||||
    1. Build argon2
 | 
			
		||||
 | 
			
		||||
        ```
 | 
			
		||||
        cd src/java/argon2
 | 
			
		||||
        %ANDROID_NDK_ROOT%/ndk-build.cmd
 | 
			
		||||
        ```
 | 
			
		||||
    1. Build the other java components
 | 
			
		||||
 | 
			
		||||
        ```
 | 
			
		||||
        cd src/build-scripts
 | 
			
		||||
        build-java.bat
 | 
			
		||||
        ```
 | 
			
		||||
 | 
			
		||||
        `build-java.bat` will call `gradlew` for several Java modules.
 | 
			
		||||
 | 
			
		||||
**Notes:**
 | 
			
		||||
 | 
			
		||||
 - For building the java parts, it is suggested to keep a short name (e.g. "c:\projects\keepass2android") for the root project directory. Otherwise the Windows path length limit might be hit when building.
 | 
			
		||||
 - Before building the java parts, make sure you have set the ANDROID_HOME variable or create a local.properties file inside the directories with a gradlew file. It is recommended to use the same SDK location as that of the Xamarin build.
 | 
			
		||||
 - On some environments, `make` can fail to properly use the detected `MSBUILD` tools. This seems to be due to long pathnames and/or spaces in pathnames. It may be required to explicitly set the `MSBUILD` path using 8.3 "short" path notation:
 | 
			
		||||
 	- Determine the location of `MSBUILD` (e.g. `C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe`)
 | 
			
		||||
 	- [Generate the "short" path](https://superuser.com/a/728792) of that location (e.g.: `C:\PROGRA~1\MICROS~2\2022\COMMUN~1\MSBuild\Current\Bin\MSBuild.exe`)
 | 
			
		||||
 	- When running `make` specify the location of ``MSBUILD` explicitly (e.g.: `make MSBUILD="C:\PROGRA~1\MICROS~2\2022\COMMUN~1\MSBuild\Current\Bin\MSBuild.exe` 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### On Linux/macOS
 | 
			
		||||
 | 
			
		||||
- Setup your environment:
 | 
			
		||||
  - Set these environment variables for Android's SDK & NDK
 | 
			
		||||
    - `ANDROID_HOME` (for example `export ANDROID_HOME=/path/to/android-sdk/`)
 | 
			
		||||
    - `ANDROID_SDK_ROOT` (for example `export ANDROID_SDK_ROOT=/path/to/android-sdk/`)
 | 
			
		||||
    - `ANDROID_NDK_ROOT` (for example `export ANDROID_NDK_ROOT=/path/to/android-sdk/ndk/version`)
 | 
			
		||||
 | 
			
		||||
- Update your PATH environment variable so that it can access `nuget`, `msbuild` or `xabuild` (for linux):
 | 
			
		||||
    - On Linux:
 | 
			
		||||
        - add `xabuild` to your path: `export PATH=/path/to/xamarin.android-oss/bin/Release/bin/:$PATH`
 | 
			
		||||
    - On macOS:
 | 
			
		||||
        - you may similarly need to add `msbuild` & `nuget` to your PATH.
 | 
			
		||||
 | 
			
		||||
- Start the build:
 | 
			
		||||
    - This will use the Makefile at the root of the project (requires GNU make). To build everything (components & Keepass2Android APK) in a single command simply run:
 | 
			
		||||
 | 
			
		||||
        ```
 | 
			
		||||
        make
 | 
			
		||||
        ```
 | 
			
		||||
 | 
			
		||||
    - Otherwise, if you prefer to do step by step
 | 
			
		||||
 | 
			
		||||
        1. Build argon2
 | 
			
		||||
 | 
			
		||||
            ```
 | 
			
		||||
            make native
 | 
			
		||||
            ```
 | 
			
		||||
 | 
			
		||||
        1. Build the other java components
 | 
			
		||||
 | 
			
		||||
            ```
 | 
			
		||||
            make java
 | 
			
		||||
            ```
 | 
			
		||||
 | 
			
		||||
## Building Keepass2Android:
 | 
			
		||||
 | 
			
		||||
These are the basic steps to build Keepass2Android. You can also build Keepass2Android Offline. For this, configure the build by using the [Flavors](#Flavors).
 | 
			
		||||
 | 
			
		||||
### With Visual Studio
 | 
			
		||||
 | 
			
		||||
- On windows or on macOS open the src/KeePass.sln file with visual studio, and choose to build the project named 'keepass2android-app'
 | 
			
		||||
 | 
			
		||||
### Command Line
 | 
			
		||||
 | 
			
		||||
#### Windows, Macos & Linux
 | 
			
		||||
to build the APK, simply run:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
    make
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
or to skip building the APK:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
    make msbuild
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Where is the APK ?
 | 
			
		||||
The Apk can be installed on a device.
 | 
			
		||||
It is located in `src/keepass2android/bin/*/*-Signed.apk`
 | 
			
		||||
 | 
			
		||||
If you build with Visual Studio, the APK is not produced automatically. You need to perform some extra step. See the documentation of Visual Studio on how to proceed.
 | 
			
		||||
 | 
			
		||||
## Flavors
 | 
			
		||||
 | 
			
		||||
Keepass2Android is distributed in two flavors.
 | 
			
		||||
  - Keepass2Android (aka `net`)
 | 
			
		||||
  - Keepass2Android Offline (aka `nonet`)
 | 
			
		||||
 | 
			
		||||
The flavor is set through a MSBuild Property named "`Flavor`". The possible values are '`Net`' and '`NoNet`'.
 | 
			
		||||
 | 
			
		||||
The value of the Flavor property is used in 2 projects:
 | 
			
		||||
  - `keepass2android-app` (in `src/keepass2android`)
 | 
			
		||||
  - `Kp2aBusinessLogic` (in `src/keepass2android`)
 | 
			
		||||
 | 
			
		||||
Its value is set inside the `*.csproj` file (XML format) of each project in the `Project`/`PropertyGroup`/`Flavor` node.
 | 
			
		||||
By default its value is set to an empty string so that development is made with `AndroidManifest_debug.xml` on the '`net`' flavor.
 | 
			
		||||
 | 
			
		||||
This is the behaviour of the build system depending on the value of Flavor:
 | 
			
		||||
| Flavor                                     | What is built           | `AndroidManifest.xml` used  |
 | 
			
		||||
| -----                                      | -----                   | -----                       |
 | 
			
		||||
| `` (empty string): This is the default value. | Keepass2Android      | `AndroidManifest_debug.xml` |
 | 
			
		||||
| `Net`                                      | Keepass2Android         | `AndroidManifest_net.xml`   |
 | 
			
		||||
| `NoNet`                                    | Keepass2Android Offline | `AndroidManifest_nonet.xml` |
 | 
			
		||||
 | 
			
		||||
### Select/Change flavor:
 | 
			
		||||
 | 
			
		||||
When building, by default, the flavor is not set. So the value used is the value of the Flavor property in *.csproj file. This should result on doing a build of the 'net' flavor.
 | 
			
		||||
 | 
			
		||||
You can force the Flavor by setting the Flavor property.
 | 
			
		||||
 | 
			
		||||
Proceed this way:
 | 
			
		||||
 | 
			
		||||
#### Command line
 | 
			
		||||
 | 
			
		||||
##### Windows, Macos & Linux
 | 
			
		||||
 | 
			
		||||
To force building 'net' with `make`, run:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
    make Flavor=Net
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To build 'nonet' with `make`, run:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
    make Flavor=NoNet
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
##### MSBuild
 | 
			
		||||
 | 
			
		||||
To build with MSBuild directly on the command line, set the flavor with `-p:Flavor=value` argument. For example:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
    MSBuild src/KeePass.sln ... -p:Flavor=NoNet
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Visual Studio
 | 
			
		||||
When building with Visual Studio, edit the `*.csproj` file (XML format) and set the value in the `Project`/`PropertyGroup`/`Flavor` node. This is needed only for the projects that use the flavors.
 | 
			
		||||
 | 
			
		||||
**Note:** When switching between flavors, be sure to clean the previous build before.
 | 
			
		||||
 | 
			
		||||
## Makefile
 | 
			
		||||
 | 
			
		||||
It is possible to override the project's default 'Flavor' (Net, NoNet) and 'Configuration' (Release, Debug) by passing it as argument to `make`. See the header of the Makefile to see what can be done.
 | 
			
		||||
@@ -118,3 +118,5 @@ One of these has helped all users so far, but unfortunately it's not totally cle
 | 
			
		||||
# For developers
 | 
			
		||||
If you are interested in adding new features, you have two options:
 | 
			
		||||
Either your features can be implemented as a plug-in. Please see [How to create a plug-in?](How-to-create-a-plug-in_.md) for more information. Or you add the features directly in the source code of the projects and create a pull request.
 | 
			
		||||
 | 
			
		||||
If you want to build Keepass2Android, check the [build guide](Build.readme.md).
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,9 @@ Beta-releases can be obtained by opting in to the [Beta testing channel](https:/
 | 
			
		||||
# How do I learn more?
 | 
			
		||||
Please see the [documentation](Documentation.md).
 | 
			
		||||
 | 
			
		||||
# How do I build the project?
 | 
			
		||||
If you want to build Keepass2Android, check the [build guide](Build.readme.md).
 | 
			
		||||
 | 
			
		||||
The project homepage is https://philipp.crocoll.net/keepass2android/index.php
 | 
			
		||||
 | 
			
		||||
[](https://www.bitrise.io/app/43a23ab54dee9f7e)
 | 
			
		||||
<img src="https://github.com/PhilippC/keepass2android/actions/workflows/build.yml/badge.svg" alt="build status" /> [Build status](https://github.com/PhilippC/keepass2android/actions)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<packages>
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices" version="27.0.0.0" />
 | 
			
		||||
</packages>
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
    <TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
 | 
			
		||||
    <AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
 | 
			
		||||
    <AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
 | 
			
		||||
    <AndroidClassParser>class-parse</AndroidClassParser>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
			
		||||
    <DebugSymbols>true</DebugSymbols>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Build.Download.0.10.0\build\Xamarin.Build.Download.props" Condition="Exists('..\packages\Xamarin.Build.Download.0.10.0\build\Xamarin.Build.Download.props')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Migration.1.0.8\build\monoandroid90\Xamarin.AndroidX.Migration.props" Condition="Exists('..\packages\Xamarin.AndroidX.Migration.1.0.8\build\monoandroid90\Xamarin.AndroidX.Migration.props')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Build.Download.0.11.4\build\Xamarin.Build.Download.props" Condition="Exists('..\packages\Xamarin.Build.Download.0.11.4\build\Xamarin.Build.Download.props')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Migration.1.0.10\build\monoandroid120\Xamarin.AndroidX.Migration.props" Condition="Exists('..\packages\Xamarin.AndroidX.Migration.1.0.10\build\monoandroid120\Xamarin.AndroidX.Migration.props')" />
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
 | 
			
		||||
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
 | 
			
		||||
@@ -13,7 +13,7 @@
 | 
			
		||||
    <AssemblyName>JavaFileStorageBindings</AssemblyName>
 | 
			
		||||
    <FileAlignment>512</FileAlignment>
 | 
			
		||||
    <AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
 | 
			
		||||
    <TargetFrameworkVersion>v9.0</TargetFrameworkVersion>
 | 
			
		||||
    <TargetFrameworkVersion>v13.0</TargetFrameworkVersion>
 | 
			
		||||
    <AndroidClassParser>class-parse</AndroidClassParser>
 | 
			
		||||
    <AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
 | 
			
		||||
    <NuGetPackageImportStamp>
 | 
			
		||||
@@ -58,6 +58,72 @@
 | 
			
		||||
    <Reference Include="System.Numerics" />
 | 
			
		||||
    <Reference Include="System.Numerics.Vectors" />
 | 
			
		||||
    <Reference Include="System.Xml" />
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Activity, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Activity.1.6.0\lib\monoandroid12.0\Xamarin.AndroidX.Activity.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Annotation, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Annotation.1.5.0\lib\monoandroid12.0\Xamarin.AndroidX.Annotation.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Annotation.Experimental, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Annotation.Experimental.1.3.0\lib\monoandroid12.0\Xamarin.AndroidX.Annotation.Experimental.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Arch.Core.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Arch.Core.Common.2.1.0.15\lib\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Common.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Arch.Core.Runtime, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Arch.Core.Runtime.2.1.0.15\lib\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Runtime.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Collection, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Collection.1.2.0.4\lib\monoandroid12.0\Xamarin.AndroidX.Collection.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Concurrent.Futures, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Concurrent.Futures.1.1.0.9\lib\monoandroid12.0\Xamarin.AndroidX.Concurrent.Futures.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Core.1.9.0\lib\monoandroid12.0\Xamarin.AndroidX.Core.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Core.Core.Ktx, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Core.Core.Ktx.1.9.0\lib\monoandroid12.0\Xamarin.AndroidX.Core.Core.Ktx.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.CustomView, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.CustomView.1.1.0.13\lib\monoandroid12.0\Xamarin.AndroidX.CustomView.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Fragment, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Fragment.1.5.3\lib\monoandroid12.0\Xamarin.AndroidX.Fragment.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Lifecycle.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Lifecycle.Common.2.5.1\lib\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Common.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Lifecycle.LiveData.Core, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Lifecycle.LiveData.Core.2.5.1\lib\monoandroid12.0\Xamarin.AndroidX.Lifecycle.LiveData.Core.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Lifecycle.Runtime, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Lifecycle.Runtime.2.5.1\lib\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Runtime.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Lifecycle.ViewModel, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Lifecycle.ViewModel.2.5.1\lib\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModel.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Lifecycle.ViewModelSavedState, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.2.5.1\lib\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Loader, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Loader.1.1.0.14\lib\monoandroid12.0\Xamarin.AndroidX.Loader.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.MultiDex, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.MultiDex.2.0.1.13\lib\monoandroid12.0\Xamarin.AndroidX.MultiDex.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.SavedState, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.SavedState.1.2.0\lib\monoandroid12.0\Xamarin.AndroidX.SavedState.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.Tracing.Tracing, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.Tracing.Tracing.1.1.0.1\lib\monoandroid12.0\Xamarin.AndroidX.Tracing.Tracing.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.VersionedParcelable, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.VersionedParcelable.1.1.1.14\lib\monoandroid12.0\Xamarin.AndroidX.VersionedParcelable.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.AndroidX.ViewPager, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.AndroidX.ViewPager.1.0.0.14\lib\monoandroid12.0\Xamarin.AndroidX.ViewPager.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.Google.Guava, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.Google.Guava.28.2.0.1\lib\monoandroid90\Xamarin.Google.Guava.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
@@ -65,7 +131,49 @@
 | 
			
		||||
      <HintPath>..\packages\Xamarin.Google.Guava.FailureAccess.1.0.1.3\lib\monoandroid90\Xamarin.Google.Guava.FailureAccess.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.Google.Guava.ListenableFuture, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.Google.Guava.ListenableFuture.1.0.0.3\lib\monoandroid90\Xamarin.Google.Guava.ListenableFuture.dll</HintPath>
 | 
			
		||||
      <HintPath>..\packages\Xamarin.Google.Guava.ListenableFuture.1.0.0.9\lib\monoandroid12.0\Xamarin.Google.Guava.ListenableFuture.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.GooglePlayServices.Auth, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.GooglePlayServices.Auth.120.4.0\lib\monoandroid12.0\Xamarin.GooglePlayServices.Auth.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.GooglePlayServices.Auth.Api.Phone, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.GooglePlayServices.Auth.Api.Phone.118.0.1.2\lib\monoandroid12.0\Xamarin.GooglePlayServices.Auth.Api.Phone.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.GooglePlayServices.Auth.Base, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.GooglePlayServices.Auth.Base.118.0.6\lib\monoandroid12.0\Xamarin.GooglePlayServices.Auth.Base.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.GooglePlayServices.Base, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.GooglePlayServices.Base.118.1.0\lib\monoandroid12.0\Xamarin.GooglePlayServices.Base.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.GooglePlayServices.Basement, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.GooglePlayServices.Basement.118.1.0.1\lib\monoandroid12.0\Xamarin.GooglePlayServices.Basement.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.GooglePlayServices.Fido, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.GooglePlayServices.Fido.119.0.0\lib\monoandroid12.0\Xamarin.GooglePlayServices.Fido.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.GooglePlayServices.Tasks, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.GooglePlayServices.Tasks.118.0.2\lib\monoandroid12.0\Xamarin.GooglePlayServices.Tasks.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.Jetbrains.Annotations, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.Jetbrains.Annotations.23.0.0.4\lib\monoandroid12.0\Xamarin.Jetbrains.Annotations.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.Kotlin.StdLib, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.Kotlin.StdLib.1.7.10\lib\monoandroid12.0\Xamarin.Kotlin.StdLib.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.Kotlin.StdLib.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.Kotlin.StdLib.Common.1.7.10\lib\monoandroid12.0\Xamarin.Kotlin.StdLib.Common.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.Kotlin.StdLib.Jdk7, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.Kotlin.StdLib.Jdk7.1.7.10\lib\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk7.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.Kotlin.StdLib.Jdk8, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.Kotlin.StdLib.Jdk8.1.7.10\lib\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk8.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.KotlinX.Coroutines.Android, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.KotlinX.Coroutines.Android.1.6.4\lib\monoandroid12.0\Xamarin.KotlinX.Coroutines.Android.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
    <Reference Include="Xamarin.KotlinX.Coroutines.Core.Jvm, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
 | 
			
		||||
      <HintPath>..\packages\Xamarin.KotlinX.Coroutines.Core.Jvm.1.6.4\lib\monoandroid12.0\Xamarin.KotlinX.Coroutines.Core.Jvm.dll</HintPath>
 | 
			
		||||
    </Reference>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
@@ -182,69 +290,93 @@
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <EmbeddedReferenceJar Include="Jars\gdrive\opencensus-api-0.24.0.jar" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Annotation.Experimental.1.0.0.9\build\monoandroid9.0\Xamarin.AndroidX.Annotation.Experimental.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Annotation.Experimental.1.0.0.9\build\monoandroid9.0\Xamarin.AndroidX.Annotation.Experimental.targets')" />
 | 
			
		||||
  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
 | 
			
		||||
    <PropertyGroup>
 | 
			
		||||
      <ErrorText>Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".</ErrorText>
 | 
			
		||||
    </PropertyGroup>
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Annotation.Experimental.1.0.0.9\build\monoandroid9.0\Xamarin.AndroidX.Annotation.Experimental.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Annotation.Experimental.1.0.0.9\build\monoandroid9.0\Xamarin.AndroidX.Annotation.Experimental.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.MultiDex.2.0.1.5\build\monoandroid90\Xamarin.AndroidX.MultiDex.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.MultiDex.2.0.1.5\build\monoandroid90\Xamarin.AndroidX.MultiDex.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Migration.1.0.8\build\monoandroid90\Xamarin.AndroidX.Migration.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Migration.1.0.8\build\monoandroid90\Xamarin.AndroidX.Migration.props'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Migration.1.0.8\build\monoandroid90\Xamarin.AndroidX.Migration.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Migration.1.0.8\build\monoandroid90\Xamarin.AndroidX.Migration.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Annotation.1.2.0\build\monoandroid9.0\Xamarin.AndroidX.Annotation.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Annotation.1.2.0\build\monoandroid9.0\Xamarin.AndroidX.Annotation.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Arch.Core.Common.2.1.0.8\build\monoandroid9.0\Xamarin.AndroidX.Arch.Core.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Arch.Core.Common.2.1.0.8\build\monoandroid9.0\Xamarin.AndroidX.Arch.Core.Common.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Collection.1.1.0.7\build\monoandroid9.0\Xamarin.AndroidX.Collection.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Collection.1.1.0.7\build\monoandroid9.0\Xamarin.AndroidX.Collection.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Lifecycle.Common.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Lifecycle.Common.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.Common.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Lifecycle.LiveData.Core.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.LiveData.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Lifecycle.LiveData.Core.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.LiveData.Core.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Lifecycle.Runtime.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.Runtime.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Lifecycle.Runtime.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.Runtime.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Lifecycle.ViewModel.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.ViewModel.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Lifecycle.ViewModel.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.ViewModel.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.SavedState.1.1.0.1\build\monoandroid9.0\Xamarin.AndroidX.SavedState.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.SavedState.1.1.0.1\build\monoandroid9.0\Xamarin.AndroidX.SavedState.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.VersionedParcelable.1.1.1.7\build\monoandroid9.0\Xamarin.AndroidX.VersionedParcelable.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.VersionedParcelable.1.1.1.7\build\monoandroid9.0\Xamarin.AndroidX.VersionedParcelable.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Core.1.3.2.3\build\monoandroid9.0\Xamarin.AndroidX.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Core.1.3.2.3\build\monoandroid9.0\Xamarin.AndroidX.Core.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Activity.1.2.2\build\monoandroid9.0\Xamarin.AndroidX.Activity.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Activity.1.2.2\build\monoandroid9.0\Xamarin.AndroidX.Activity.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.CustomView.1.1.0.6\build\monoandroid9.0\Xamarin.AndroidX.CustomView.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.CustomView.1.1.0.6\build\monoandroid9.0\Xamarin.AndroidX.CustomView.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Loader.1.1.0.7\build\monoandroid9.0\Xamarin.AndroidX.Loader.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Loader.1.1.0.7\build\monoandroid9.0\Xamarin.AndroidX.Loader.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.ViewPager.1.0.0.7\build\monoandroid9.0\Xamarin.AndroidX.ViewPager.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.ViewPager.1.0.0.7\build\monoandroid9.0\Xamarin.AndroidX.ViewPager.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Fragment.1.3.2\build\monoandroid9.0\Xamarin.AndroidX.Fragment.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Fragment.1.3.2\build\monoandroid9.0\Xamarin.AndroidX.Fragment.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Build.Download.0.10.0\build\Xamarin.Build.Download.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Build.Download.0.10.0\build\Xamarin.Build.Download.props'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Build.Download.0.10.0\build\Xamarin.Build.Download.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Build.Download.0.10.0\build\Xamarin.Build.Download.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Basement.117.6.0.4\build\monoandroid90\Xamarin.GooglePlayServices.Basement.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Basement.117.6.0.4\build\monoandroid90\Xamarin.GooglePlayServices.Basement.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Tasks.117.2.1.3\build\monoandroid90\Xamarin.GooglePlayServices.Tasks.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Tasks.117.2.1.3\build\monoandroid90\Xamarin.GooglePlayServices.Tasks.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Base.117.6.0.3\build\monoandroid90\Xamarin.GooglePlayServices.Base.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Base.117.6.0.3\build\monoandroid90\Xamarin.GooglePlayServices.Base.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Auth.Api.Phone.117.5.1.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.Api.Phone.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Auth.Api.Phone.117.5.1.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.Api.Phone.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Auth.Base.117.1.4.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.Base.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Auth.Base.117.1.4.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.Base.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Auth.119.2.0.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Auth.119.2.0.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Google.Guava.FailureAccess.1.0.1.3\build\monoandroid90\Xamarin.Google.Guava.FailureAccess.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Google.Guava.FailureAccess.1.0.1.3\build\monoandroid90\Xamarin.Google.Guava.FailureAccess.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Google.Guava.ListenableFuture.1.0.0.3\build\monoandroid90\Xamarin.Google.Guava.ListenableFuture.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Google.Guava.ListenableFuture.1.0.0.3\build\monoandroid90\Xamarin.Google.Guava.ListenableFuture.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Google.Guava.28.2.0.1\build\monoandroid90\Xamarin.Google.Guava.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Google.Guava.28.2.0.1\build\monoandroid90\Xamarin.Google.Guava.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.MultiDex.2.0.1.13\build\monoandroid12.0\Xamarin.AndroidX.MultiDex.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.MultiDex.2.0.1.13\build\monoandroid12.0\Xamarin.AndroidX.MultiDex.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Migration.1.0.10\build\monoandroid120\Xamarin.AndroidX.Migration.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Migration.1.0.10\build\monoandroid120\Xamarin.AndroidX.Migration.props'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Migration.1.0.10\build\monoandroid120\Xamarin.AndroidX.Migration.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Migration.1.0.10\build\monoandroid120\Xamarin.AndroidX.Migration.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Build.Download.0.11.4\build\Xamarin.Build.Download.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Build.Download.0.11.4\build\Xamarin.Build.Download.props'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Build.Download.0.11.4\build\Xamarin.Build.Download.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Build.Download.0.11.4\build\Xamarin.Build.Download.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Google.Guava.ListenableFuture.1.0.0.9\build\monoandroid12.0\Xamarin.Google.Guava.ListenableFuture.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Google.Guava.ListenableFuture.1.0.0.9\build\monoandroid12.0\Xamarin.Google.Guava.ListenableFuture.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Jetbrains.Annotations.23.0.0.4\build\monoandroid12.0\Xamarin.Jetbrains.Annotations.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Jetbrains.Annotations.23.0.0.4\build\monoandroid12.0\Xamarin.Jetbrains.Annotations.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Kotlin.StdLib.Common.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Kotlin.StdLib.Common.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Common.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Kotlin.StdLib.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Kotlin.StdLib.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Annotation.1.5.0\build\monoandroid12.0\Xamarin.AndroidX.Annotation.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Annotation.1.5.0\build\monoandroid12.0\Xamarin.AndroidX.Annotation.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Annotation.Experimental.1.3.0\build\monoandroid12.0\Xamarin.AndroidX.Annotation.Experimental.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Annotation.Experimental.1.3.0\build\monoandroid12.0\Xamarin.AndroidX.Annotation.Experimental.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Arch.Core.Common.2.1.0.15\build\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Arch.Core.Common.2.1.0.15\build\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Common.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Arch.Core.Runtime.2.1.0.15\build\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Runtime.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Arch.Core.Runtime.2.1.0.15\build\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Runtime.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Collection.1.2.0.4\build\monoandroid12.0\Xamarin.AndroidX.Collection.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Collection.1.2.0.4\build\monoandroid12.0\Xamarin.AndroidX.Collection.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Concurrent.Futures.1.1.0.9\build\monoandroid12.0\Xamarin.AndroidX.Concurrent.Futures.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Concurrent.Futures.1.1.0.9\build\monoandroid12.0\Xamarin.AndroidX.Concurrent.Futures.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Lifecycle.Common.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Common.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Lifecycle.Common.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Common.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Lifecycle.LiveData.Core.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.LiveData.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Lifecycle.LiveData.Core.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.LiveData.Core.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Lifecycle.Runtime.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Runtime.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Lifecycle.Runtime.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Runtime.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Lifecycle.ViewModel.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModel.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Lifecycle.ViewModel.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModel.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.SavedState.1.2.0\build\monoandroid12.0\Xamarin.AndroidX.SavedState.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.SavedState.1.2.0\build\monoandroid12.0\Xamarin.AndroidX.SavedState.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Tracing.Tracing.1.1.0.1\build\monoandroid12.0\Xamarin.AndroidX.Tracing.Tracing.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Tracing.Tracing.1.1.0.1\build\monoandroid12.0\Xamarin.AndroidX.Tracing.Tracing.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.VersionedParcelable.1.1.1.14\build\monoandroid12.0\Xamarin.AndroidX.VersionedParcelable.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.VersionedParcelable.1.1.1.14\build\monoandroid12.0\Xamarin.AndroidX.VersionedParcelable.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Core.1.9.0\build\monoandroid12.0\Xamarin.AndroidX.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Core.1.9.0\build\monoandroid12.0\Xamarin.AndroidX.Core.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Core.Core.Ktx.1.9.0\build\monoandroid12.0\Xamarin.AndroidX.Core.Core.Ktx.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Core.Core.Ktx.1.9.0\build\monoandroid12.0\Xamarin.AndroidX.Core.Core.Ktx.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.CustomView.1.1.0.13\build\monoandroid12.0\Xamarin.AndroidX.CustomView.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.CustomView.1.1.0.13\build\monoandroid12.0\Xamarin.AndroidX.CustomView.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Loader.1.1.0.14\build\monoandroid12.0\Xamarin.AndroidX.Loader.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Loader.1.1.0.14\build\monoandroid12.0\Xamarin.AndroidX.Loader.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.ViewPager.1.0.0.14\build\monoandroid12.0\Xamarin.AndroidX.ViewPager.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.ViewPager.1.0.0.14\build\monoandroid12.0\Xamarin.AndroidX.ViewPager.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Kotlin.StdLib.Jdk7.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk7.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Kotlin.StdLib.Jdk7.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk7.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.Kotlin.StdLib.Jdk8.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk8.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.Kotlin.StdLib.Jdk8.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk8.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.KotlinX.Coroutines.Core.Jvm.1.6.4\build\monoandroid12.0\Xamarin.KotlinX.Coroutines.Core.Jvm.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.KotlinX.Coroutines.Core.Jvm.1.6.4\build\monoandroid12.0\Xamarin.KotlinX.Coroutines.Core.Jvm.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.KotlinX.Coroutines.Android.1.6.4\build\monoandroid12.0\Xamarin.KotlinX.Coroutines.Android.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.KotlinX.Coroutines.Android.1.6.4\build\monoandroid12.0\Xamarin.KotlinX.Coroutines.Android.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Activity.1.6.0\build\monoandroid12.0\Xamarin.AndroidX.Activity.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Activity.1.6.0\build\monoandroid12.0\Xamarin.AndroidX.Activity.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.AndroidX.Fragment.1.5.3\build\monoandroid12.0\Xamarin.AndroidX.Fragment.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.AndroidX.Fragment.1.5.3\build\monoandroid12.0\Xamarin.AndroidX.Fragment.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Basement.118.1.0.1\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Basement.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Basement.118.1.0.1\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Basement.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Tasks.118.0.2\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Tasks.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Tasks.118.0.2\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Tasks.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Base.118.1.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Base.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Base.118.1.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Base.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Auth.Api.Phone.118.0.1.2\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.Api.Phone.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Auth.Api.Phone.118.0.1.2\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.Api.Phone.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Auth.Base.118.0.6\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.Base.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Auth.Base.118.0.6\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.Base.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Fido.119.0.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Fido.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Fido.119.0.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Fido.targets'))" />
 | 
			
		||||
    <Error Condition="!Exists('..\packages\Xamarin.GooglePlayServices.Auth.120.4.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Xamarin.GooglePlayServices.Auth.120.4.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.targets'))" />
 | 
			
		||||
  </Target>
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.MultiDex.2.0.1.5\build\monoandroid90\Xamarin.AndroidX.MultiDex.targets" Condition="Exists('..\packages\Xamarin.AndroidX.MultiDex.2.0.1.5\build\monoandroid90\Xamarin.AndroidX.MultiDex.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Migration.1.0.8\build\monoandroid90\Xamarin.AndroidX.Migration.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Migration.1.0.8\build\monoandroid90\Xamarin.AndroidX.Migration.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Annotation.1.2.0\build\monoandroid9.0\Xamarin.AndroidX.Annotation.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Annotation.1.2.0\build\monoandroid9.0\Xamarin.AndroidX.Annotation.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Arch.Core.Common.2.1.0.8\build\monoandroid9.0\Xamarin.AndroidX.Arch.Core.Common.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Arch.Core.Common.2.1.0.8\build\monoandroid9.0\Xamarin.AndroidX.Arch.Core.Common.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Collection.1.1.0.7\build\monoandroid9.0\Xamarin.AndroidX.Collection.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Collection.1.1.0.7\build\monoandroid9.0\Xamarin.AndroidX.Collection.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Lifecycle.Common.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.Common.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Lifecycle.Common.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.Common.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Lifecycle.LiveData.Core.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.LiveData.Core.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Lifecycle.LiveData.Core.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.LiveData.Core.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Lifecycle.Runtime.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.Runtime.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Lifecycle.Runtime.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.Runtime.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Lifecycle.ViewModel.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.ViewModel.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Lifecycle.ViewModel.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.ViewModel.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.SavedState.1.1.0.1\build\monoandroid9.0\Xamarin.AndroidX.SavedState.targets" Condition="Exists('..\packages\Xamarin.AndroidX.SavedState.1.1.0.1\build\monoandroid9.0\Xamarin.AndroidX.SavedState.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.2.3.1\build\monoandroid9.0\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.VersionedParcelable.1.1.1.7\build\monoandroid9.0\Xamarin.AndroidX.VersionedParcelable.targets" Condition="Exists('..\packages\Xamarin.AndroidX.VersionedParcelable.1.1.1.7\build\monoandroid9.0\Xamarin.AndroidX.VersionedParcelable.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Core.1.3.2.3\build\monoandroid9.0\Xamarin.AndroidX.Core.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Core.1.3.2.3\build\monoandroid9.0\Xamarin.AndroidX.Core.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Activity.1.2.2\build\monoandroid9.0\Xamarin.AndroidX.Activity.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Activity.1.2.2\build\monoandroid9.0\Xamarin.AndroidX.Activity.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.CustomView.1.1.0.6\build\monoandroid9.0\Xamarin.AndroidX.CustomView.targets" Condition="Exists('..\packages\Xamarin.AndroidX.CustomView.1.1.0.6\build\monoandroid9.0\Xamarin.AndroidX.CustomView.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Loader.1.1.0.7\build\monoandroid9.0\Xamarin.AndroidX.Loader.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Loader.1.1.0.7\build\monoandroid9.0\Xamarin.AndroidX.Loader.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.ViewPager.1.0.0.7\build\monoandroid9.0\Xamarin.AndroidX.ViewPager.targets" Condition="Exists('..\packages\Xamarin.AndroidX.ViewPager.1.0.0.7\build\monoandroid9.0\Xamarin.AndroidX.ViewPager.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Fragment.1.3.2\build\monoandroid9.0\Xamarin.AndroidX.Fragment.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Fragment.1.3.2\build\monoandroid9.0\Xamarin.AndroidX.Fragment.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Build.Download.0.10.0\build\Xamarin.Build.Download.targets" Condition="Exists('..\packages\Xamarin.Build.Download.0.10.0\build\Xamarin.Build.Download.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Basement.117.6.0.4\build\monoandroid90\Xamarin.GooglePlayServices.Basement.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Basement.117.6.0.4\build\monoandroid90\Xamarin.GooglePlayServices.Basement.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Tasks.117.2.1.3\build\monoandroid90\Xamarin.GooglePlayServices.Tasks.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Tasks.117.2.1.3\build\monoandroid90\Xamarin.GooglePlayServices.Tasks.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Base.117.6.0.3\build\monoandroid90\Xamarin.GooglePlayServices.Base.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Base.117.6.0.3\build\monoandroid90\Xamarin.GooglePlayServices.Base.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Auth.Api.Phone.117.5.1.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.Api.Phone.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Auth.Api.Phone.117.5.1.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.Api.Phone.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Auth.Base.117.1.4.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.Base.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Auth.Base.117.1.4.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.Base.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Auth.119.2.0.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Auth.119.2.0.3\build\monoandroid90\Xamarin.GooglePlayServices.Auth.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Google.Guava.FailureAccess.1.0.1.3\build\monoandroid90\Xamarin.Google.Guava.FailureAccess.targets" Condition="Exists('..\packages\Xamarin.Google.Guava.FailureAccess.1.0.1.3\build\monoandroid90\Xamarin.Google.Guava.FailureAccess.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Google.Guava.ListenableFuture.1.0.0.3\build\monoandroid90\Xamarin.Google.Guava.ListenableFuture.targets" Condition="Exists('..\packages\Xamarin.Google.Guava.ListenableFuture.1.0.0.3\build\monoandroid90\Xamarin.Google.Guava.ListenableFuture.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Google.Guava.28.2.0.1\build\monoandroid90\Xamarin.Google.Guava.targets" Condition="Exists('..\packages\Xamarin.Google.Guava.28.2.0.1\build\monoandroid90\Xamarin.Google.Guava.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.MultiDex.2.0.1.13\build\monoandroid12.0\Xamarin.AndroidX.MultiDex.targets" Condition="Exists('..\packages\Xamarin.AndroidX.MultiDex.2.0.1.13\build\monoandroid12.0\Xamarin.AndroidX.MultiDex.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Migration.1.0.10\build\monoandroid120\Xamarin.AndroidX.Migration.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Migration.1.0.10\build\monoandroid120\Xamarin.AndroidX.Migration.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Build.Download.0.11.4\build\Xamarin.Build.Download.targets" Condition="Exists('..\packages\Xamarin.Build.Download.0.11.4\build\Xamarin.Build.Download.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Google.Guava.ListenableFuture.1.0.0.9\build\monoandroid12.0\Xamarin.Google.Guava.ListenableFuture.targets" Condition="Exists('..\packages\Xamarin.Google.Guava.ListenableFuture.1.0.0.9\build\monoandroid12.0\Xamarin.Google.Guava.ListenableFuture.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Jetbrains.Annotations.23.0.0.4\build\monoandroid12.0\Xamarin.Jetbrains.Annotations.targets" Condition="Exists('..\packages\Xamarin.Jetbrains.Annotations.23.0.0.4\build\monoandroid12.0\Xamarin.Jetbrains.Annotations.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Kotlin.StdLib.Common.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Common.targets" Condition="Exists('..\packages\Xamarin.Kotlin.StdLib.Common.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Common.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Kotlin.StdLib.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.targets" Condition="Exists('..\packages\Xamarin.Kotlin.StdLib.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Annotation.1.5.0\build\monoandroid12.0\Xamarin.AndroidX.Annotation.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Annotation.1.5.0\build\monoandroid12.0\Xamarin.AndroidX.Annotation.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Annotation.Experimental.1.3.0\build\monoandroid12.0\Xamarin.AndroidX.Annotation.Experimental.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Annotation.Experimental.1.3.0\build\monoandroid12.0\Xamarin.AndroidX.Annotation.Experimental.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Arch.Core.Common.2.1.0.15\build\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Common.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Arch.Core.Common.2.1.0.15\build\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Common.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Arch.Core.Runtime.2.1.0.15\build\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Runtime.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Arch.Core.Runtime.2.1.0.15\build\monoandroid12.0\Xamarin.AndroidX.Arch.Core.Runtime.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Collection.1.2.0.4\build\monoandroid12.0\Xamarin.AndroidX.Collection.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Collection.1.2.0.4\build\monoandroid12.0\Xamarin.AndroidX.Collection.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Concurrent.Futures.1.1.0.9\build\monoandroid12.0\Xamarin.AndroidX.Concurrent.Futures.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Concurrent.Futures.1.1.0.9\build\monoandroid12.0\Xamarin.AndroidX.Concurrent.Futures.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Lifecycle.Common.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Common.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Lifecycle.Common.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Common.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Lifecycle.LiveData.Core.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.LiveData.Core.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Lifecycle.LiveData.Core.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.LiveData.Core.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Lifecycle.Runtime.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Runtime.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Lifecycle.Runtime.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.Runtime.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Lifecycle.ViewModel.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModel.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Lifecycle.ViewModel.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModel.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.SavedState.1.2.0\build\monoandroid12.0\Xamarin.AndroidX.SavedState.targets" Condition="Exists('..\packages\Xamarin.AndroidX.SavedState.1.2.0\build\monoandroid12.0\Xamarin.AndroidX.SavedState.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Tracing.Tracing.1.1.0.1\build\monoandroid12.0\Xamarin.AndroidX.Tracing.Tracing.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Tracing.Tracing.1.1.0.1\build\monoandroid12.0\Xamarin.AndroidX.Tracing.Tracing.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.VersionedParcelable.1.1.1.14\build\monoandroid12.0\Xamarin.AndroidX.VersionedParcelable.targets" Condition="Exists('..\packages\Xamarin.AndroidX.VersionedParcelable.1.1.1.14\build\monoandroid12.0\Xamarin.AndroidX.VersionedParcelable.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Core.1.9.0\build\monoandroid12.0\Xamarin.AndroidX.Core.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Core.1.9.0\build\monoandroid12.0\Xamarin.AndroidX.Core.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Core.Core.Ktx.1.9.0\build\monoandroid12.0\Xamarin.AndroidX.Core.Core.Ktx.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Core.Core.Ktx.1.9.0\build\monoandroid12.0\Xamarin.AndroidX.Core.Core.Ktx.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.CustomView.1.1.0.13\build\monoandroid12.0\Xamarin.AndroidX.CustomView.targets" Condition="Exists('..\packages\Xamarin.AndroidX.CustomView.1.1.0.13\build\monoandroid12.0\Xamarin.AndroidX.CustomView.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Loader.1.1.0.14\build\monoandroid12.0\Xamarin.AndroidX.Loader.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Loader.1.1.0.14\build\monoandroid12.0\Xamarin.AndroidX.Loader.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.ViewPager.1.0.0.14\build\monoandroid12.0\Xamarin.AndroidX.ViewPager.targets" Condition="Exists('..\packages\Xamarin.AndroidX.ViewPager.1.0.0.14\build\monoandroid12.0\Xamarin.AndroidX.ViewPager.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Kotlin.StdLib.Jdk7.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk7.targets" Condition="Exists('..\packages\Xamarin.Kotlin.StdLib.Jdk7.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk7.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.Kotlin.StdLib.Jdk8.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk8.targets" Condition="Exists('..\packages\Xamarin.Kotlin.StdLib.Jdk8.1.7.10\build\monoandroid12.0\Xamarin.Kotlin.StdLib.Jdk8.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.KotlinX.Coroutines.Core.Jvm.1.6.4\build\monoandroid12.0\Xamarin.KotlinX.Coroutines.Core.Jvm.targets" Condition="Exists('..\packages\Xamarin.KotlinX.Coroutines.Core.Jvm.1.6.4\build\monoandroid12.0\Xamarin.KotlinX.Coroutines.Core.Jvm.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.KotlinX.Coroutines.Android.1.6.4\build\monoandroid12.0\Xamarin.KotlinX.Coroutines.Android.targets" Condition="Exists('..\packages\Xamarin.KotlinX.Coroutines.Android.1.6.4\build\monoandroid12.0\Xamarin.KotlinX.Coroutines.Android.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.2.5.1\build\monoandroid12.0\Xamarin.AndroidX.Lifecycle.ViewModelSavedState.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Activity.1.6.0\build\monoandroid12.0\Xamarin.AndroidX.Activity.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Activity.1.6.0\build\monoandroid12.0\Xamarin.AndroidX.Activity.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.AndroidX.Fragment.1.5.3\build\monoandroid12.0\Xamarin.AndroidX.Fragment.targets" Condition="Exists('..\packages\Xamarin.AndroidX.Fragment.1.5.3\build\monoandroid12.0\Xamarin.AndroidX.Fragment.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Basement.118.1.0.1\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Basement.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Basement.118.1.0.1\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Basement.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Tasks.118.0.2\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Tasks.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Tasks.118.0.2\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Tasks.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Base.118.1.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Base.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Base.118.1.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Base.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Auth.Api.Phone.118.0.1.2\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.Api.Phone.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Auth.Api.Phone.118.0.1.2\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.Api.Phone.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Auth.Base.118.0.6\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.Base.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Auth.Base.118.0.6\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.Base.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Fido.119.0.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Fido.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Fido.119.0.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Fido.targets')" />
 | 
			
		||||
  <Import Project="..\packages\Xamarin.GooglePlayServices.Auth.120.4.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.targets" Condition="Exists('..\packages\Xamarin.GooglePlayServices.Auth.120.4.0\build\MonoAndroid12.0\Xamarin.GooglePlayServices.Auth.targets')" />
 | 
			
		||||
</Project>
 | 
			
		||||
@@ -1,32 +1,44 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<packages>
 | 
			
		||||
  <package id="Xamarin.AndroidX.Activity" version="1.2.2" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Annotation" version="1.2.0" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Annotation.Experimental" version="1.0.0.9" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Arch.Core.Common" version="2.1.0.8" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Collection" version="1.1.0.7" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Core" version="1.3.2.3" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.CustomView" version="1.1.0.6" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Fragment" version="1.3.2" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Lifecycle.Common" version="2.3.1" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Lifecycle.LiveData.Core" version="2.3.1" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Lifecycle.Runtime" version="2.3.1" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Lifecycle.ViewModel" version="2.3.1" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Lifecycle.ViewModelSavedState" version="2.3.1" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Loader" version="1.1.0.7" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Migration" version="1.0.8" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.MultiDex" version="2.0.1.5" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.SavedState" version="1.1.0.1" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.VersionedParcelable" version="1.1.1.7" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.ViewPager" version="1.0.0.7" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.Build.Download" version="0.10.0" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Activity" version="1.6.0" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Annotation" version="1.5.0" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Annotation.Experimental" version="1.3.0" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Arch.Core.Common" version="2.1.0.15" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Arch.Core.Runtime" version="2.1.0.15" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Collection" version="1.2.0.4" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Concurrent.Futures" version="1.1.0.9" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Core" version="1.9.0" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Core.Core.Ktx" version="1.9.0" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.CustomView" version="1.1.0.13" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Fragment" version="1.5.3" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Lifecycle.Common" version="2.5.1" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Lifecycle.LiveData.Core" version="2.5.1" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Lifecycle.Runtime" version="2.5.1" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Lifecycle.ViewModel" version="2.5.1" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Lifecycle.ViewModelSavedState" version="2.5.1" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Loader" version="1.1.0.14" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Migration" version="1.0.10" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.MultiDex" version="2.0.1.13" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.SavedState" version="1.2.0" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.Tracing.Tracing" version="1.1.0.1" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.VersionedParcelable" version="1.1.1.14" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.AndroidX.ViewPager" version="1.0.0.14" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.Build.Download" version="0.11.4" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.Google.Guava" version="28.2.0.1" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.Google.Guava.FailureAccess" version="1.0.1.3" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.Google.Guava.ListenableFuture" version="1.0.0.3" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Auth" version="119.2.0.3" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Auth.Api.Phone" version="117.5.1.3" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Auth.Base" version="117.1.4.3" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Base" version="117.6.0.3" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Basement" version="117.6.0.4" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Tasks" version="117.2.1.3" targetFramework="monoandroid90" />
 | 
			
		||||
  <package id="Xamarin.Google.Guava.ListenableFuture" version="1.0.0.9" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Auth" version="120.4.0" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Auth.Api.Phone" version="118.0.1.2" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Auth.Base" version="118.0.6" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Base" version="118.1.0" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Basement" version="118.1.0.1" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Fido" version="119.0.0" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.GooglePlayServices.Tasks" version="118.0.2" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.Jetbrains.Annotations" version="23.0.0.4" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.Kotlin.StdLib" version="1.7.10" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.Kotlin.StdLib.Common" version="1.7.10" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.Kotlin.StdLib.Jdk7" version="1.7.10" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.Kotlin.StdLib.Jdk8" version="1.7.10" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.KotlinX.Coroutines.Android" version="1.6.4" targetFramework="monoandroid13.0" />
 | 
			
		||||
  <package id="Xamarin.KotlinX.Coroutines.Core.Jvm" version="1.6.4" targetFramework="monoandroid13.0" />
 | 
			
		||||
</packages>
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
    <TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
 | 
			
		||||
    <AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
 | 
			
		||||
    <AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
 | 
			
		||||
    <AndroidClassParser>class-parse</AndroidClassParser>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
			
		||||
    <DebugSymbols>true</DebugSymbols>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
 | 
			
		||||
Microsoft Visual Studio Solution File, Format Version 12.00
 | 
			
		||||
# Visual Studio Version 16
 | 
			
		||||
VisualStudioVersion = 16.0.29418.71
 | 
			
		||||
# Visual Studio Version 17
 | 
			
		||||
VisualStudioVersion = 17.4.33205.214
 | 
			
		||||
MinimumVisualStudioVersion = 10.0.40219.1
 | 
			
		||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeePassLib2Android", "KeePassLib2Android\KeePassLib2Android.csproj", "{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}"
 | 
			
		||||
EndProject
 | 
			
		||||
@@ -25,7 +25,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PCloudBindings", "PCloudBin
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "keepass2android-app", "keepass2android\keepass2android-app.csproj", "{D4C32E0A-0193-4496-9DB4-02CC126FD9F3}"
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamsungPass", "SamsungPass\Xamarin.SamsungPass\SamsungPass\SamsungPass.csproj", "{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}"
 | 
			
		||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kp2aAutofillParser", "Kp2aAutofillParser\Kp2aAutofillParser.csproj", "{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}"
 | 
			
		||||
EndProject
 | 
			
		||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aAutofillParserTest", "Kp2aAutofillParserTest\Kp2aAutofillParserTest.csproj", "{3D1560FF-86BB-4CB4-8367-80BA13B81C38}"
 | 
			
		||||
EndProject
 | 
			
		||||
Global
 | 
			
		||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
			
		||||
@@ -285,30 +287,54 @@ Global
 | 
			
		||||
		{D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
 | 
			
		||||
		{D4C32E0A-0193-4496-9DB4-02CC126FD9F3}.ReleaseNoNet|x64.Deploy.0 = Release|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Win32.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Win32.Build.0 = Debug|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|x64.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|x64.Build.0 = Debug|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Win32.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Win32.Build.0 = Release|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|x64.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|x64.Build.0 = Release|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Win32.Build.0 = ReleaseNoNet|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
 | 
			
		||||
		{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|x64.Build.0 = ReleaseNoNet|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Win32.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|Win32.Build.0 = Debug|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|x64.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Debug|x64.Build.0 = Debug|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Win32.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|Win32.Build.0 = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|x64.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.Release|x64.Build.0 = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{39B12571-BAFE-4D3A-AEE2-4D74F14DFD96}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Win32.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|Win32.Build.0 = Debug|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|x64.ActiveCfg = Debug|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Debug|x64.Build.0 = Debug|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Mixed Platforms.Build.0 = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Win32.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|Win32.Build.0 = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|x64.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.Release|x64.Build.0 = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
 | 
			
		||||
		{3D1560FF-86BB-4CB4-8367-80BA13B81C38}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
 | 
			
		||||
	EndGlobalSection
 | 
			
		||||
	GlobalSection(SolutionProperties) = preSolution
 | 
			
		||||
		HideSolutionNode = FALSE
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										987
									
								
								src/Kp2aAutofillParser/AutofillParser.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										987
									
								
								src/Kp2aAutofillParser/AutofillParser.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,987 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using Formatting = System.Xml.Formatting;
 | 
			
		||||
 | 
			
		||||
namespace Kp2aAutofillParser
 | 
			
		||||
{
 | 
			
		||||
    public class W3cHints
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        // Supported W3C autofill tokens (https://html.spec.whatwg.org/multipage/forms.html#autofill)
 | 
			
		||||
        public const string HONORIFIC_PREFIX = "honorific-prefix";
 | 
			
		||||
        public const string NAME = "name";
 | 
			
		||||
        public const string GIVEN_NAME = "given-name";
 | 
			
		||||
        public const string ADDITIONAL_NAME = "additional-name";
 | 
			
		||||
        public const string FAMILY_NAME = "family-name";
 | 
			
		||||
        public const string HONORIFIC_SUFFIX = "honorific-suffix";
 | 
			
		||||
        public const string USERNAME = "username";
 | 
			
		||||
        public const string NEW_PASSWORD = "new-password";
 | 
			
		||||
        public const string CURRENT_PASSWORD = "current-password";
 | 
			
		||||
        public const string ORGANIZATION_TITLE = "organization-title";
 | 
			
		||||
        public const string ORGANIZATION = "organization";
 | 
			
		||||
        public const string STREET_ADDRESS = "street-address";
 | 
			
		||||
        public const string ADDRESS_LINE1 = "address-line1";
 | 
			
		||||
        public const string ADDRESS_LINE2 = "address-line2";
 | 
			
		||||
        public const string ADDRESS_LINE3 = "address-line3";
 | 
			
		||||
        public const string ADDRESS_LEVEL4 = "address-level4";
 | 
			
		||||
        public const string ADDRESS_LEVEL3 = "address-level3";
 | 
			
		||||
        public const string ADDRESS_LEVEL2 = "address-level2";
 | 
			
		||||
        public const string ADDRESS_LEVEL1 = "address-level1";
 | 
			
		||||
        public const string COUNTRY = "country";
 | 
			
		||||
        public const string COUNTRY_NAME = "country-name";
 | 
			
		||||
        public const string POSTAL_CODE = "postal-code";
 | 
			
		||||
        public const string CC_NAME = "cc-name";
 | 
			
		||||
        public const string CC_GIVEN_NAME = "cc-given-name";
 | 
			
		||||
        public const string CC_ADDITIONAL_NAME = "cc-additional-name";
 | 
			
		||||
        public const string CC_FAMILY_NAME = "cc-family-name";
 | 
			
		||||
        public const string CC_NUMBER = "cc-number";
 | 
			
		||||
        public const string CC_EXPIRATION = "cc-exp";
 | 
			
		||||
        public const string CC_EXPIRATION_MONTH = "cc-exp-month";
 | 
			
		||||
        public const string CC_EXPIRATION_YEAR = "cc-exp-year";
 | 
			
		||||
        public const string CC_CSC = "cc-csc";
 | 
			
		||||
        public const string CC_TYPE = "cc-type";
 | 
			
		||||
        public const string TRANSACTION_CURRENCY = "transaction-currency";
 | 
			
		||||
        public const string TRANSACTION_AMOUNT = "transaction-amount";
 | 
			
		||||
        public const string LANGUAGE = "language";
 | 
			
		||||
        public const string BDAY = "bday";
 | 
			
		||||
        public const string BDAY_DAY = "bday-day";
 | 
			
		||||
        public const string BDAY_MONTH = "bday-month";
 | 
			
		||||
        public const string BDAY_YEAR = "bday-year";
 | 
			
		||||
        public const string SEX = "sex";
 | 
			
		||||
        public const string URL = "url";
 | 
			
		||||
        public const string PHOTO = "photo";
 | 
			
		||||
        // Optional W3C prefixes
 | 
			
		||||
        public const string PREFIX_SECTION = "section-";
 | 
			
		||||
        public const string SHIPPING = "shipping";
 | 
			
		||||
        public const string BILLING = "billing";
 | 
			
		||||
        // W3C prefixes below...
 | 
			
		||||
        public const string PREFIX_HOME = "home";
 | 
			
		||||
        public const string PREFIX_WORK = "work";
 | 
			
		||||
        public const string PREFIX_FAX = "fax";
 | 
			
		||||
        public const string PREFIX_PAGER = "pager";
 | 
			
		||||
        // ... require those suffix
 | 
			
		||||
        public const string TEL = "tel";
 | 
			
		||||
        public const string TEL_COUNTRY_CODE = "tel-country-code";
 | 
			
		||||
        public const string TEL_NATIONAL = "tel-national";
 | 
			
		||||
        public const string TEL_AREA_CODE = "tel-area-code";
 | 
			
		||||
        public const string TEL_LOCAL = "tel-local";
 | 
			
		||||
        public const string TEL_LOCAL_PREFIX = "tel-local-prefix";
 | 
			
		||||
        public const string TEL_LOCAL_SUFFIX = "tel-local-suffix";
 | 
			
		||||
        public const string TEL_EXTENSION = "tel_extension";
 | 
			
		||||
        public const string EMAIL = "email";
 | 
			
		||||
        public const string IMPP = "impp";
 | 
			
		||||
 | 
			
		||||
        private W3cHints()
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public static bool isW3cSectionPrefix(string hint)
 | 
			
		||||
        {
 | 
			
		||||
            return hint.ToLower().StartsWith(W3cHints.PREFIX_SECTION);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool isW3cAddressType(string hint)
 | 
			
		||||
        {
 | 
			
		||||
            switch (hint.ToLower())
 | 
			
		||||
            {
 | 
			
		||||
                case W3cHints.SHIPPING:
 | 
			
		||||
                case W3cHints.BILLING:
 | 
			
		||||
                    return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool isW3cTypePrefix(string hint)
 | 
			
		||||
        {
 | 
			
		||||
            switch (hint.ToLower())
 | 
			
		||||
            {
 | 
			
		||||
                case W3cHints.PREFIX_WORK:
 | 
			
		||||
                case W3cHints.PREFIX_FAX:
 | 
			
		||||
                case W3cHints.PREFIX_HOME:
 | 
			
		||||
                case W3cHints.PREFIX_PAGER:
 | 
			
		||||
                    return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static bool isW3cTypeHint(string hint)
 | 
			
		||||
        {
 | 
			
		||||
            switch (hint.ToLower())
 | 
			
		||||
            {
 | 
			
		||||
                case W3cHints.TEL:
 | 
			
		||||
                case W3cHints.TEL_COUNTRY_CODE:
 | 
			
		||||
                case W3cHints.TEL_NATIONAL:
 | 
			
		||||
                case W3cHints.TEL_AREA_CODE:
 | 
			
		||||
                case W3cHints.TEL_LOCAL:
 | 
			
		||||
                case W3cHints.TEL_LOCAL_PREFIX:
 | 
			
		||||
                case W3cHints.TEL_LOCAL_SUFFIX:
 | 
			
		||||
                case W3cHints.TEL_EXTENSION:
 | 
			
		||||
                case W3cHints.EMAIL:
 | 
			
		||||
                case W3cHints.IMPP:
 | 
			
		||||
                    return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// FilledAutofillFieldCollection is the model that holds all of the data on a client app's page,
 | 
			
		||||
    /// plus the dataset name associated with it.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class FilledAutofillFieldCollection<FieldT> where FieldT:InputField
 | 
			
		||||
    {
 | 
			
		||||
        public Dictionary<string, FilledAutofillField> HintMap { get; }
 | 
			
		||||
        public string DatasetName { get; set; }
 | 
			
		||||
 | 
			
		||||
        public FilledAutofillFieldCollection(Dictionary<string, FilledAutofillField> hintMap, string datasetName = "")
 | 
			
		||||
        {
 | 
			
		||||
            //recreate hint map making sure we compare case insensitive
 | 
			
		||||
            HintMap = BuildHintMap();
 | 
			
		||||
            foreach (var p in hintMap)
 | 
			
		||||
                HintMap.Add(p.Key, p.Value);
 | 
			
		||||
            DatasetName = datasetName;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public FilledAutofillFieldCollection() : this(BuildHintMap())
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        private static Dictionary<string, FilledAutofillField> BuildHintMap()
 | 
			
		||||
        {
 | 
			
		||||
            return new Dictionary<string, FilledAutofillField>(StringComparer.OrdinalIgnoreCase);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Adds a filledAutofillField to the collection, indexed by all of its hints.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>The add.</returns>
 | 
			
		||||
        /// <param name="filledAutofillField">Filled autofill field.</param>
 | 
			
		||||
        public void Add(FilledAutofillField filledAutofillField)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (string hint in filledAutofillField.AutofillHints)
 | 
			
		||||
            {
 | 
			
		||||
                if (AutofillHintsHelper.IsSupportedHint(hint))
 | 
			
		||||
                {
 | 
			
		||||
                    HintMap.TryAdd(hint, filledAutofillField);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Takes in a list of autofill hints (`autofillHints`), usually associated with a View or set of
 | 
			
		||||
        /// Views. Returns whether any of the filled fields on the page have at least 1 of these
 | 
			
		||||
        /// `autofillHint`s.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns><c>true</c>, if with hints was helpsed, <c>false</c> otherwise.</returns>
 | 
			
		||||
        /// <param name="autofillHints">Autofill hints.</param>
 | 
			
		||||
        public bool HelpsWithHints(List<string> autofillHints)
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 0; i < autofillHints.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                var autofillHint = autofillHints[i];
 | 
			
		||||
                if (HintMap.ContainsKey(autofillHint) && !HintMap[autofillHint].IsNull())
 | 
			
		||||
                {
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    public class AutofillHintsHelper
 | 
			
		||||
    {
 | 
			
		||||
        public const string AutofillHint2faAppOtp = "2faAppOTPCode";
 | 
			
		||||
        public const string AutofillHintBirthDateDay = "birthDateDay";
 | 
			
		||||
        public const string AutofillHintBirthDateFull = "birthDateFull";
 | 
			
		||||
        public const string AutofillHintBirthDateMonth = "birthDateMonth";
 | 
			
		||||
        public const string AutofillHintBirthDateYear = "birthDateYear";
 | 
			
		||||
        public const string AutofillHintCreditCardExpirationDate = "creditCardExpirationDate";
 | 
			
		||||
        public const string AutofillHintCreditCardExpirationDay = "creditCardExpirationDay";
 | 
			
		||||
        public const string AutofillHintCreditCardExpirationMonth = "creditCardExpirationMonth";
 | 
			
		||||
        public const string AutofillHintCreditCardExpirationYear = "creditCardExpirationYear";
 | 
			
		||||
        public const string AutofillHintCreditCardNumber = "creditCardNumber";
 | 
			
		||||
        public const string AutofillHintCreditCardSecurityCode = "creditCardSecurityCode";
 | 
			
		||||
        public const string AutofillHintEmailAddress = "emailAddress";
 | 
			
		||||
        public const string AutofillHintEmailOtp = "emailOTPCode";
 | 
			
		||||
        public const string AutofillHintGender = "gender";
 | 
			
		||||
        public const string AutofillHintName = "name";
 | 
			
		||||
        public const string AutofillHintNewPassword = "newPassword";
 | 
			
		||||
        public const string AutofillHintNewUsername = "newUsername";
 | 
			
		||||
        public const string AutofillHintNotApplicable = "notApplicable";
 | 
			
		||||
        public const string AutofillHintPassword = "password";
 | 
			
		||||
        public const string AutofillHintPersonName = "personName";
 | 
			
		||||
        public const string AutofillHintPersonNameFAMILY = "personFamilyName";
 | 
			
		||||
        public const string AutofillHintPersonNameGIVEN = "personGivenName";
 | 
			
		||||
        public const string AutofillHintPersonNameMIDDLE = "personMiddleName";
 | 
			
		||||
        public const string AutofillHintPersonNameMIDDLE_INITIAL = "personMiddleInitial";
 | 
			
		||||
        public const string AutofillHintPersonNamePREFIX = "personNamePrefix";
 | 
			
		||||
        public const string AutofillHintPersonNameSUFFIX = "personNameSuffix";
 | 
			
		||||
        public const string AutofillHintPhone = "phone";
 | 
			
		||||
        public const string AutofillHintPhoneContryCode = "phoneCountryCode";
 | 
			
		||||
        public const string AutofillHintPostalAddressAPT_NUMBER = "aptNumber";
 | 
			
		||||
        public const string AutofillHintPostalAddressCOUNTRY = "addressCountry";
 | 
			
		||||
        public const string AutofillHintPostalAddressDEPENDENT_LOCALITY = "dependentLocality";
 | 
			
		||||
        public const string AutofillHintPostalAddressEXTENDED_ADDRESS = "extendedAddress";
 | 
			
		||||
        public const string AutofillHintPostalAddressEXTENDED_POSTAL_CODE = "extendedPostalCode";
 | 
			
		||||
        public const string AutofillHintPostalAddressLOCALITY = "addressLocality";
 | 
			
		||||
        public const string AutofillHintPostalAddressREGION = "addressRegion";
 | 
			
		||||
        public const string AutofillHintPostalAddressSTREET_ADDRESS = "streetAddress";
 | 
			
		||||
        public const string AutofillHintPostalCode = "postalCode";
 | 
			
		||||
        public const string AutofillHintPromoCode = "promoCode";
 | 
			
		||||
        public const string AutofillHintSMS_OTP = "smsOTPCode";
 | 
			
		||||
        public const string AutofillHintUPI_VPA = "upiVirtualPaymentAddress";
 | 
			
		||||
        public const string AutofillHintUsername = "username";
 | 
			
		||||
        public const string AutofillHintWifiPassword = "wifiPassword";
 | 
			
		||||
        public const string AutofillHintPhoneNational = "phoneNational";
 | 
			
		||||
        public const string AutofillHintPhoneNumber = "phoneNumber";
 | 
			
		||||
        public const string AutofillHintPhoneNumberDevice = "phoneNumberDevice";
 | 
			
		||||
        public const string AutofillHintPostalAddress = "postalAddress";
 | 
			
		||||
 | 
			
		||||
        private static readonly HashSet<string> _allSupportedHints = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
 | 
			
		||||
        {
 | 
			
		||||
            AutofillHintCreditCardExpirationDate,
 | 
			
		||||
            AutofillHintCreditCardExpirationDay,
 | 
			
		||||
            AutofillHintCreditCardExpirationMonth,
 | 
			
		||||
            AutofillHintCreditCardExpirationYear,
 | 
			
		||||
            AutofillHintCreditCardNumber,
 | 
			
		||||
            AutofillHintCreditCardSecurityCode,
 | 
			
		||||
            AutofillHintEmailAddress,
 | 
			
		||||
            AutofillHintPhone,
 | 
			
		||||
            AutofillHintName,
 | 
			
		||||
            AutofillHintPassword,
 | 
			
		||||
            AutofillHintPostalAddress,
 | 
			
		||||
            AutofillHintPostalCode,
 | 
			
		||||
            AutofillHintUsername,
 | 
			
		||||
            W3cHints.HONORIFIC_PREFIX,
 | 
			
		||||
            W3cHints.NAME,
 | 
			
		||||
            W3cHints.GIVEN_NAME,
 | 
			
		||||
            W3cHints.ADDITIONAL_NAME,
 | 
			
		||||
            W3cHints.FAMILY_NAME,
 | 
			
		||||
            W3cHints.HONORIFIC_SUFFIX,
 | 
			
		||||
            W3cHints.USERNAME,
 | 
			
		||||
            W3cHints.NEW_PASSWORD,
 | 
			
		||||
            W3cHints.CURRENT_PASSWORD,
 | 
			
		||||
            W3cHints.ORGANIZATION_TITLE,
 | 
			
		||||
            W3cHints.ORGANIZATION,
 | 
			
		||||
            W3cHints.STREET_ADDRESS,
 | 
			
		||||
            W3cHints.ADDRESS_LINE1,
 | 
			
		||||
            W3cHints.ADDRESS_LINE2,
 | 
			
		||||
            W3cHints.ADDRESS_LINE3,
 | 
			
		||||
            W3cHints.ADDRESS_LEVEL4,
 | 
			
		||||
            W3cHints.ADDRESS_LEVEL3,
 | 
			
		||||
            W3cHints.ADDRESS_LEVEL2,
 | 
			
		||||
            W3cHints.ADDRESS_LEVEL1,
 | 
			
		||||
            W3cHints.COUNTRY,
 | 
			
		||||
            W3cHints.COUNTRY_NAME,
 | 
			
		||||
            W3cHints.POSTAL_CODE,
 | 
			
		||||
            W3cHints.CC_NAME,
 | 
			
		||||
            W3cHints.CC_GIVEN_NAME,
 | 
			
		||||
            W3cHints.CC_ADDITIONAL_NAME,
 | 
			
		||||
            W3cHints.CC_FAMILY_NAME,
 | 
			
		||||
            W3cHints.CC_NUMBER,
 | 
			
		||||
            W3cHints.CC_EXPIRATION,
 | 
			
		||||
            W3cHints.CC_EXPIRATION_MONTH,
 | 
			
		||||
            W3cHints.CC_EXPIRATION_YEAR,
 | 
			
		||||
            W3cHints.CC_CSC,
 | 
			
		||||
            W3cHints.CC_TYPE,
 | 
			
		||||
            W3cHints.TRANSACTION_CURRENCY,
 | 
			
		||||
            W3cHints.TRANSACTION_AMOUNT,
 | 
			
		||||
            W3cHints.LANGUAGE,
 | 
			
		||||
            W3cHints.BDAY,
 | 
			
		||||
            W3cHints.BDAY_DAY,
 | 
			
		||||
            W3cHints.BDAY_MONTH,
 | 
			
		||||
            W3cHints.BDAY_YEAR,
 | 
			
		||||
            W3cHints.SEX,
 | 
			
		||||
            W3cHints.URL,
 | 
			
		||||
            W3cHints.PHOTO,
 | 
			
		||||
            W3cHints.TEL,
 | 
			
		||||
            W3cHints.TEL_COUNTRY_CODE,
 | 
			
		||||
            W3cHints.TEL_NATIONAL,
 | 
			
		||||
            W3cHints.TEL_AREA_CODE,
 | 
			
		||||
            W3cHints.TEL_LOCAL,
 | 
			
		||||
            W3cHints.TEL_LOCAL_PREFIX,
 | 
			
		||||
            W3cHints.TEL_LOCAL_SUFFIX,
 | 
			
		||||
            W3cHints.TEL_EXTENSION,
 | 
			
		||||
            W3cHints.EMAIL,
 | 
			
		||||
            W3cHints.IMPP,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        private static readonly List<HashSet<string>> partitionsOfCanonicalHints = new List<HashSet<string>>()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            new HashSet<string>(StringComparer.OrdinalIgnoreCase)
 | 
			
		||||
            {
 | 
			
		||||
            AutofillHintEmailAddress,
 | 
			
		||||
            AutofillHintPhone,
 | 
			
		||||
            AutofillHintName,
 | 
			
		||||
            AutofillHintPassword,
 | 
			
		||||
            AutofillHintUsername,
 | 
			
		||||
            W3cHints.HONORIFIC_PREFIX,
 | 
			
		||||
            W3cHints.EMAIL,
 | 
			
		||||
            W3cHints.NAME,
 | 
			
		||||
            W3cHints.GIVEN_NAME,
 | 
			
		||||
            W3cHints.ADDITIONAL_NAME,
 | 
			
		||||
            W3cHints.FAMILY_NAME,
 | 
			
		||||
            W3cHints.HONORIFIC_SUFFIX,
 | 
			
		||||
            W3cHints.ORGANIZATION_TITLE,
 | 
			
		||||
            W3cHints.ORGANIZATION,
 | 
			
		||||
            W3cHints.LANGUAGE,
 | 
			
		||||
            W3cHints.BDAY,
 | 
			
		||||
            W3cHints.BDAY_DAY,
 | 
			
		||||
            W3cHints.BDAY_MONTH,
 | 
			
		||||
            W3cHints.BDAY_YEAR,
 | 
			
		||||
            W3cHints.SEX,
 | 
			
		||||
            W3cHints.URL,
 | 
			
		||||
            W3cHints.PHOTO,
 | 
			
		||||
            W3cHints.TEL,
 | 
			
		||||
            W3cHints.TEL_COUNTRY_CODE,
 | 
			
		||||
            W3cHints.TEL_NATIONAL,
 | 
			
		||||
            W3cHints.TEL_AREA_CODE,
 | 
			
		||||
            W3cHints.TEL_LOCAL,
 | 
			
		||||
            W3cHints.TEL_LOCAL_PREFIX,
 | 
			
		||||
            W3cHints.TEL_LOCAL_SUFFIX,
 | 
			
		||||
            W3cHints.TEL_EXTENSION,
 | 
			
		||||
            W3cHints.IMPP,
 | 
			
		||||
            },
 | 
			
		||||
            new HashSet<string>(StringComparer.OrdinalIgnoreCase)
 | 
			
		||||
            {
 | 
			
		||||
                AutofillHintPostalAddress,
 | 
			
		||||
                AutofillHintPostalCode,
 | 
			
		||||
 | 
			
		||||
                W3cHints.STREET_ADDRESS,
 | 
			
		||||
                W3cHints.ADDRESS_LINE1,
 | 
			
		||||
                W3cHints.ADDRESS_LINE2,
 | 
			
		||||
                W3cHints.ADDRESS_LINE3,
 | 
			
		||||
                W3cHints.ADDRESS_LEVEL4,
 | 
			
		||||
                W3cHints.ADDRESS_LEVEL3,
 | 
			
		||||
                W3cHints.ADDRESS_LEVEL2,
 | 
			
		||||
                W3cHints.ADDRESS_LEVEL1,
 | 
			
		||||
                W3cHints.COUNTRY,
 | 
			
		||||
                W3cHints.COUNTRY_NAME
 | 
			
		||||
            },
 | 
			
		||||
            new HashSet<string>(StringComparer.OrdinalIgnoreCase)
 | 
			
		||||
            {
 | 
			
		||||
                AutofillHintCreditCardExpirationDate,
 | 
			
		||||
                AutofillHintCreditCardExpirationDay,
 | 
			
		||||
                AutofillHintCreditCardExpirationMonth,
 | 
			
		||||
                AutofillHintCreditCardExpirationYear,
 | 
			
		||||
                AutofillHintCreditCardNumber,
 | 
			
		||||
                AutofillHintCreditCardSecurityCode,
 | 
			
		||||
 | 
			
		||||
                W3cHints.CC_NAME,
 | 
			
		||||
                W3cHints.CC_GIVEN_NAME,
 | 
			
		||||
                W3cHints.CC_ADDITIONAL_NAME,
 | 
			
		||||
                W3cHints.CC_FAMILY_NAME,
 | 
			
		||||
                W3cHints.CC_TYPE,
 | 
			
		||||
                W3cHints.TRANSACTION_CURRENCY,
 | 
			
		||||
                W3cHints.TRANSACTION_AMOUNT,
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
                      };
 | 
			
		||||
 | 
			
		||||
        private static readonly Dictionary<string, string> hintToCanonicalReplacement = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
 | 
			
		||||
        {
 | 
			
		||||
            {W3cHints.EMAIL, AutofillHintEmailAddress},
 | 
			
		||||
            {W3cHints.USERNAME, AutofillHintUsername},
 | 
			
		||||
            {W3cHints.CURRENT_PASSWORD, AutofillHintPassword},
 | 
			
		||||
            {W3cHints.NEW_PASSWORD, AutofillHintPassword},
 | 
			
		||||
            {W3cHints.CC_EXPIRATION_MONTH, AutofillHintCreditCardExpirationMonth },
 | 
			
		||||
            {W3cHints.CC_EXPIRATION_YEAR, AutofillHintCreditCardExpirationYear },
 | 
			
		||||
            {W3cHints.CC_EXPIRATION, AutofillHintCreditCardExpirationDate },
 | 
			
		||||
            {W3cHints.CC_NUMBER, AutofillHintCreditCardNumber },
 | 
			
		||||
            {W3cHints.CC_CSC, AutofillHintCreditCardSecurityCode },
 | 
			
		||||
            {W3cHints.POSTAL_CODE, AutofillHintPostalCode },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        public static bool IsSupportedHint(string hint)
 | 
			
		||||
        {
 | 
			
		||||
            return _allSupportedHints.Contains(hint);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public static string[] FilterForSupportedHints(string[] hints)
 | 
			
		||||
        {
 | 
			
		||||
            if (hints == null)
 | 
			
		||||
                return Array.Empty<string>();
 | 
			
		||||
            var filteredHints = new string[hints.Length];
 | 
			
		||||
            int i = 0;
 | 
			
		||||
            foreach (var hint in hints)
 | 
			
		||||
            {
 | 
			
		||||
                if (IsSupportedHint(hint))
 | 
			
		||||
                {
 | 
			
		||||
                    filteredHints[i++] = hint;
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
            }
 | 
			
		||||
            var finalFilteredHints = new string[i];
 | 
			
		||||
            Array.Copy(filteredHints, 0, finalFilteredHints, 0, i);
 | 
			
		||||
            return finalFilteredHints;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// transforms hints by replacing some W3cHints by their Android counterparts and transforming everything to lowercase
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public static List<string> ConvertToCanonicalLowerCaseHints(string[] supportedHints)
 | 
			
		||||
        {
 | 
			
		||||
            List<string> result = new List<string>();
 | 
			
		||||
            foreach (string hint in supportedHints)
 | 
			
		||||
            {
 | 
			
		||||
                var canonicalHint = ToCanonicalHint(hint);
 | 
			
		||||
                result.Add(canonicalHint.ToLower());
 | 
			
		||||
            }
 | 
			
		||||
            return result;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static string ToCanonicalHint(string hint)
 | 
			
		||||
        {
 | 
			
		||||
            string canonicalHint;
 | 
			
		||||
            if (!hintToCanonicalReplacement.TryGetValue(hint, out canonicalHint))
 | 
			
		||||
                canonicalHint = hint;
 | 
			
		||||
            return canonicalHint;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static int GetPartitionIndex(string hint)
 | 
			
		||||
        {
 | 
			
		||||
            for (int i = 0; i < partitionsOfCanonicalHints.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                if (partitionsOfCanonicalHints[i].Contains(hint))
 | 
			
		||||
                {
 | 
			
		||||
                    return i;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return -1;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static FilledAutofillFieldCollection<FieldT> FilterForPartition<FieldT>(FilledAutofillFieldCollection<FieldT> autofillFields, int partitionIndex) where FieldT: InputField
 | 
			
		||||
        {
 | 
			
		||||
            FilledAutofillFieldCollection<FieldT> filteredCollection =
 | 
			
		||||
                new FilledAutofillFieldCollection<FieldT> { DatasetName = autofillFields.DatasetName };
 | 
			
		||||
 | 
			
		||||
            if (partitionIndex == -1)
 | 
			
		||||
                return filteredCollection;
 | 
			
		||||
 | 
			
		||||
            foreach (var field in autofillFields.HintMap.Values.Distinct())
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var hint in field.AutofillHints)
 | 
			
		||||
                {
 | 
			
		||||
                    if (GetPartitionIndex(hint) == partitionIndex)
 | 
			
		||||
                    {
 | 
			
		||||
                        filteredCollection.Add(field);
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return filteredCollection;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static FilledAutofillFieldCollection<FieldT> FilterForPartition<FieldT>(FilledAutofillFieldCollection<FieldT> filledAutofillFieldCollection, List<string> autofillFieldsFocusedAutofillCanonicalHints) where FieldT: InputField
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            //only apply partition data if we have FocusedAutofillCanonicalHints. This may be empty on buggy Firefox.
 | 
			
		||||
            if (autofillFieldsFocusedAutofillCanonicalHints.Any())
 | 
			
		||||
            {
 | 
			
		||||
                int partitionIndex = AutofillHintsHelper.GetPartitionIndex(autofillFieldsFocusedAutofillCanonicalHints.FirstOrDefault());
 | 
			
		||||
                return AutofillHintsHelper.FilterForPartition(filledAutofillFieldCollection, partitionIndex);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return filledAutofillFieldCollection;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// This enum represents the Android.Text.InputTypes values. For testability, this is duplicated here.
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public enum InputTypes
 | 
			
		||||
    {
 | 
			
		||||
        ClassDatetime = 4,
 | 
			
		||||
        ClassNumber = 2,
 | 
			
		||||
        ClassPhone = 3,
 | 
			
		||||
        ClassText = 1,
 | 
			
		||||
        DatetimeVariationDate = 16,
 | 
			
		||||
        DatetimeVariationNormal = 0,
 | 
			
		||||
        DatetimeVariationTime = 32,
 | 
			
		||||
        MaskClass = 15,
 | 
			
		||||
        MaskFlags = 16773120,
 | 
			
		||||
        MaskVariation = 4080,
 | 
			
		||||
        Null = 0,
 | 
			
		||||
        NumberFlagDecimal = 8192,
 | 
			
		||||
        NumberFlagSigned = 4096,
 | 
			
		||||
        NumberVariationNormal = 0,
 | 
			
		||||
        NumberVariationPassword = 16,
 | 
			
		||||
        TextFlagAutoComplete = 65536,
 | 
			
		||||
        TextFlagAutoCorrect = 32768,
 | 
			
		||||
        TextFlagCapCharacters = 4096,
 | 
			
		||||
        TextFlagCapSentences = 16384,
 | 
			
		||||
        TextFlagCapWords = 8192,
 | 
			
		||||
        TextFlagEnableTextConversionSuggestions = 1048576,
 | 
			
		||||
        TextFlagImeMultiLine = 262144,
 | 
			
		||||
        TextFlagMultiLine = 131072,
 | 
			
		||||
        TextFlagNoSuggestions = 524288,
 | 
			
		||||
        TextVariationEmailAddress = 32,
 | 
			
		||||
        TextVariationEmailSubject = 48,
 | 
			
		||||
        TextVariationFilter = 176,
 | 
			
		||||
        TextVariationLongMessage = 80,
 | 
			
		||||
        TextVariationNormal = 0,
 | 
			
		||||
        TextVariationPassword = 128,
 | 
			
		||||
        TextVariationPersonName = 96,
 | 
			
		||||
        TextVariationPhonetic = 192,
 | 
			
		||||
        TextVariationPostalAddress = 112,
 | 
			
		||||
        TextVariationShortMessage = 64,
 | 
			
		||||
        TextVariationUri = 16,
 | 
			
		||||
        TextVariationVisiblePassword = 144,
 | 
			
		||||
        TextVariationWebEditText = 160,
 | 
			
		||||
        TextVariationWebEmailAddress = 208,
 | 
			
		||||
        TextVariationWebPassword = 224
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface IKp2aDigitalAssetLinksDataSource
 | 
			
		||||
    {
 | 
			
		||||
        bool IsTrustedApp(string packageName);
 | 
			
		||||
        bool IsTrustedLink(string domain, string targetPackage);
 | 
			
		||||
        bool IsEnabled();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    class TimeUtil
 | 
			
		||||
    {
 | 
			
		||||
        private static DateTime? m_dtUnixRoot = null;
 | 
			
		||||
        public static DateTime ConvertUnixTime(double dtUnix)
 | 
			
		||||
        {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                if (!m_dtUnixRoot.HasValue)
 | 
			
		||||
                    m_dtUnixRoot = (new DateTime(1970, 1, 1, 0, 0, 0, 0,
 | 
			
		||||
                        DateTimeKind.Utc)).ToLocalTime();
 | 
			
		||||
 | 
			
		||||
                return m_dtUnixRoot.Value.AddSeconds(dtUnix);
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception) { Debug.Assert(false); }
 | 
			
		||||
 | 
			
		||||
            return DateTime.UtcNow;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class FilledAutofillField
 | 
			
		||||
    {
 | 
			
		||||
        private string[] _autofillHints;
 | 
			
		||||
        public string TextValue { get; set; }
 | 
			
		||||
        public long? DateValue { get; set; }
 | 
			
		||||
        public bool? ToggleValue { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string ValueToString()
 | 
			
		||||
        {
 | 
			
		||||
            if (DateValue != null)
 | 
			
		||||
            {
 | 
			
		||||
                return TimeUtil.ConvertUnixTime((long)DateValue / 1000.0).ToLongDateString();
 | 
			
		||||
            }
 | 
			
		||||
            if (ToggleValue != null)
 | 
			
		||||
                return ToggleValue.ToString();
 | 
			
		||||
            return TextValue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// returns the autofill hints for the filled field. These are always lowercased for simpler string comparison.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
	    public string[] AutofillHints
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return _autofillHints;
 | 
			
		||||
            }
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                _autofillHints = value;
 | 
			
		||||
                for (int i = 0; i < _autofillHints.Length; i++)
 | 
			
		||||
                    _autofillHints[i] = _autofillHints[i].ToLower();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public FilledAutofillField()
 | 
			
		||||
        { }
 | 
			
		||||
 | 
			
		||||
        public FilledAutofillField(InputField inputField) 
 | 
			
		||||
            : this(inputField, inputField.AutofillHints)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public FilledAutofillField(InputField inputField, string[] hints)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            string[] rawHints = AutofillHintsHelper.FilterForSupportedHints(hints);
 | 
			
		||||
            List<string> hintList = new List<string>();
 | 
			
		||||
 | 
			
		||||
            string nextHint = null;
 | 
			
		||||
            for (int i = 0; i < rawHints.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                string hint = rawHints[i];
 | 
			
		||||
                if (i < rawHints.Length - 1)
 | 
			
		||||
                {
 | 
			
		||||
                    nextHint = rawHints[i + 1];
 | 
			
		||||
                }
 | 
			
		||||
                // First convert the compound W3C autofill hints
 | 
			
		||||
                if (W3cHints.isW3cSectionPrefix(hint) && i < rawHints.Length - 1)
 | 
			
		||||
                {
 | 
			
		||||
                    hint = rawHints[++i];
 | 
			
		||||
                    
 | 
			
		||||
                    if (i < rawHints.Length - 1)
 | 
			
		||||
                    {
 | 
			
		||||
                        nextHint = rawHints[i + 1];
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (W3cHints.isW3cTypePrefix(hint) && nextHint != null && W3cHints.isW3cTypeHint(nextHint))
 | 
			
		||||
                {
 | 
			
		||||
                    hint = nextHint;
 | 
			
		||||
                    i++;
 | 
			
		||||
                    
 | 
			
		||||
                }
 | 
			
		||||
                if (W3cHints.isW3cAddressType(hint) && nextHint != null)
 | 
			
		||||
                {
 | 
			
		||||
                    hint = nextHint;
 | 
			
		||||
                    i++;
 | 
			
		||||
                    
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Then check if the "actual" hint is supported.
 | 
			
		||||
                if (AutofillHintsHelper.IsSupportedHint(hint))
 | 
			
		||||
                {
 | 
			
		||||
                    hintList.Add(hint);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            AutofillHints = AutofillHintsHelper.ConvertToCanonicalLowerCaseHints(hintList.ToArray()).ToArray();
 | 
			
		||||
            inputField.FillFilledAutofillValue(this);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool IsNull()
 | 
			
		||||
        {
 | 
			
		||||
            return TextValue == null && DateValue == null && ToggleValue == null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            if (this == obj) return true;
 | 
			
		||||
            if (obj == null || GetType() != obj.GetType()) return false;
 | 
			
		||||
 | 
			
		||||
            FilledAutofillField that = (FilledAutofillField)obj;
 | 
			
		||||
 | 
			
		||||
            if (!TextValue?.Equals(that.TextValue) ?? that.TextValue != null)
 | 
			
		||||
                return false;
 | 
			
		||||
            if (DateValue != null ? !DateValue.Equals(that.DateValue) : that.DateValue != null)
 | 
			
		||||
                return false;
 | 
			
		||||
            return ToggleValue != null ? ToggleValue.Equals(that.ToggleValue) : that.ToggleValue == null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            unchecked
 | 
			
		||||
            {
 | 
			
		||||
                var result = TextValue != null ? TextValue.GetHashCode() : 0;
 | 
			
		||||
                result = 31 * result + (DateValue != null ? DateValue.GetHashCode() : 0);
 | 
			
		||||
                result = 31 * result + (ToggleValue != null ? ToggleValue.GetHashCode() : 0);
 | 
			
		||||
                return result;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Base class for everything that is (or could be) an input field which might (or might not) be autofilled.
 | 
			
		||||
    /// For testability, this is independent from Android classes like ViewNode
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public abstract class InputField
 | 
			
		||||
    {
 | 
			
		||||
        public string? IdEntry { get; set; }
 | 
			
		||||
        public string? Hint { get; set; }
 | 
			
		||||
        public string ClassName { get; set; }
 | 
			
		||||
        public string[] AutofillHints { get; set; }
 | 
			
		||||
        public bool IsFocused { get; set; }
 | 
			
		||||
 | 
			
		||||
        public InputTypes InputType { get; set; }
 | 
			
		||||
 | 
			
		||||
        public string HtmlInfoTag { get; set; }
 | 
			
		||||
        public string HtmlInfoTypeAttribute { get; set; }
 | 
			
		||||
 | 
			
		||||
        public abstract void FillFilledAutofillValue(FilledAutofillField filledField);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Serializable structure defining the contents of the current view (from an autofill perspective)
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    /// <typeparam name="TField"></typeparam>
 | 
			
		||||
    public class AutofillView<TField> where TField : InputField
 | 
			
		||||
    {
 | 
			
		||||
        public List<TField> InputFields { get; set; } = new List<TField>();
 | 
			
		||||
 | 
			
		||||
        public string PackageId { get; set; } = null;
 | 
			
		||||
        public string WebDomain { get; set; } = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface ILogger
 | 
			
		||||
    {
 | 
			
		||||
        void Log(string x);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class StructureParserBase<FieldT> where FieldT: InputField
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ILogger _log;
 | 
			
		||||
        private readonly IKp2aDigitalAssetLinksDataSource _digitalAssetLinksDataSource;
 | 
			
		||||
 | 
			
		||||
        private readonly List<string> _autofillHintsForLogin = new List<string>
 | 
			
		||||
            {
 | 
			
		||||
                AutofillHintsHelper.AutofillHintPassword,
 | 
			
		||||
                AutofillHintsHelper.AutofillHintUsername,
 | 
			
		||||
                AutofillHintsHelper.AutofillHintEmailAddress
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
        public string PackageId { get; set; }
 | 
			
		||||
 | 
			
		||||
        public Dictionary<FieldT, string[]> FieldsMappedToHints = new Dictionary<FieldT, string[]>();
 | 
			
		||||
 | 
			
		||||
        public StructureParserBase(ILogger logger, IKp2aDigitalAssetLinksDataSource digitalAssetLinksDataSource)
 | 
			
		||||
        {
 | 
			
		||||
            _log = logger;
 | 
			
		||||
            _digitalAssetLinksDataSource = digitalAssetLinksDataSource;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public class AutofillTargetId
 | 
			
		||||
        {
 | 
			
		||||
            public string PackageName { get; set; }
 | 
			
		||||
 | 
			
		||||
            public string PackageNameWithPseudoSchema
 | 
			
		||||
            {
 | 
			
		||||
                get { return AndroidAppScheme + PackageName; }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            public const string AndroidAppScheme = "androidapp://";
 | 
			
		||||
 | 
			
		||||
            public string WebDomain { get; set; }
 | 
			
		||||
 | 
			
		||||
            /// <summary>
 | 
			
		||||
            /// If PackageName and WebDomain are not compatible (by DAL or because PackageName is a trusted browser in which case we treat all domains as "compatible"
 | 
			
		||||
            /// we need to issue a warning. If we would fill credentials for the package, a malicious website could try to get credentials for the app.
 | 
			
		||||
            /// If we would fill credentials for the domain, a malicious app could get credentials for the domain.
 | 
			
		||||
            /// </summary>
 | 
			
		||||
            public bool IncompatiblePackageAndDomain { get; set; }
 | 
			
		||||
 | 
			
		||||
            public string DomainOrPackage
 | 
			
		||||
            {
 | 
			
		||||
                get
 | 
			
		||||
                {
 | 
			
		||||
                    return WebDomain ?? PackageNameWithPseudoSchema;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AutofillTargetId ParseForFill(bool isManual, AutofillView<FieldT> autofillView)
 | 
			
		||||
        {
 | 
			
		||||
            return Parse(true, isManual, autofillView);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public AutofillTargetId ParseForSave(AutofillView<FieldT> autofillView)
 | 
			
		||||
        {
 | 
			
		||||
            return Parse(false, true, autofillView);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Traverse AssistStructure and add ViewNode metadata to a flat list.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns>The parse.</returns>
 | 
			
		||||
        /// <param name="forFill">If set to <c>true</c> for fill.</param>
 | 
			
		||||
        /// <param name="isManualRequest"></param>
 | 
			
		||||
        protected virtual AutofillTargetId Parse(bool forFill, bool isManualRequest, AutofillView<FieldT> autofillView)
 | 
			
		||||
        {
 | 
			
		||||
            AutofillTargetId result = new AutofillTargetId()
 | 
			
		||||
            {
 | 
			
		||||
                PackageName = autofillView.PackageId,
 | 
			
		||||
                WebDomain = autofillView.WebDomain
 | 
			
		||||
            };
 | 
			
		||||
            
 | 
			
		||||
            _log.Log("parsing autofillStructure...");
 | 
			
		||||
 | 
			
		||||
            if (LogAutofillView)
 | 
			
		||||
            {
 | 
			
		||||
                string debugInfo = JsonConvert.SerializeObject(autofillView, Newtonsoft.Json.Formatting.Indented);
 | 
			
		||||
                _log.Log("This is the autofillStructure: \n\n " + debugInfo);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            //go through each input field and determine username/password fields.
 | 
			
		||||
            //Depending on the target this can require more or less heuristics.
 | 
			
		||||
            // * if there is a valid & supported autofill hint, we assume that all fields which should be filled do have an appropriate Autofill hint
 | 
			
		||||
            // * if there is no such autofill hint, we use IsPassword to 
 | 
			
		||||
 | 
			
		||||
            HashSet<string> autofillHintsOfAllFields = autofillView.InputFields.Where(f => f.AutofillHints != null)
 | 
			
		||||
                .SelectMany(f => f.AutofillHints).Select(AutofillHintsHelper.ToCanonicalHint).ToHashSet();
 | 
			
		||||
            bool hasLoginAutofillHints = autofillHintsOfAllFields.Intersect(_autofillHintsForLogin).Any();
 | 
			
		||||
 | 
			
		||||
            if (hasLoginAutofillHints)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (var viewNode in autofillView.InputFields)
 | 
			
		||||
                {
 | 
			
		||||
                    string[] viewHints = viewNode.AutofillHints;
 | 
			
		||||
                    if (viewHints == null)
 | 
			
		||||
                        continue;
 | 
			
		||||
                    if (viewHints.Select(AutofillHintsHelper.ToCanonicalHint).Intersect(_autofillHintsForLogin).Any())
 | 
			
		||||
                    {
 | 
			
		||||
                        AddFieldToHintMap(viewNode, viewHints.Select(AutofillHintsHelper.ToCanonicalHint).ToHashSet().ToArray());
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                //determine password fields, first by type, then by hint:
 | 
			
		||||
                List<FieldT> editTexts = autofillView.InputFields.Where(f => IsEditText(f)).ToList();
 | 
			
		||||
                List<FieldT> passwordFields = autofillView.InputFields.Where(f => IsEditText(f) && IsPassword(f)).ToList();
 | 
			
		||||
                if (!passwordFields.Any())
 | 
			
		||||
                {
 | 
			
		||||
                    passwordFields = autofillView.InputFields.Where(f => IsEditText(f) && HasPasswordHint(f)).ToList();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                //determine username fields. Try by hint, if that fails use the one before the password
 | 
			
		||||
                List<FieldT> usernameFields = autofillView.InputFields.Where(f => IsEditText(f) && HasUsernameHint(f)).ToList();
 | 
			
		||||
                if (!usernameFields.Any())
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var passwordField in passwordFields)
 | 
			
		||||
                    {
 | 
			
		||||
                        
 | 
			
		||||
                        var lastInputBeforePassword = autofillView.InputFields.Where(IsEditText)
 | 
			
		||||
                            .TakeWhile(f =>  f != passwordField && !passwordFields.Contains(f)).LastOrDefault();
 | 
			
		||||
                        
 | 
			
		||||
                        if (lastInputBeforePassword != null)
 | 
			
		||||
                            usernameFields.Add(lastInputBeforePassword);
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                //for "heuristic determination" we demand that one of the filled fields is focused:
 | 
			
		||||
                if (passwordFields.Concat(usernameFields).Any(f => f.IsFocused))
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var uf in usernameFields)
 | 
			
		||||
                        AddFieldToHintMap(uf, new string[] { AutofillHintsHelper.AutofillHintUsername });
 | 
			
		||||
                    foreach (var pf in passwordFields.Except(usernameFields))
 | 
			
		||||
                        AddFieldToHintMap(pf, new string[] { AutofillHintsHelper.AutofillHintPassword });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            if (!string.IsNullOrEmpty(autofillView.WebDomain) && _digitalAssetLinksDataSource.IsEnabled())
 | 
			
		||||
            {
 | 
			
		||||
                result.IncompatiblePackageAndDomain = !_digitalAssetLinksDataSource.IsTrustedLink(autofillView.WebDomain, result.PackageName);
 | 
			
		||||
                if (result.IncompatiblePackageAndDomain)
 | 
			
		||||
                {
 | 
			
		||||
                    _log.Log($"DAL verification failed for {result.PackageName}/{result.WebDomain}");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                result.IncompatiblePackageAndDomain = false;
 | 
			
		||||
            }
 | 
			
		||||
            return result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddFieldToHintMap(FieldT field, string[] hints)
 | 
			
		||||
        {
 | 
			
		||||
            if (FieldsMappedToHints.ContainsKey(field))
 | 
			
		||||
            {
 | 
			
		||||
                FieldsMappedToHints[field] = FieldsMappedToHints[field].Concat(hints).ToArray();
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                FieldsMappedToHints[field] = hints;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool LogAutofillView { get; set; }
 | 
			
		||||
 | 
			
		||||
        private bool IsEditText(FieldT f)
 | 
			
		||||
        {
 | 
			
		||||
            return (f.ClassName == "android.widget.EditText"
 | 
			
		||||
                    || f.ClassName == "android.widget.AutoCompleteTextView"
 | 
			
		||||
                    || f.HtmlInfoTag == "input");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static readonly HashSet<string> _passwordHints = new HashSet<string> { "password", "passwort", "passwordAuto", "pswd" };
 | 
			
		||||
        private static bool HasPasswordHint(InputField f)
 | 
			
		||||
        {
 | 
			
		||||
            return IsAny(f.IdEntry, _passwordHints) ||
 | 
			
		||||
                   IsAny(f.Hint, _passwordHints);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static readonly HashSet<string> _usernameHints = new HashSet<string> { "email", "e-mail", "username", "user id" };
 | 
			
		||||
 | 
			
		||||
        private static bool HasUsernameHint(InputField f)
 | 
			
		||||
        {
 | 
			
		||||
            return IsAny(f.IdEntry?.ToLower(), _usernameHints) ||
 | 
			
		||||
                IsAny(f.Hint?.ToLower(), _usernameHints);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static bool IsAny(string? value, IEnumerable<string> terms)
 | 
			
		||||
        {
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(value))
 | 
			
		||||
            {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            var lowerValue = value.ToLowerInvariant();
 | 
			
		||||
            return terms.Any(t => lowerValue == t);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static bool IsInputTypeClass(InputTypes inputType, InputTypes inputTypeClass)
 | 
			
		||||
        {
 | 
			
		||||
            if (!InputTypes.MaskClass.HasFlag(inputTypeClass))
 | 
			
		||||
                throw new Exception("invalid inputTypeClass");
 | 
			
		||||
            return (((int)inputType) & (int)InputTypes.MaskClass) == (int)(inputTypeClass);
 | 
			
		||||
        }
 | 
			
		||||
        private static bool IsInputTypeVariation(InputTypes inputType, InputTypes inputTypeVariation)
 | 
			
		||||
        {
 | 
			
		||||
            if (!InputTypes.MaskVariation.HasFlag(inputTypeVariation))
 | 
			
		||||
                throw new Exception("invalid inputTypeVariation");
 | 
			
		||||
            return (((int)inputType) & (int)InputTypes.MaskVariation) == (int)(inputTypeVariation);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static bool IsPassword(InputField f)
 | 
			
		||||
        {
 | 
			
		||||
            InputTypes inputType = f.InputType;
 | 
			
		||||
 | 
			
		||||
            return
 | 
			
		||||
                (!f.IdEntry?.ToLowerInvariant().Contains("search") ?? true) &&
 | 
			
		||||
                (!f.Hint?.ToLowerInvariant().Contains("search") ?? true) &&
 | 
			
		||||
                (
 | 
			
		||||
                   (IsInputTypeClass(inputType, InputTypes.ClassText)
 | 
			
		||||
                        &&
 | 
			
		||||
                        (
 | 
			
		||||
                      IsInputTypeVariation(inputType, InputTypes.TextVariationPassword)
 | 
			
		||||
                      || IsInputTypeVariation(inputType, InputTypes.TextVariationVisiblePassword)
 | 
			
		||||
                      || IsInputTypeVariation(inputType, InputTypes.TextVariationWebPassword)
 | 
			
		||||
                      )
 | 
			
		||||
                      )
 | 
			
		||||
                    || (f.AutofillHints != null && f.AutofillHints.First() == "passwordAuto")
 | 
			
		||||
                    || (f.HtmlInfoTypeAttribute == "password")
 | 
			
		||||
                );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								src/Kp2aAutofillParser/Kp2aAutofillParser.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/Kp2aAutofillParser/Kp2aAutofillParser.csproj
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,12 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>netstandard2.1</TargetFramework>
 | 
			
		||||
    <Nullable>enable</Nullable>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										138
									
								
								src/Kp2aAutofillParserTest/AutofillTest.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/Kp2aAutofillParserTest/AutofillTest.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,138 @@
 | 
			
		||||
using Kp2aAutofillParser;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Reflection;
 | 
			
		||||
using Xunit.Abstractions;
 | 
			
		||||
 | 
			
		||||
namespace Kp2aAutofillParserTest
 | 
			
		||||
{
 | 
			
		||||
    public class AutofillTest
 | 
			
		||||
    {
 | 
			
		||||
        private readonly ITestOutputHelper _testOutputHelper;
 | 
			
		||||
 | 
			
		||||
        public AutofillTest(ITestOutputHelper testOutputHelper)
 | 
			
		||||
        {
 | 
			
		||||
            _testOutputHelper = testOutputHelper;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        class TestInputField: InputField
 | 
			
		||||
        {
 | 
			
		||||
            public string[] ExpectedAssignedHints { get; set; }
 | 
			
		||||
            public override void FillFilledAutofillValue(FilledAutofillField filledField)
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void TestNotFocusedPasswordAutoIsNotFilled()
 | 
			
		||||
        {
 | 
			
		||||
            var resourceName = "Kp2aAutofillParserTest.com-servicenet-mobile-no-focus.json";
 | 
			
		||||
            RunTestFromAutofillInput(resourceName, "com.servicenet.mobile");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void TestFocusedPasswordAutoIsFilled()
 | 
			
		||||
        {
 | 
			
		||||
            var resourceName = "Kp2aAutofillParserTest.com-servicenet-mobile-focused.json";
 | 
			
		||||
            RunTestFromAutofillInput(resourceName, "com.servicenet.mobile" );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void TestMulitpleUnfocusedLoginsIsFilled()
 | 
			
		||||
        {
 | 
			
		||||
            var resourceName = "Kp2aAutofillParserTest.firefox-amazon-it.json";
 | 
			
		||||
            RunTestFromAutofillInput(resourceName, "org.mozilla.firefox", "www.amazon.it");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void CanDetectFieldsWithoutAutofillHints()
 | 
			
		||||
        {
 | 
			
		||||
            var resourceName = "Kp2aAutofillParserTest.chrome-android10-amazon-it.json";
 | 
			
		||||
            RunTestFromAutofillInput(resourceName, "com.android.chrome", "www.amazon.it");
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void DetectsUsernameFieldDespitePasswordAutoHint()
 | 
			
		||||
        {
 | 
			
		||||
            var resourceName = "Kp2aAutofillParserTest.com-ifs-banking-fiid3364-android13.json";
 | 
			
		||||
            RunTestFromAutofillInput(resourceName, "com.ifs.banking.fiid3364", null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void DetectsEmailAutofillHint()
 | 
			
		||||
        {
 | 
			
		||||
            var resourceName = "Kp2aAutofillParserTest.com-expressvpn-vpn-android13.json";
 | 
			
		||||
            RunTestFromAutofillInput(resourceName, "com.expressvpn.vpn", null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void RunTestFromAutofillInput(string resourceName, string expectedPackageName = null, string expectedWebDomain = null)
 | 
			
		||||
        {
 | 
			
		||||
            var assembly = Assembly.GetExecutingAssembly();
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            string input;
 | 
			
		||||
            using (Stream stream = assembly.GetManifestResourceStream(resourceName))
 | 
			
		||||
            using (StreamReader reader = new StreamReader(stream))
 | 
			
		||||
            {
 | 
			
		||||
                input = reader.ReadToEnd();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            AutofillView<TestInputField>? autofillView =
 | 
			
		||||
                JsonConvert.DeserializeObject<AutofillView<TestInputField>>(input);
 | 
			
		||||
 | 
			
		||||
            StructureParserBase<TestInputField> parser =
 | 
			
		||||
                new StructureParserBase<TestInputField>(new TestLogger(), new TestDalSourceTrustAll());
 | 
			
		||||
 | 
			
		||||
            var result = parser.ParseForFill(false, autofillView);
 | 
			
		||||
            if (expectedPackageName != null)
 | 
			
		||||
                Assert.Equal(expectedPackageName, result.PackageName);
 | 
			
		||||
            if (expectedWebDomain != null)
 | 
			
		||||
                Assert.Equal(expectedWebDomain, result.WebDomain);
 | 
			
		||||
            foreach (var field in autofillView.InputFields)
 | 
			
		||||
            {
 | 
			
		||||
                string[] expectedHints = field.ExpectedAssignedHints;
 | 
			
		||||
                if (expectedHints == null)
 | 
			
		||||
                    expectedHints = new string[0];
 | 
			
		||||
                string[] actualHints;
 | 
			
		||||
                parser.FieldsMappedToHints.TryGetValue(field, out actualHints);
 | 
			
		||||
                if (actualHints == null)
 | 
			
		||||
                    actualHints = new string[0];
 | 
			
		||||
                if (actualHints.Any() || expectedHints.Any())
 | 
			
		||||
                {
 | 
			
		||||
                    _testOutputHelper.WriteLine($"field = {field.IdEntry} {field.Hint} {string.Join(",", field.AutofillHints ?? new string[]{})}");
 | 
			
		||||
                    _testOutputHelper.WriteLine("actual Hints = " + string.Join(", ", actualHints));
 | 
			
		||||
                    _testOutputHelper.WriteLine("expected Hints = " + string.Join(", ", expectedHints));
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                Assert.Equal(expectedHints.Length, actualHints.Length);
 | 
			
		||||
                Assert.Equal(expectedHints.OrderBy(x => x), actualHints.OrderBy(x => x));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class TestDalSourceTrustAll : IKp2aDigitalAssetLinksDataSource
 | 
			
		||||
    {
 | 
			
		||||
        public bool IsTrustedApp(string packageName)
 | 
			
		||||
        {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool IsTrustedLink(string domain, string targetPackage)
 | 
			
		||||
        {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool IsEnabled()
 | 
			
		||||
        {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class TestLogger : ILogger
 | 
			
		||||
    {
 | 
			
		||||
        public void Log(string x)
 | 
			
		||||
        {
 | 
			
		||||
            Console.WriteLine(x);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										58
									
								
								src/Kp2aAutofillParserTest/Kp2aAutofillParserTest.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								src/Kp2aAutofillParserTest/Kp2aAutofillParserTest.csproj
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <TargetFramework>net6.0</TargetFramework>
 | 
			
		||||
    <ImplicitUsings>enable</ImplicitUsings>
 | 
			
		||||
    <Nullable>enable</Nullable>
 | 
			
		||||
 | 
			
		||||
    <IsPackable>false</IsPackable>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Remove="chrome-android10-amazon-it.json" />
 | 
			
		||||
    <None Remove="com-expressvpn-vpn-android13.json" />
 | 
			
		||||
    <None Remove="com-ifs-banking-fiid3364-android13.json" />
 | 
			
		||||
    <None Remove="com-servicenet-mobile-focused.json" />
 | 
			
		||||
    <None Remove="com-servicenet-mobile-no-focus.json" />
 | 
			
		||||
    <None Remove="firefox-amazon-it.json" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
 | 
			
		||||
    <PackageReference Include="xunit" Version="2.4.2" />
 | 
			
		||||
    <PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
 | 
			
		||||
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
 | 
			
		||||
      <PrivateAssets>all</PrivateAssets>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="coverlet.collector" Version="3.1.2">
 | 
			
		||||
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
 | 
			
		||||
      <PrivateAssets>all</PrivateAssets>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\Kp2aAutofillParser\Kp2aAutofillParser.csproj" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <EmbeddedResource Include="chrome-android10-amazon-it.json">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </EmbeddedResource>
 | 
			
		||||
    <EmbeddedResource Include="com-expressvpn-vpn-android13.json">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </EmbeddedResource>
 | 
			
		||||
    <EmbeddedResource Include="com-ifs-banking-fiid3364-android13.json">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </EmbeddedResource>
 | 
			
		||||
    <EmbeddedResource Include="firefox-amazon-it.json">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </EmbeddedResource>
 | 
			
		||||
    <EmbeddedResource Include="com-servicenet-mobile-focused.json">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </EmbeddedResource>
 | 
			
		||||
    <EmbeddedResource Include="com-servicenet-mobile-no-focus.json">
 | 
			
		||||
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
 | 
			
		||||
    </EmbeddedResource>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										1
									
								
								src/Kp2aAutofillParserTest/Usings.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/Kp2aAutofillParserTest/Usings.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
global using Xunit;
 | 
			
		||||
							
								
								
									
										2018
									
								
								src/Kp2aAutofillParserTest/chrome-android10-amazon-it.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2018
									
								
								src/Kp2aAutofillParserTest/chrome-android10-amazon-it.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										226
									
								
								src/Kp2aAutofillParserTest/com-expressvpn-vpn-android13.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								src/Kp2aAutofillParserTest/com-expressvpn-vpn-android13.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,226 @@
 | 
			
		||||
{
 | 
			
		||||
  "InputFields": [
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "action_bar_root",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "action_mode_bar_stub",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.View",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "layout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "textView2",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.TextView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "emailLayout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "email",
 | 
			
		||||
      "Hint": "E-Mail",
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": [
 | 
			
		||||
        "email"
 | 
			
		||||
      ],
 | 
			
		||||
      "IsFocused": true,
 | 
			
		||||
      "InputType": 33,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null,
 | 
			
		||||
      "ExpectedAssignedHints": [ "emailAddress" ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "passwordLayout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "password",
 | 
			
		||||
      "Hint": "Passwort",
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": [
 | 
			
		||||
        "password",
 | 
			
		||||
        "passwordAuto"
 | 
			
		||||
      ],
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 129,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null,
 | 
			
		||||
      "ExpectedAssignedHints": [
 | 
			
		||||
        "password",
 | 
			
		||||
        "passwordAuto"
 | 
			
		||||
      ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "textinput_suffix_text",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.TextView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "forgotPassword",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.Button",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "amazonInfo",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "signInButtonBarrier",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.View",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "signIn",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.Button",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "newUser",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.Button",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "focusThief",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.View",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "activatingContainer",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "PackageId": "com.expressvpn.vpn",
 | 
			
		||||
  "WebDomain": null
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,322 @@
 | 
			
		||||
{
 | 
			
		||||
  "InputFields": [
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "action_bar_root",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "action_mode_bar_stub",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.View",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "loginParent",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "rooted_device_error_screen",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "scroll",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.ScrollView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "login_box_layout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "loginFragment_container_view",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "login_box",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "Edt_UserId",
 | 
			
		||||
      "Hint": "User ID",
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": [
 | 
			
		||||
        "passwordAuto"
 | 
			
		||||
      ],
 | 
			
		||||
      "IsFocused": true,
 | 
			
		||||
      "InputType": 145,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null,
 | 
			
		||||
      "ExpectedAssignedHints": [ "username" ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "login_save_userid_switch",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.CompoundButton",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "Edt_Password_layout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "Edt_Password",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": [
 | 
			
		||||
        "passwordAuto"
 | 
			
		||||
      ],
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 129,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null,
 | 
			
		||||
      "ExpectedAssignedHints": [ "password" ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "textinput_prefix_text",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.TextView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "textinput_suffix_text",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.TextView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "textinput_placeholder",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.TextView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "forgot_login_btn",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.Button",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "Btn_Login",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.Button",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "login_fab_fragment_container",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "biometric_fragment_container",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "biometricLayout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "login_menu_container",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "deposit_insurance_systems_textview",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.TextView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "login_menu",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "login_menu_item_border_right",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.View",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "login_menu_item_border_left",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.View",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "sign_up_link",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.Button",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "locations_link",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.Button",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "more_link",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.Button",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "PackageId": "com.ifs.banking.fiid3364",
 | 
			
		||||
  "WebDomain": null
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										121
									
								
								src/Kp2aAutofillParserTest/com-servicenet-mobile-focused.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								src/Kp2aAutofillParserTest/com-servicenet-mobile-focused.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
			
		||||
{
 | 
			
		||||
  "InputFields": [
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": true,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "action_bar_root",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "action_mode_bar_stub",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.View",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "content",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "username_text_input_layout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "username",
 | 
			
		||||
      "Hint": "Username",
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": true,
 | 
			
		||||
      "InputType": 97,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null,
 | 
			
		||||
      "ExpectedAssignedHints": [ "username" ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "password_text_input_layout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "password",
 | 
			
		||||
      "Hint": "Password",
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": [
 | 
			
		||||
        "passwordAuto"
 | 
			
		||||
      ],
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 129,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null,
 | 
			
		||||
 | 
			
		||||
      "ExpectedAssignedHints": [ "password" ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "login_button",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.Button",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "progressBar",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.ProgressBar",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "forgot_password",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.TextView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "PackageId": "com.servicenet.mobile",
 | 
			
		||||
  "WebDomain": null
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										119
									
								
								src/Kp2aAutofillParserTest/com-servicenet-mobile-no-focus.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/Kp2aAutofillParserTest/com-servicenet-mobile-no-focus.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
{
 | 
			
		||||
  "InputFields": [
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": true,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "action_bar_root",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "action_mode_bar_stub",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.View",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "content",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "username_text_input_layout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "username",
 | 
			
		||||
      "Hint": "Username",
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 97,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "password_text_input_layout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "password",
 | 
			
		||||
      "Hint": "Password",
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": [
 | 
			
		||||
        "passwordAuto"
 | 
			
		||||
      ],
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 129,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null,
 | 
			
		||||
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "login_button",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.Button",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "progressBar",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.ProgressBar",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "forgot_password",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.TextView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "PackageId": "com.servicenet.mobile",
 | 
			
		||||
  "WebDomain": null
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										469
									
								
								src/Kp2aAutofillParserTest/firefox-amazon-it.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										469
									
								
								src/Kp2aAutofillParserTest/firefox-amazon-it.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,469 @@
 | 
			
		||||
{
 | 
			
		||||
  "InputFields": [
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "action_bar_root",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "action_mode_bar_stub",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.View",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "rootContainer",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "navigationToolbarStub",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.View",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "container",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "container",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "gestureLayout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "browserWindow",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "browserLayout",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "swipeRefresh",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "engineView",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": true,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": "",
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": "form",
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": [
 | 
			
		||||
        "password"
 | 
			
		||||
      ],
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 225,
 | 
			
		||||
      "HtmlInfoTag": "input",
 | 
			
		||||
      "HtmlInfoTypeAttribute": "password",
 | 
			
		||||
      "ExpectedAssignedHints": [ "password" ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": [
 | 
			
		||||
        "emailAddress"
 | 
			
		||||
      ],
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 33,
 | 
			
		||||
      "HtmlInfoTag": "input",
 | 
			
		||||
      "HtmlInfoTypeAttribute": "email",
 | 
			
		||||
      "ExpectedAssignedHints": [ "emailAddress" ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": "input",
 | 
			
		||||
      "HtmlInfoTypeAttribute": "checkbox"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": "input",
 | 
			
		||||
      "HtmlInfoTypeAttribute": "submit"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": "form",
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": [
 | 
			
		||||
        "password"
 | 
			
		||||
      ],
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 225,
 | 
			
		||||
      "HtmlInfoTag": "input",
 | 
			
		||||
      "HtmlInfoTypeAttribute": "password",
 | 
			
		||||
      "ExpectedAssignedHints": [ "password" ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": [
 | 
			
		||||
        "emailAddress"
 | 
			
		||||
      ],
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 33,
 | 
			
		||||
      "HtmlInfoTag": "input",
 | 
			
		||||
      "HtmlInfoTypeAttribute": "email",
 | 
			
		||||
 | 
			
		||||
      "ExpectedAssignedHints": [ "emailAddress" ]
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": null,
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": "input",
 | 
			
		||||
      "HtmlInfoTypeAttribute": "submit"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "stubFindInPage",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.View",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "viewDynamicDownloadDialog",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "crash_reporter_view",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "toolbar",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_navigation_actions",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_origin_view",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_title_view",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.TextView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_url_view",
 | 
			
		||||
      "Hint": "Suche oder Adresse",
 | 
			
		||||
      "ClassName": "android.widget.TextView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_page_actions",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_browser_actions",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "counter_root",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "counter_text",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.TextView",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_menu",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_progress",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.ProgressBar",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_container",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_edit_actions_start",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_edit_url_view",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.EditText",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 17,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "mozac_browser_toolbar_edit_actions_end",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.LinearLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "readerViewControlsBar",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "addressSelectBar",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "creditCardSelectBar",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "loginSelectBar",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.view.ViewGroup",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "IdEntry": "tabPreview",
 | 
			
		||||
      "Hint": null,
 | 
			
		||||
      "ClassName": "android.widget.FrameLayout",
 | 
			
		||||
      "AutofillHints": null,
 | 
			
		||||
      "IsFocused": false,
 | 
			
		||||
      "InputType": 0,
 | 
			
		||||
      "HtmlInfoTag": null,
 | 
			
		||||
      "HtmlInfoTypeAttribute": null
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "PackageId": "org.mozilla.firefox",
 | 
			
		||||
  "WebDomain": "www.amazon.it"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,9 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="showFlavor">
 | 
			
		||||
<Target Name="showFlavor" AfterTargets="Build">
 | 
			
		||||
        <Message Importance="high" Text="building flavor $(Flavor)"></Message>
 | 
			
		||||
    </Target>
 | 
			
		||||
<Import Project="../build-properties.props"/>
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
 | 
			
		||||
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
 | 
			
		||||
@@ -10,10 +14,11 @@
 | 
			
		||||
    <RootNamespace>keepass2android</RootNamespace>
 | 
			
		||||
    <AssemblyName>Kp2aBusinessLogic</AssemblyName>
 | 
			
		||||
    <FileAlignment>512</FileAlignment>
 | 
			
		||||
    <AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
 | 
			
		||||
    <AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
 | 
			
		||||
    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
 | 
			
		||||
    <TargetFrameworkVersion>v11.0</TargetFrameworkVersion>
 | 
			
		||||
    <TargetFrameworkVersion>v13.0</TargetFrameworkVersion>
 | 
			
		||||
    <AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
 | 
			
		||||
    <Flavor Condition=" '$(Flavor)' != '' ">$(Flavor)</Flavor>
 | 
			
		||||
    <NuGetPackageImportStamp>
 | 
			
		||||
    </NuGetPackageImportStamp>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
@@ -37,6 +42,13 @@
 | 
			
		||||
    <JavaMaximumHeapSize>4G</JavaMaximumHeapSize>
 | 
			
		||||
    <AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <Choose>
 | 
			
		||||
    <When Condition=" '$(Flavor)'=='NoNet' ">
 | 
			
		||||
      <PropertyGroup>
 | 
			
		||||
        <DefineConstants>$(DefineConstants);NoNet;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
 | 
			
		||||
      </PropertyGroup>
 | 
			
		||||
    </When>
 | 
			
		||||
  </Choose>
 | 
			
		||||
  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseNoNet|AnyCPU'">
 | 
			
		||||
    <OutputPath>bin\ReleaseNoNet\</OutputPath>
 | 
			
		||||
    <DefineConstants>TRACE;NoNet;EXCLUDE_JAVAFILESTORAGE</DefineConstants>
 | 
			
		||||
@@ -54,10 +66,26 @@
 | 
			
		||||
    <Reference Include="mscorlib" />
 | 
			
		||||
    <Reference Include="System" />
 | 
			
		||||
    <Reference Include="System.Core" />
 | 
			
		||||
    <Reference Include="System.Net.Http" />
 | 
			
		||||
    <Reference Include="System.Xml.Linq" />
 | 
			
		||||
    <Reference Include="System.Xml" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup Condition=" '$(Flavor)'!='NoNet' ">
 | 
			
		||||
    <Reference Include="System.Net.Http" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup Condition=" '$(Flavor)'!='NoNet' ">
 | 
			
		||||
    <Compile Include="Io\DropboxFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\DropboxFileStorageKeys.cs" />
 | 
			
		||||
    <Compile Include="Io\GDriveFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\JavaFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\MegaFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\NetFtpFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\OneDrive2FileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\OneDrive2PrefixContainer.cs" />
 | 
			
		||||
    <Compile Include="Io\PCloudFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\SftpFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\OneDriveFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\WebDavFileStorage.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Compile Include="database\CheckDatabaseForChanges.cs" />
 | 
			
		||||
    <Compile Include="database\edit\AddTemplateEntries.cs" />
 | 
			
		||||
@@ -78,24 +106,12 @@
 | 
			
		||||
    <Compile Include="Io\AndroidContentStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\BuiltInFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\CachingFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\DropboxFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\DropboxFileStorageKeys.cs" />
 | 
			
		||||
    <Compile Include="Io\FileDescription.cs" />
 | 
			
		||||
    <Compile Include="Io\FileStorageSetupActivity.cs" />
 | 
			
		||||
    <Compile Include="Io\FileStorageSetupInitiatorActivity.cs" />
 | 
			
		||||
    <Compile Include="Io\GDriveFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\IFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\IoUtil.cs" />
 | 
			
		||||
    <Compile Include="Io\JavaFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\MegaFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\NetFtpFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\OfflineSwitchableFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\OneDrive2FileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\OneDrive2PrefixContainer.cs" />
 | 
			
		||||
    <Compile Include="Io\PCloudFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\SftpFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\OneDriveFileStorage.cs" />
 | 
			
		||||
    <Compile Include="Io\WebDavFileStorage.cs" />
 | 
			
		||||
    <Compile Include="IProgressDialog.cs" />
 | 
			
		||||
    <Compile Include="PreferenceKey.cs" />
 | 
			
		||||
    <Compile Include="SelectStorageLocationActivityBase.cs" />
 | 
			
		||||
@@ -130,7 +146,7 @@
 | 
			
		||||
    <Compile Include="Utils\Spr\SprEngine.cs" />
 | 
			
		||||
    <Compile Include="Utils\Spr\SprEngine.PickChars.cs" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
  <ItemGroup Condition=" '$(Flavor)'!='NoNet' ">
 | 
			
		||||
    <ProjectReference Include="..\AndroidFileChooserBinding\AndroidFileChooserBinding.csproj">
 | 
			
		||||
      <Project>{3c0f7fe5-639f-4422-a087-8b26cf862d1b}</Project>
 | 
			
		||||
      <Name>AndroidFileChooserBinding</Name>
 | 
			
		||||
@@ -139,6 +155,12 @@
 | 
			
		||||
      <Project>{48574278-4779-4b3a-a9e4-9cf1bc285d0b}</Project>
 | 
			
		||||
      <Name>JavaFileStorageBindings</Name>
 | 
			
		||||
    </ProjectReference>
 | 
			
		||||
    <ProjectReference Include="..\PCloudBindings\PCloudBindings.csproj">
 | 
			
		||||
      <Project>{2db80c77-d46f-4970-b967-e9ffa9b2ac2e}</Project>
 | 
			
		||||
      <Name>PCloudBindings</Name>
 | 
			
		||||
    </ProjectReference>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ProjectReference Include="..\KeePassLib2Android\KeePassLib2Android.csproj">
 | 
			
		||||
      <Project>{545B4A6B-8BBA-4FBE-92FC-4AC060122A54}</Project>
 | 
			
		||||
      <Name>KeePassLib2Android</Name>
 | 
			
		||||
@@ -147,10 +169,6 @@
 | 
			
		||||
      <Project>{70D3844A-D9FA-4A64-B205-A84C6A822196}</Project>
 | 
			
		||||
      <Name>KP2AKdbLibraryBinding</Name>
 | 
			
		||||
    </ProjectReference>
 | 
			
		||||
    <ProjectReference Include="..\PCloudBindings\PCloudBindings.csproj">
 | 
			
		||||
      <Project>{2db80c77-d46f-4970-b967-e9ffa9b2ac2e}</Project>
 | 
			
		||||
      <Name>PCloudBindings</Name>
 | 
			
		||||
    </ProjectReference>
 | 
			
		||||
    <ProjectReference Include="..\TwofishCipher\TwofishCipher.csproj">
 | 
			
		||||
      <Project>{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}</Project>
 | 
			
		||||
      <Name>TwofishCipher</Name>
 | 
			
		||||
@@ -162,22 +180,24 @@
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <None Include="app.config" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
  <ItemGroup Condition=" '$(Flavor)'!='NoNet' ">
 | 
			
		||||
    <PackageReference Include="FluentFTP">
 | 
			
		||||
      <Version>31.3.1</Version>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="MegaApiClient">
 | 
			
		||||
      <Version>1.10.2</Version>
 | 
			
		||||
      <Version>1.10.3</Version>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="Microsoft.Graph">
 | 
			
		||||
      <Version>1.21.0</Version>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="Microsoft.Graph.Auth">
 | 
			
		||||
      <Version>1.0.0-preview.1</Version>
 | 
			
		||||
      <Version>1.0.0-preview.7</Version>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="Microsoft.Identity.Client">
 | 
			
		||||
      <Version>4.8.2</Version>
 | 
			
		||||
      <Version>4.49.1</Version>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Xamarin.Android.Arch.Core.Common">
 | 
			
		||||
      <Version>1.1.1.3</Version>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
@@ -281,7 +301,7 @@
 | 
			
		||||
      <Version>28.0.0.3</Version>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
    <PackageReference Include="Xamarin.AndroidX.Preference">
 | 
			
		||||
      <Version>1.1.1.11</Version>
 | 
			
		||||
      <Version>1.2.0.3</Version>
 | 
			
		||||
    </PackageReference>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8157
									
								
								src/Kp2aBusinessLogic/Resources/Resource.Designer.cs
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8157
									
								
								src/Kp2aBusinessLogic/Resources/Resource.Designer.cs
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,37 +0,0 @@
 | 
			
		||||
This directory is for Android .jars.
 | 
			
		||||
 | 
			
		||||
There are 3 types of jars that are supported:
 | 
			
		||||
 | 
			
		||||
== Input Jar and Embedded Jar ==
 | 
			
		||||
 | 
			
		||||
This is the jar that bindings should be generated for.
 | 
			
		||||
 | 
			
		||||
For example, if you were binding the Google Maps library, this would
 | 
			
		||||
be Google's "maps.jar".
 | 
			
		||||
 | 
			
		||||
The difference between EmbeddedJar and InputJar is, EmbeddedJar is to be
 | 
			
		||||
embedded in the resulting dll as EmbeddedResource, while InputJar is not.
 | 
			
		||||
There are couple of reasons you wouldn't like to embed the target jar
 | 
			
		||||
in your dll (the ones that could be internally loaded by <uses-library>
 | 
			
		||||
feature e.g. maps.jar, or you cannot embed jars that are under some
 | 
			
		||||
proprietary license).
 | 
			
		||||
 | 
			
		||||
Set the build action for these jars in the properties page to "InputJar".
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
== Reference Jar and Embedded Reference Jar ==
 | 
			
		||||
 | 
			
		||||
These are jars that are referenced by the input jar.  C# bindings will
 | 
			
		||||
not be created for these jars.  These jars will be used to resolve
 | 
			
		||||
types used by the input jar.
 | 
			
		||||
 | 
			
		||||
NOTE: Do not add "android.jar" as a reference jar.  It will be added automatically
 | 
			
		||||
based on the Target Framework selected.
 | 
			
		||||
 | 
			
		||||
Set the build action for these jars in the properties page to "ReferenceJar".
 | 
			
		||||
 | 
			
		||||
"EmbeddedJar" works like "ReferenceJar", but like "EmbeddedJar", it is
 | 
			
		||||
embedded in your dll. But at application build time, they are not included
 | 
			
		||||
in the final apk, like ReferenceJar files.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
    <AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
 | 
			
		||||
    <TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
 | 
			
		||||
    <AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
 | 
			
		||||
    <AndroidClassParser>class-parse</AndroidClassParser>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
			
		||||
    <DebugSymbols>True</DebugSymbols>
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
    <AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
 | 
			
		||||
    <TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
 | 
			
		||||
    <AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
 | 
			
		||||
    <AndroidClassParser>class-parse</AndroidClassParser>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
			
		||||
    <DebugSymbols>true</DebugSymbols>
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@
 | 
			
		||||
    <AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
 | 
			
		||||
    <TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
 | 
			
		||||
    <AndroidCodegenTarget>XAJavaInterop1</AndroidCodegenTarget>
 | 
			
		||||
    <AndroidClassParser>class-parse</AndroidClassParser>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
 | 
			
		||||
    <DebugSymbols>true</DebugSymbols>
 | 
			
		||||
 
 | 
			
		||||
@@ -10,7 +10,7 @@
 | 
			
		||||
    <RootNamespace>TwofishCipher</RootNamespace>
 | 
			
		||||
    <AssemblyName>TwofishCipher</AssemblyName>
 | 
			
		||||
    <FileAlignment>512</FileAlignment>
 | 
			
		||||
    <AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
 | 
			
		||||
    <AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
 | 
			
		||||
    <GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
 | 
			
		||||
    <AndroidUseLatestPlatformSdk>false</AndroidUseLatestPlatformSdk>
 | 
			
		||||
    <TargetFrameworkVersion>v8.0</TargetFrameworkVersion>
 | 
			
		||||
@@ -54,7 +54,7 @@
 | 
			
		||||
    <Reference Include="System.Xml" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <Compile Include="Resources\Resource.Designer.cs" />
 | 
			
		||||
    <Compile Include="Resources\Resource.designer.cs" />
 | 
			
		||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
			
		||||
    <Compile Include="Twofish.cs" />
 | 
			
		||||
    <Compile Include="TwofishBase.cs" />
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								src/build-properties.props
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/build-properties.props
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
<Project>
 | 
			
		||||
<PropertyGroup>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<Flavor>NoNet</Flavor>
 | 
			
		||||
 | 
			
		||||
</PropertyGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
echo '*****************************************'
 | 
			
		||||
echo '******* Building native libraries *******'
 | 
			
		||||
echo '*****************************************'
 | 
			
		||||
./build-native.sh
 | 
			
		||||
 | 
			
		||||
echo '*****************************************'
 | 
			
		||||
echo '********** Building Java parts **********'
 | 
			
		||||
echo '*****************************************'
 | 
			
		||||
./build-java.sh
 | 
			
		||||
 | 
			
		||||
echo '*****************************************'
 | 
			
		||||
echo '******** Building Xamarin parts *********'
 | 
			
		||||
echo '*****************************************'
 | 
			
		||||
./build-xamarin.sh
 | 
			
		||||
 | 
			
		||||
echo '*****************************************'
 | 
			
		||||
echo '************** Building APK *************'
 | 
			
		||||
echo '*****************************************'
 | 
			
		||||
./build-apk.sh
 | 
			
		||||
 | 
			
		||||
echo
 | 
			
		||||
echo 'Congratulations! You you can find the target APK in src/keepass2android/bin/Debug/.'
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
pushd ../keepass2android
 | 
			
		||||
 | 
			
		||||
# check if ANDROID_HOME is defined
 | 
			
		||||
if [ -z ${ANDROID_HOME+x} ];
 | 
			
		||||
then
 | 
			
		||||
	xabuild keepass2android.csproj /t:SignAndroidPackage "$@"
 | 
			
		||||
else
 | 
			
		||||
	xabuild keepass2android.csproj /p:AndroidSdkDirectory=$ANDROID_HOME /t:SignAndroidPackage "$@"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
popd
 | 
			
		||||
@@ -1,20 +1,15 @@
 | 
			
		||||
cd ..\java\JavaFileStorageTest-AS
 | 
			
		||||
./gradlew clean assemble
 | 
			
		||||
call ./gradlew clean assemble || exit /b
 | 
			
		||||
cd ..\..\build-scripts
 | 
			
		||||
 | 
			
		||||
cd ..\java\KP2ASoftkeyboard_AS
 | 
			
		||||
./gradlew clean assemble
 | 
			
		||||
call ./gradlew clean assemble || exit /b
 | 
			
		||||
cd ..\..\build-scripts
 | 
			
		||||
 | 
			
		||||
cd ..\java\Keepass2AndroidPluginSDK2
 | 
			
		||||
./gradlew clean assemble
 | 
			
		||||
call ./gradlew clean assemble || exit /b
 | 
			
		||||
cd ..\..\build-scripts
 | 
			
		||||
 | 
			
		||||
cd ..\java\KP2AKdbLibrary
 | 
			
		||||
./gradlew clean assemble
 | 
			
		||||
cd ..\..\build-scripts
 | 
			
		||||
 | 
			
		||||
cd ..\java\PluginQR
 | 
			
		||||
./gradlew clean assemble
 | 
			
		||||
 | 
			
		||||
call ./gradlew clean assemble || exit /b
 | 
			
		||||
cd ..\..\build-scripts
 | 
			
		||||
 
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
unset ANDROID_NDK_HOME ANDROID_NDK
 | 
			
		||||
 | 
			
		||||
pushd ../java/
 | 
			
		||||
 | 
			
		||||
pushd JavaFileStorageTest-AS
 | 
			
		||||
./gradlew assemble
 | 
			
		||||
popd
 | 
			
		||||
 | 
			
		||||
pushd KP2ASoftkeyboard_AS
 | 
			
		||||
./gradlew assemble
 | 
			
		||||
popd
 | 
			
		||||
 | 
			
		||||
pushd Keepass2AndroidPluginSDK2
 | 
			
		||||
./gradlew assemble
 | 
			
		||||
popd
 | 
			
		||||
 | 
			
		||||
pushd PluginQR
 | 
			
		||||
./gradlew assemble
 | 
			
		||||
popd
 | 
			
		||||
 | 
			
		||||
popd
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
pushd ../java/argon2
 | 
			
		||||
ndk-build
 | 
			
		||||
popd
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
cd ..\Kp2aBusinessLogic\Io
 | 
			
		||||
if exist "DropboxFileStorageKeys.cs" (
 | 
			
		||||
  echo DropboxFileStorageKeys.cs found.
 | 
			
		||||
) ELSE (
 | 
			
		||||
  xcopy DropboxFileStorageKeysDummy.cs DropboxFileStorageKeys.cs*
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
cd ..\..\keepass2android
 | 
			
		||||
call UseManifestDebug.bat
 | 
			
		||||
cd ..
 | 
			
		||||
 | 
			
		||||
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
 | 
			
		||||
 | 
			
		||||
msbuild KeePass.sln /target:keepass2android /p:BuildProjectReferences=true /p:Configuration="Debug" /p:Platform="Any CPU"
 | 
			
		||||
 | 
			
		||||
cd build-scripts
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
pushd ..
 | 
			
		||||
 | 
			
		||||
pushd Kp2aBusinessLogic/Io
 | 
			
		||||
 | 
			
		||||
if [ -f "DropboxFileStorageKeys.cs" ]
 | 
			
		||||
then
 | 
			
		||||
  echo "DropboxFileStorageKeys.cs found."
 | 
			
		||||
else
 | 
			
		||||
  cp DropboxFileStorageKeysDummy.cs DropboxFileStorageKeys.cs
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
popd
 | 
			
		||||
 | 
			
		||||
pushd keepass2android
 | 
			
		||||
./UseManifestDebug.sh
 | 
			
		||||
popd
 | 
			
		||||
 | 
			
		||||
# call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
 | 
			
		||||
 | 
			
		||||
# check if ANDROID_HOME is defined
 | 
			
		||||
if [ -z ${ANDROID_HOME+x} ];
 | 
			
		||||
then
 | 
			
		||||
	xabuild KeePass.sln /target:keepass2android /p:BuildProjectReferences=true /p:Configuration="Debug" /p:Platform="Any CPU" "$@"
 | 
			
		||||
else
 | 
			
		||||
	xabuild KeePass.sln /target:keepass2android /p:AndroidSdkDirectory=$ANDROID_HOME /p:BuildProjectReferences=true /p:Configuration="Debug" /p:Platform="Any CPU" "$@"
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
popd
 | 
			
		||||
@@ -1,56 +0,0 @@
 | 
			
		||||
# How to build Keepass2Android
 | 
			
		||||
 | 
			
		||||
## Overview
 | 
			
		||||
 | 
			
		||||
Keepass2Android is a Mono for Android app. This means that you need Xamarin's Mono for Android to build it. However, it also uses several components written in Java, so there are also Android-Studio projects involved. To make things even worse, parts of the keyboard and kdb-library are written in native code.
 | 
			
		||||
The current build-scripts assume that the native libraries are already built (they are included in the repo). 
 | 
			
		||||
 | 
			
		||||
To build KP2A from scratch, make sure that you have Xamarin's Mono for Android installed and also install Android Studio. Make sure that both point to the same Android SDK location.
 | 
			
		||||
 | 
			
		||||
## Prerequisites
 | 
			
		||||
 | 
			
		||||
- Install Xamarin.Android
 | 
			
		||||
- Fetch all submodules (`git submodule init && git submodule update`)
 | 
			
		||||
 | 
			
		||||
## Build
 | 
			
		||||
 | 
			
		||||
### On Windows
 | 
			
		||||
 | 
			
		||||
```bat
 | 
			
		||||
cd build-scripts
 | 
			
		||||
build-java.bat
 | 
			
		||||
build-xamarin.bat
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
build-java.bat will call gradlew for several Java modules. build-xamarin.bat will first make sure that you have all files at their place. (There is a "secret" file for Dropbox SDK keys which is not in the repo, this is replaced with a dummy file. There are also different Android Manifest files depending on the configuration which is selected by calling the appropriate script.)
 | 
			
		||||
 | 
			
		||||
**Notes:**
 | 
			
		||||
 | 
			
		||||
 - For building the java parts, it is suggested to keep a short name (e.g. "c:\projects\keepass2android") for the root project directory. Otherwise the Windows path length limit might be hit when building.
 | 
			
		||||
 - Before building the java parts, make sure you have set the ANDROID_HOME variable or create a local.properties file inside the directories with a gradlew file. It is recommended to use the same SDK location as that of the Xamarin build.
 | 
			
		||||
 | 
			
		||||
### On Linux
 | 
			
		||||
 | 
			
		||||
- Install [Mono](https://www.mono-project.com/)
 | 
			
		||||
- Install Xamarin.Android
 | 
			
		||||
  - Option 1: Use the mono-project [CI builds](https://dev.azure.com/xamarin/public/_build/latest?definitionId=48&branchName=main&stageName=Linux)
 | 
			
		||||
  - Option 2: [Build it from source](https://github.com/xamarin/xamarin-android/blob/master/Documentation/README.md#building-from-source)
 | 
			
		||||
- Setup your environment:
 | 
			
		||||
  - Add `xabuild` to your path: `export PATH=/path/to/xamarin.android-oss/bin/Release/bin/:$PATH`
 | 
			
		||||
  - Setup your `ANDROID_HOME` if it's not already: `export ANDROID_HOME=/path/to/android/`
 | 
			
		||||
  - Alternatively, you can set your `ANDROID_SDK_PATH` and `ANDROID_NDK_PATH`.
 | 
			
		||||
- Build [jar2xml](https://github.com/xamarin/jar2xml) and copy `jar2xml.jar` to `/path/to/xamarin.android-oss/bin/Release/lib/xamarin.android/xbuild/Xamarin/Android/`
 | 
			
		||||
- Install [libzip](https://libzip.org/) for your distribution.
 | 
			
		||||
  - Note: Xamarin seems to require `libzip4`, yet most distributions only ships `libzip5`. As a dirty workaround, it's possible to symlink `libzip.so.5` to `libzip.so.4`. Luckily, it appears to be working.
 | 
			
		||||
  - `sudo ln -s /usr/lib/libzip.so.5 /usr/lib/libzip.so.4`
 | 
			
		||||
  - or `sudo ln -s /usr/lib64/libzip.so.5 /usr/lib/libzip.so.4`
 | 
			
		||||
- Install NuGet dependencies:
 | 
			
		||||
  - `cd src/ && nuget restore KeePass.sln`
 | 
			
		||||
- Build:
 | 
			
		||||
  - Option 1: `cd build-scripts && ./build-all.sh`
 | 
			
		||||
  - Option 2:
 | 
			
		||||
    - Build the Java parts: `cd build-scripts/ && ./build-java.sh`
 | 
			
		||||
    - Build the Xamarin parts: `./build-xamarin.sh`
 | 
			
		||||
    - Build the signed APK: `./build-apk.sh`
 | 
			
		||||
- Enjoy:
 | 
			
		||||
  - `adb install ../keepass2android/bin/Debug/keepass2android.keepass2android_debug-Signed.apk`
 | 
			
		||||
							
								
								
									
										1
									
								
								src/java/JavaFileStorage/.idea/.name
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								src/java/JavaFileStorage/.idea/.name
									
									
									
										generated
									
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
JavaFileStorage
 | 
			
		||||
							
								
								
									
										22
									
								
								src/java/JavaFileStorage/.idea/compiler.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										22
									
								
								src/java/JavaFileStorage/.idea/compiler.xml
									
									
									
										generated
									
									
									
								
							@@ -1,22 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="CompilerConfiguration">
 | 
			
		||||
    <resourceExtensions />
 | 
			
		||||
    <wildcardResourcePatterns>
 | 
			
		||||
      <entry name="!?*.java" />
 | 
			
		||||
      <entry name="!?*.form" />
 | 
			
		||||
      <entry name="!?*.class" />
 | 
			
		||||
      <entry name="!?*.groovy" />
 | 
			
		||||
      <entry name="!?*.scala" />
 | 
			
		||||
      <entry name="!?*.flex" />
 | 
			
		||||
      <entry name="!?*.kt" />
 | 
			
		||||
      <entry name="!?*.clj" />
 | 
			
		||||
      <entry name="!?*.aj" />
 | 
			
		||||
    </wildcardResourcePatterns>
 | 
			
		||||
    <annotationProcessing>
 | 
			
		||||
      <profile default="true" name="Default" enabled="false">
 | 
			
		||||
        <processorPath useClasspath="true" />
 | 
			
		||||
      </profile>
 | 
			
		||||
    </annotationProcessing>
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
<component name="CopyrightManager">
 | 
			
		||||
  <settings default="" />
 | 
			
		||||
</component>
 | 
			
		||||
							
								
								
									
										25
									
								
								src/java/JavaFileStorage/.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										25
									
								
								src/java/JavaFileStorage/.idea/gradle.xml
									
									
									
										generated
									
									
									
								
							@@ -1,25 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="GradleSettings">
 | 
			
		||||
    <option name="linkedExternalProjectsSettings">
 | 
			
		||||
      <GradleProjectSettings>
 | 
			
		||||
        <option name="distributionType" value="LOCAL" />
 | 
			
		||||
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
 | 
			
		||||
        <option name="gradleHome" value="C:\Program Files\Android\Android Studio\gradle\gradle-2.2.1" />
 | 
			
		||||
        <option name="gradleJvm" value="1.7" />
 | 
			
		||||
        <option name="modules">
 | 
			
		||||
          <set>
 | 
			
		||||
            <option value="$PROJECT_DIR$" />
 | 
			
		||||
            <option value="$PROJECT_DIR$/app" />
 | 
			
		||||
          </set>
 | 
			
		||||
        </option>
 | 
			
		||||
        <option name="myModules">
 | 
			
		||||
          <set>
 | 
			
		||||
            <option value="$PROJECT_DIR$" />
 | 
			
		||||
            <option value="$PROJECT_DIR$/app" />
 | 
			
		||||
          </set>
 | 
			
		||||
        </option>
 | 
			
		||||
      </GradleProjectSettings>
 | 
			
		||||
    </option>
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										46
									
								
								src/java/JavaFileStorage/.idea/misc.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										46
									
								
								src/java/JavaFileStorage/.idea/misc.xml
									
									
									
										generated
									
									
									
								
							@@ -1,46 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="EntryPointsManager">
 | 
			
		||||
    <entry_points version="2.0" />
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="NullableNotNullManager">
 | 
			
		||||
    <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
 | 
			
		||||
    <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
 | 
			
		||||
    <option name="myNullables">
 | 
			
		||||
      <value>
 | 
			
		||||
        <list size="4">
 | 
			
		||||
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
 | 
			
		||||
          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
 | 
			
		||||
          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
 | 
			
		||||
          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
 | 
			
		||||
        </list>
 | 
			
		||||
      </value>
 | 
			
		||||
    </option>
 | 
			
		||||
    <option name="myNotNulls">
 | 
			
		||||
      <value>
 | 
			
		||||
        <list size="4">
 | 
			
		||||
          <item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
 | 
			
		||||
          <item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
 | 
			
		||||
          <item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
 | 
			
		||||
          <item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
 | 
			
		||||
        </list>
 | 
			
		||||
      </value>
 | 
			
		||||
    </option>
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
 | 
			
		||||
    <OptionsSetting value="true" id="Add" />
 | 
			
		||||
    <OptionsSetting value="true" id="Remove" />
 | 
			
		||||
    <OptionsSetting value="true" id="Checkout" />
 | 
			
		||||
    <OptionsSetting value="true" id="Update" />
 | 
			
		||||
    <OptionsSetting value="true" id="Status" />
 | 
			
		||||
    <OptionsSetting value="true" id="Edit" />
 | 
			
		||||
    <ConfirmationsSetting value="0" id="Add" />
 | 
			
		||||
    <ConfirmationsSetting value="0" id="Remove" />
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
 | 
			
		||||
    <output url="file://$PROJECT_DIR$/build/classes" />
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="ProjectType">
 | 
			
		||||
    <option name="id" value="Android" />
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										9
									
								
								src/java/JavaFileStorage/.idea/modules.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										9
									
								
								src/java/JavaFileStorage/.idea/modules.xml
									
									
									
										generated
									
									
									
								
							@@ -1,9 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="ProjectModuleManager">
 | 
			
		||||
    <modules>
 | 
			
		||||
      <module fileurl="file://$PROJECT_DIR$/JavaFileStorage.iml" filepath="$PROJECT_DIR$/JavaFileStorage.iml" />
 | 
			
		||||
      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
 | 
			
		||||
    </modules>
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
							
								
								
									
										6
									
								
								src/java/JavaFileStorage/.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								src/java/JavaFileStorage/.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							@@ -1,6 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<project version="4">
 | 
			
		||||
  <component name="VcsDirectoryMappings">
 | 
			
		||||
    <mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
 | 
			
		||||
  </component>
 | 
			
		||||
</project>
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<module external.linked.project.id="JavaFileStorage" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
 | 
			
		||||
  <component name="FacetManager">
 | 
			
		||||
    <facet type="java-gradle" name="Java-Gradle">
 | 
			
		||||
      <configuration>
 | 
			
		||||
        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
 | 
			
		||||
        <option name="BUILDABLE" value="false" />
 | 
			
		||||
      </configuration>
 | 
			
		||||
    </facet>
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
 | 
			
		||||
    <exclude-output />
 | 
			
		||||
    <content url="file://$MODULE_DIR$">
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
 | 
			
		||||
    </content>
 | 
			
		||||
    <orderEntry type="inheritedJdk" />
 | 
			
		||||
    <orderEntry type="sourceFolder" forTests="false" />
 | 
			
		||||
  </component>
 | 
			
		||||
</module>
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<module external.linked.project.id="JavaFileStorage2" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
 | 
			
		||||
  <component name="FacetManager">
 | 
			
		||||
    <facet type="java-gradle" name="Java-Gradle">
 | 
			
		||||
      <configuration>
 | 
			
		||||
        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
 | 
			
		||||
        <option name="BUILDABLE" value="false" />
 | 
			
		||||
      </configuration>
 | 
			
		||||
    </facet>
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="NewModuleRootManager" inherit-compiler-output="true">
 | 
			
		||||
    <exclude-output />
 | 
			
		||||
    <content url="file://$MODULE_DIR$">
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
 | 
			
		||||
    </content>
 | 
			
		||||
    <orderEntry type="jdk" jdkName="1.7" jdkType="JavaSDK" />
 | 
			
		||||
    <orderEntry type="sourceFolder" forTests="false" />
 | 
			
		||||
  </component>
 | 
			
		||||
</module>
 | 
			
		||||
@@ -1,142 +0,0 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
			
		||||
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="JavaFileStorage" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
 | 
			
		||||
  <component name="FacetManager">
 | 
			
		||||
    <facet type="android-gradle" name="Android-Gradle">
 | 
			
		||||
      <configuration>
 | 
			
		||||
        <option name="GRADLE_PROJECT_PATH" value=":app" />
 | 
			
		||||
      </configuration>
 | 
			
		||||
    </facet>
 | 
			
		||||
    <facet type="android" name="Android">
 | 
			
		||||
      <configuration>
 | 
			
		||||
        <option name="SELECTED_BUILD_VARIANT" value="debug" />
 | 
			
		||||
        <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
 | 
			
		||||
        <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
 | 
			
		||||
        <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
 | 
			
		||||
        <afterSyncTasks>
 | 
			
		||||
          <task>generateDebugSources</task>
 | 
			
		||||
        </afterSyncTasks>
 | 
			
		||||
        <option name="ALLOW_USER_CONFIGURATION" value="false" />
 | 
			
		||||
        <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
 | 
			
		||||
        <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
 | 
			
		||||
        <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
 | 
			
		||||
        <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
 | 
			
		||||
        <option name="LIBRARY_PROJECT" value="true" />
 | 
			
		||||
      </configuration>
 | 
			
		||||
    </facet>
 | 
			
		||||
  </component>
 | 
			
		||||
  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
 | 
			
		||||
    <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
 | 
			
		||||
    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
 | 
			
		||||
    <exclude-output />
 | 
			
		||||
    <content url="file://$MODULE_DIR$">
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug" type="java-test-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
 | 
			
		||||
      <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotations" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-compat/24.2.0/jars" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-core-ui/24.2.0/jars" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-core-utils/24.2.0/jars" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-fragment/24.2.0/jars" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-media-compat/24.2.0/jars" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/24.2.0/jars" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services/4.0.30/jars" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.microsoft.aad/adal/1.1.19/jars" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.microsoft.services.msa/msa-auth/0.8.6/jars" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.onedrive.sdk/onedrive-sdk-android/1.2.2/jars" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard-rules" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
 | 
			
		||||
      <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
 | 
			
		||||
    </content>
 | 
			
		||||
    <orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
 | 
			
		||||
    <orderEntry type="sourceFolder" forTests="false" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="support-core-utils-24.2.0" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="dropbox-core-sdk-2.1.1" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="onedrive-sdk-android-1.2.2" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" scope="TEST" name="httpclient-4.0.1" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="google-api-client-android-1.16.0-rc" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="support-v4-24.2.0" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" scope="TEST" name="mockable-android-23" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="jackson-core-2.7.4" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="msa-auth-0.8.6" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="google-http-client-android-1.16.0-rc" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="support-annotations-24.2.0" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" scope="TEST" name="xpp3-1.1.4c" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="play-services-4.0.30" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" scope="TEST" name="commons-logging-1.1.1" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" scope="TEST" name="commons-codec-1.3" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="jsr305-1.3.9" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="google-api-services-drive-v2-rev102-1.16.0-rc" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="support-fragment-24.2.0" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="adal-1.1.19" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="okio-1.9.0" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="google-api-client-1.16.0-rc" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="google-http-client-1.16.0-rc" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="google-oauth-client-1.16.0-rc" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="gson-2.3.1" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="okhttp-3.4.1" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="support-compat-24.2.0" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="support-core-ui-24.2.0" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="google-http-client-gson-1.16.0-rc" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" scope="TEST" name="httpcore-4.0.1" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="okhttp-digest-1.7" level="project" />
 | 
			
		||||
    <orderEntry type="library" exported="" name="support-media-compat-24.2.0" level="project" />
 | 
			
		||||
  </component>
 | 
			
		||||
</module>
 | 
			
		||||
@@ -1,11 +1,14 @@
 | 
			
		||||
apply plugin: 'com.android.library'
 | 
			
		||||
 | 
			
		||||
android {
 | 
			
		||||
    compileSdkVersion 28
 | 
			
		||||
    buildToolsVersion '28.0.3'
 | 
			
		||||
 | 
			
		||||
    namespace 'keepass2android.javafilestorage'
 | 
			
		||||
 | 
			
		||||
    compileSdkVersion 33
 | 
			
		||||
 | 
			
		||||
    defaultConfig {
 | 
			
		||||
        minSdkVersion 15
 | 
			
		||||
        targetSdkVersion 28
 | 
			
		||||
        targetSdkVersion 33
 | 
			
		||||
    }
 | 
			
		||||
    buildTypes {
 | 
			
		||||
        release {
 | 
			
		||||
@@ -16,8 +19,8 @@ android {
 | 
			
		||||
    productFlavors {
 | 
			
		||||
    }
 | 
			
		||||
    compileOptions {
 | 
			
		||||
        sourceCompatibility 1.8
 | 
			
		||||
        targetCompatibility 1.8
 | 
			
		||||
        sourceCompatibility 11
 | 
			
		||||
        targetCompatibility 11
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -27,27 +30,27 @@ NOTE: If you change dependencies here, don't forget to update the jar files in J
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
 | 
			
		||||
    compile 'com.squareup.okhttp3:okhttp:4.10.0-RC1'
 | 
			
		||||
    compile 'com.burgstaller:okhttp-digest:2.5'
 | 
			
		||||
    implementation 'com.squareup.okhttp3:okhttp:4.10.0-RC1'
 | 
			
		||||
    implementation 'com.burgstaller:okhttp-digest:2.5'
 | 
			
		||||
 | 
			
		||||
    compile 'com.google.http-client:google-http-client-gson:1.20.0'
 | 
			
		||||
    compile('com.google.api-client:google-api-client-android:1.30.5') {
 | 
			
		||||
    implementation 'com.google.http-client:google-http-client-gson:1.20.0'
 | 
			
		||||
    implementation('com.google.api-client:google-api-client-android:1.30.5') {
 | 
			
		||||
        exclude group: 'com.google.android.google-play-services'
 | 
			
		||||
    }
 | 
			
		||||
    compile 'com.google.apis:google-api-services-drive:v2-rev102-1.16.0-rc'
 | 
			
		||||
    compile 'com.dropbox.core:dropbox-core-sdk:4.0.0'
 | 
			
		||||
    implementation 'com.google.apis:google-api-services-drive:v2-rev102-1.16.0-rc'
 | 
			
		||||
    implementation 'com.dropbox.core:dropbox-core-sdk:4.0.0'
 | 
			
		||||
    implementation 'com.google.api-client:google-api-client:1.30.5'
 | 
			
		||||
    implementation 'com.google.api-client:google-api-client-android:1.30.5'
 | 
			
		||||
 | 
			
		||||
    implementation 'com.google.android.gms:play-services-auth:19.2.0'
 | 
			
		||||
    implementation 'com.google.android.gms:play-services-auth:20.4.0'
 | 
			
		||||
    //onedrive:
 | 
			
		||||
    compile('com.onedrive.sdk:onedrive-sdk-android:1.2.0') {
 | 
			
		||||
    implementation('com.onedrive.sdk:onedrive-sdk-android:1.2.0') {
 | 
			
		||||
        transitive = false
 | 
			
		||||
    }
 | 
			
		||||
    compile 'com.pcloud.sdk:java-core:1.2.0'
 | 
			
		||||
    compile 'com.pcloud.sdk:android:1.2.0'
 | 
			
		||||
    compile 'com.google.code.gson:gson:2.8.6'
 | 
			
		||||
    compile 'com.microsoft.services.msa:msa-auth:0.8.6'
 | 
			
		||||
    compile 'com.microsoft.aad:adal:1.14.0'
 | 
			
		||||
    implementation 'com.pcloud.sdk:java-core:1.2.0'
 | 
			
		||||
    implementation 'com.pcloud.sdk:android:1.2.0'
 | 
			
		||||
    implementation 'com.google.code.gson:gson:2.8.6'
 | 
			
		||||
    implementation 'com.microsoft.services.msa:msa-auth:0.8.6'
 | 
			
		||||
    implementation 'com.microsoft.aad:adal:1.14.0'
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,9 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    package="keepass2android.javafilestorage"
 | 
			
		||||
    android:versionCode="1"
 | 
			
		||||
    android:versionName="1.0">
 | 
			
		||||
 | 
			
		||||
    <uses-sdk
 | 
			
		||||
        android:targetSdkVersion="14" />
 | 
			
		||||
 | 
			
		||||
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
public interface AgentConnector {
 | 
			
		||||
  String getName();
 | 
			
		||||
  boolean isAvailable();
 | 
			
		||||
  void query(Buffer buffer) throws AgentProxyException;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,80 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class AgentIdentity implements Identity {
 | 
			
		||||
 | 
			
		||||
  private AgentProxy agent;
 | 
			
		||||
  private byte[] blob;
 | 
			
		||||
  private String comment;
 | 
			
		||||
  private String algname;
 | 
			
		||||
  AgentIdentity(AgentProxy agent, byte[] blob, String comment) {
 | 
			
		||||
    this.agent = agent;
 | 
			
		||||
    this.blob = blob;
 | 
			
		||||
    this.comment = comment;
 | 
			
		||||
    algname = Util.byte2str((new Buffer(blob)).getString());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean setPassphrase(byte[] passphrase) throws JSchException{
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public byte[] getPublicKeyBlob() { return blob; }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public byte[] getSignature(byte[] data){
 | 
			
		||||
    return agent.sign(blob, data, null);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public byte[] getSignature(byte[] data, String alg){
 | 
			
		||||
    return agent.sign(blob, data, alg);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  @Deprecated
 | 
			
		||||
  public boolean decrypt() {
 | 
			
		||||
    throw new RuntimeException("not implemented");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getAlgName() { return algname; }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getName() { return comment; }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean isEncrypted() { return false; }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void clear() { }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,75 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
 | 
			
		||||
public class AgentIdentityRepository implements IdentityRepository {
 | 
			
		||||
 | 
			
		||||
  private AgentProxy agent;
 | 
			
		||||
  public AgentIdentityRepository(AgentConnector connector) {
 | 
			
		||||
    this.agent = new AgentProxy(connector);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public Vector<Identity> getIdentities() {
 | 
			
		||||
    return agent.getIdentities();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean add(byte[] identity) {
 | 
			
		||||
    return agent.addIdentity(identity);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean remove(byte[] blob) {
 | 
			
		||||
    return agent.removeIdentity(blob);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void removeAll() {
 | 
			
		||||
    agent.removeAllIdentities();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public String getName() {
 | 
			
		||||
    return agent.getConnector().getName();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int getStatus() {
 | 
			
		||||
    if(agent.getConnector().isAvailable()){
 | 
			
		||||
      return RUNNING;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      return NOTRUNNING;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,256 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2012 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
 | 
			
		||||
class AgentProxy {
 | 
			
		||||
 | 
			
		||||
  private static final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1;
 | 
			
		||||
  private static final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2;
 | 
			
		||||
  private static final byte SSH_AGENTC_RSA_CHALLENGE = 3;
 | 
			
		||||
  private static final byte SSH_AGENT_RSA_RESPONSE = 4;
 | 
			
		||||
  private static final byte SSH_AGENT_FAILURE = 5;
 | 
			
		||||
  private static final byte SSH_AGENT_SUCCESS = 6;
 | 
			
		||||
  private static final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7;
 | 
			
		||||
  private static final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8;
 | 
			
		||||
  private static final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9;
 | 
			
		||||
 | 
			
		||||
  private static final byte SSH2_AGENTC_REQUEST_IDENTITIES = 11;
 | 
			
		||||
  private static final byte SSH2_AGENT_IDENTITIES_ANSWER = 12;
 | 
			
		||||
  private static final byte SSH2_AGENTC_SIGN_REQUEST = 13;
 | 
			
		||||
  private static final byte SSH2_AGENT_SIGN_RESPONSE = 14;
 | 
			
		||||
  private static final byte SSH2_AGENTC_ADD_IDENTITY = 17;
 | 
			
		||||
  private static final byte SSH2_AGENTC_REMOVE_IDENTITY = 18;
 | 
			
		||||
  private static final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES = 19;
 | 
			
		||||
 | 
			
		||||
  private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY = 20;
 | 
			
		||||
  private static final byte SSH_AGENTC_REMOVE_SMARTCARD_KEY = 21;
 | 
			
		||||
 | 
			
		||||
  private static final byte SSH_AGENTC_LOCK = 22;
 | 
			
		||||
  private static final byte SSH_AGENTC_UNLOCK = 23;
 | 
			
		||||
 | 
			
		||||
  private static final byte SSH_AGENTC_ADD_RSA_ID_CONSTRAINED = 24;
 | 
			
		||||
  private static final byte SSH2_AGENTC_ADD_ID_CONSTRAINED = 25;
 | 
			
		||||
  private static final byte SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED = 26;
 | 
			
		||||
 | 
			
		||||
  private static final byte SSH_AGENT_CONSTRAIN_LIFETIME = 1;
 | 
			
		||||
  private static final byte SSH_AGENT_CONSTRAIN_CONFIRM = 2;
 | 
			
		||||
 | 
			
		||||
  private static final byte SSH2_AGENT_FAILURE = 30;
 | 
			
		||||
 | 
			
		||||
  private static final byte SSH_COM_AGENT2_FAILURE = 102;
 | 
			
		||||
 | 
			
		||||
  //private static final byte SSH_AGENT_OLD_SIGNATURE = 0x1;
 | 
			
		||||
  private static final int SSH_AGENT_RSA_SHA2_256 = 0x2;
 | 
			
		||||
  private static final int SSH_AGENT_RSA_SHA2_512 = 0x4;
 | 
			
		||||
 | 
			
		||||
  private static final int MAX_AGENT_IDENTITIES = 2048;
 | 
			
		||||
 | 
			
		||||
  private final byte[] buf = new byte[1024];
 | 
			
		||||
  private final Buffer buffer = new Buffer(buf);
 | 
			
		||||
 | 
			
		||||
  private AgentConnector connector;
 | 
			
		||||
 | 
			
		||||
  AgentProxy(AgentConnector connector){
 | 
			
		||||
    this.connector = connector;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  synchronized Vector<Identity> getIdentities() {
 | 
			
		||||
    Vector<Identity> identities = new Vector<>();
 | 
			
		||||
 | 
			
		||||
    int required_size = 1 + 4;
 | 
			
		||||
    buffer.reset();
 | 
			
		||||
    buffer.checkFreeSize(required_size);
 | 
			
		||||
    buffer.putInt(required_size - 4);
 | 
			
		||||
    buffer.putByte(SSH2_AGENTC_REQUEST_IDENTITIES);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      connector.query(buffer);
 | 
			
		||||
    }
 | 
			
		||||
    catch(AgentProxyException e){
 | 
			
		||||
      buffer.rewind();
 | 
			
		||||
      buffer.putByte(SSH_AGENT_FAILURE);
 | 
			
		||||
      return identities;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int rcode = buffer.getByte();
 | 
			
		||||
 | 
			
		||||
    //System.out.println(rcode == SSH2_AGENT_IDENTITIES_ANSWER);
 | 
			
		||||
 | 
			
		||||
    if(rcode != SSH2_AGENT_IDENTITIES_ANSWER) {
 | 
			
		||||
      return identities;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int count = buffer.getInt();
 | 
			
		||||
    //System.out.println(count);
 | 
			
		||||
    if(count <= 0 || count > MAX_AGENT_IDENTITIES) {
 | 
			
		||||
      return identities;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(int i=0; i<count; i++){
 | 
			
		||||
      byte[] blob = buffer.getString();
 | 
			
		||||
      String comment = Util.byte2str(buffer.getString());
 | 
			
		||||
      identities.add(new AgentIdentity(this, blob, comment));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return identities;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  synchronized byte[] sign(byte[] blob, byte[] data, String alg) {
 | 
			
		||||
    int flags = 0x0;
 | 
			
		||||
    if(alg != null) {
 | 
			
		||||
      if(alg.equals("rsa-sha2-256")) {
 | 
			
		||||
        flags = SSH_AGENT_RSA_SHA2_256;
 | 
			
		||||
      }
 | 
			
		||||
      else if(alg.equals("rsa-sha2-512")) {
 | 
			
		||||
        flags = SSH_AGENT_RSA_SHA2_512;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int required_size = 1 + 4*4 + blob.length + data.length;
 | 
			
		||||
    buffer.reset();
 | 
			
		||||
    buffer.checkFreeSize(required_size);
 | 
			
		||||
    buffer.putInt(required_size - 4);
 | 
			
		||||
    buffer.putByte(SSH2_AGENTC_SIGN_REQUEST);
 | 
			
		||||
    buffer.putString(blob);
 | 
			
		||||
    buffer.putString(data);
 | 
			
		||||
    buffer.putInt(flags);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      connector.query(buffer);
 | 
			
		||||
    }
 | 
			
		||||
    catch(AgentProxyException e){
 | 
			
		||||
      buffer.rewind();
 | 
			
		||||
      buffer.putByte(SSH_AGENT_FAILURE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int rcode = buffer.getByte();
 | 
			
		||||
 | 
			
		||||
    //System.out.println(rcode == SSH2_AGENT_SIGN_RESPONSE);
 | 
			
		||||
 | 
			
		||||
    if(rcode != SSH2_AGENT_SIGN_RESPONSE) {
 | 
			
		||||
      return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return buffer.getString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  synchronized boolean removeIdentity(byte[] blob) {
 | 
			
		||||
    int required_size = 1 + 4*2 + blob.length;
 | 
			
		||||
    buffer.reset();
 | 
			
		||||
    buffer.checkFreeSize(required_size);
 | 
			
		||||
    buffer.putInt(required_size - 4);
 | 
			
		||||
    buffer.putByte(SSH2_AGENTC_REMOVE_IDENTITY);
 | 
			
		||||
    buffer.putString(blob);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      connector.query(buffer);
 | 
			
		||||
    }
 | 
			
		||||
    catch(AgentProxyException e){
 | 
			
		||||
      buffer.rewind();
 | 
			
		||||
      buffer.putByte(SSH_AGENT_FAILURE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int rcode = buffer.getByte();
 | 
			
		||||
 | 
			
		||||
    //System.out.println(rcode == SSH_AGENT_SUCCESS);
 | 
			
		||||
 | 
			
		||||
    return rcode == SSH_AGENT_SUCCESS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  synchronized void removeAllIdentities() {
 | 
			
		||||
    int required_size = 1 + 4;
 | 
			
		||||
    buffer.reset();
 | 
			
		||||
    buffer.checkFreeSize(required_size);
 | 
			
		||||
    buffer.putInt(required_size - 4);
 | 
			
		||||
    buffer.putByte(SSH2_AGENTC_REMOVE_ALL_IDENTITIES);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      connector.query(buffer);
 | 
			
		||||
    }
 | 
			
		||||
    catch(AgentProxyException e){
 | 
			
		||||
      buffer.rewind();
 | 
			
		||||
      buffer.putByte(SSH_AGENT_FAILURE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //int rcode = buffer.getByte();
 | 
			
		||||
 | 
			
		||||
    //System.out.println(rcode == SSH_AGENT_SUCCESS);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  synchronized boolean addIdentity(byte[] identity) {
 | 
			
		||||
    int required_size = 1 + 4 + identity.length;
 | 
			
		||||
    buffer.reset();
 | 
			
		||||
    buffer.checkFreeSize(required_size);
 | 
			
		||||
    buffer.putInt(required_size - 4);
 | 
			
		||||
    buffer.putByte(SSH2_AGENTC_ADD_IDENTITY);
 | 
			
		||||
    buffer.putByte(identity);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      connector.query(buffer);
 | 
			
		||||
    }
 | 
			
		||||
    catch(AgentProxyException e){
 | 
			
		||||
      buffer.rewind();
 | 
			
		||||
      buffer.putByte(SSH_AGENT_FAILURE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int rcode = buffer.getByte();
 | 
			
		||||
 | 
			
		||||
    //System.out.println(rcode == SSH_AGENT_SUCCESS);
 | 
			
		||||
 | 
			
		||||
    return rcode == SSH_AGENT_SUCCESS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  synchronized boolean isRunning(){
 | 
			
		||||
    int required_size = 1 + 4;
 | 
			
		||||
    buffer.reset();
 | 
			
		||||
    buffer.checkFreeSize(required_size);
 | 
			
		||||
    buffer.putInt(required_size - 4);
 | 
			
		||||
    buffer.putByte(SSH2_AGENTC_REQUEST_IDENTITIES);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      connector.query(buffer);
 | 
			
		||||
    }
 | 
			
		||||
    catch(AgentProxyException e){
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int rcode = buffer.getByte();
 | 
			
		||||
 | 
			
		||||
    //System.out.println(rcode == SSH2_AGENT_IDENTITIES_ANSWER);
 | 
			
		||||
 | 
			
		||||
    return rcode == SSH2_AGENT_IDENTITIES_ANSWER;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  synchronized AgentConnector getConnector() {
 | 
			
		||||
    return connector;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2006-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
Copyright (c) 2011 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
@@ -27,25 +27,14 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch.jcraft;
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
import com.jcraft.jsch.MAC;
 | 
			
		||||
import java.security.*;
 | 
			
		||||
 | 
			
		||||
public class HMACSHA1 extends HMAC implements MAC{
 | 
			
		||||
  private static final String name="hmac-sha1";
 | 
			
		||||
 | 
			
		||||
  public HMACSHA1(){
 | 
			
		||||
    super();
 | 
			
		||||
    MessageDigest md=null;
 | 
			
		||||
    try{ md=MessageDigest.getInstance("SHA-1"); }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      System.err.println(e);
 | 
			
		||||
    }
 | 
			
		||||
    setH(md);
 | 
			
		||||
public class AgentProxyException extends Exception {
 | 
			
		||||
  private static final long serialVersionUID=-1L;
 | 
			
		||||
  public AgentProxyException(String message){
 | 
			
		||||
    super(message);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public String getName(){
 | 
			
		||||
    return name;
 | 
			
		||||
  public AgentProxyException(String message, Throwable e){
 | 
			
		||||
    super(message, e);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -271,15 +271,15 @@ public class Buffer{
 | 
			
		||||
    int foo;
 | 
			
		||||
    for(int i=0; i<tmp_buffer_index; i++){
 | 
			
		||||
        foo=tmp_buffer[i]&0xff;
 | 
			
		||||
	System.err.print(chars[(foo>>>4)&0xf]);
 | 
			
		||||
	System.err.print(chars[foo&0xf]);
 | 
			
		||||
        System.err.print(chars[(foo>>>4)&0xf]);
 | 
			
		||||
        System.err.print(chars[foo&0xf]);
 | 
			
		||||
        if(i%16==15){
 | 
			
		||||
          System.err.println("");
 | 
			
		||||
	  continue;
 | 
			
		||||
	}
 | 
			
		||||
          continue;
 | 
			
		||||
        }
 | 
			
		||||
        if(i>0 && i%2==1){
 | 
			
		||||
          System.err.print(" ");
 | 
			
		||||
	}
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    System.err.println("");
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -29,14 +29,10 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
import java.io.PipedInputStream;
 | 
			
		||||
import java.io.PipedOutputStream;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.io.OutputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public abstract class Channel implements Runnable{
 | 
			
		||||
public abstract class Channel{
 | 
			
		||||
 | 
			
		||||
  static final int SSH_MSG_CHANNEL_OPEN_CONFIRMATION=      91;
 | 
			
		||||
  static final int SSH_MSG_CHANNEL_OPEN_FAILURE=           92;
 | 
			
		||||
@@ -48,41 +44,49 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
  static final int SSH_OPEN_RESOURCE_SHORTAGE=              4;
 | 
			
		||||
 | 
			
		||||
  static int index=0; 
 | 
			
		||||
  private static java.util.Vector pool=new java.util.Vector();
 | 
			
		||||
  static Channel getChannel(String type){
 | 
			
		||||
  private static Vector<Channel> pool=new Vector<>();
 | 
			
		||||
  static Channel getChannel(String type, Session session){
 | 
			
		||||
    Channel ret = null;
 | 
			
		||||
    if(type.equals("session")){
 | 
			
		||||
      return new ChannelSession();
 | 
			
		||||
      ret = new ChannelSession();
 | 
			
		||||
    }
 | 
			
		||||
    if(type.equals("shell")){
 | 
			
		||||
      return new ChannelShell();
 | 
			
		||||
      ret = new ChannelShell();
 | 
			
		||||
    }
 | 
			
		||||
    if(type.equals("exec")){
 | 
			
		||||
      return new ChannelExec();
 | 
			
		||||
      ret = new ChannelExec();
 | 
			
		||||
    }
 | 
			
		||||
    if(type.equals("x11")){
 | 
			
		||||
      return new ChannelX11();
 | 
			
		||||
      ret = new ChannelX11();
 | 
			
		||||
    }
 | 
			
		||||
    if(type.equals("auth-agent@openssh.com")){
 | 
			
		||||
      return new ChannelAgentForwarding();
 | 
			
		||||
      ret = new ChannelAgentForwarding();
 | 
			
		||||
    }
 | 
			
		||||
    if(type.equals("direct-tcpip")){
 | 
			
		||||
      return new ChannelDirectTCPIP();
 | 
			
		||||
      ret = new ChannelDirectTCPIP();
 | 
			
		||||
    }
 | 
			
		||||
    if(type.equals("forwarded-tcpip")){
 | 
			
		||||
      return new ChannelForwardedTCPIP();
 | 
			
		||||
      ret = new ChannelForwardedTCPIP();
 | 
			
		||||
    }
 | 
			
		||||
    if(type.equals("sftp")){
 | 
			
		||||
      return new ChannelSftp();
 | 
			
		||||
      ret = new ChannelSftp();
 | 
			
		||||
    }
 | 
			
		||||
    if(type.equals("subsystem")){
 | 
			
		||||
      return new ChannelSubsystem();
 | 
			
		||||
      ret = new ChannelSubsystem();
 | 
			
		||||
    }
 | 
			
		||||
    return null;
 | 
			
		||||
    if(type.equals("direct-streamlocal@openssh.com")){
 | 
			
		||||
      ret = new ChannelDirectStreamLocal();
 | 
			
		||||
    }
 | 
			
		||||
    if (ret == null) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
    ret.setSession(session);
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
  static Channel getChannel(int id, Session session){
 | 
			
		||||
    synchronized(pool){
 | 
			
		||||
      for(int i=0; i<pool.size(); i++){
 | 
			
		||||
        Channel c=(Channel)(pool.elementAt(i));
 | 
			
		||||
        Channel c=pool.elementAt(i);
 | 
			
		||||
        if(c.id==id && c.session==session) return c;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -119,7 +123,7 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
  volatile int reply=0; 
 | 
			
		||||
  volatile int connectTimeout=0;
 | 
			
		||||
 | 
			
		||||
  private Session session;
 | 
			
		||||
  protected Session session;
 | 
			
		||||
 | 
			
		||||
  int notifyme=0; 
 | 
			
		||||
 | 
			
		||||
@@ -231,7 +235,7 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
        private Buffer buffer=null;
 | 
			
		||||
        private Packet packet=null;
 | 
			
		||||
        private boolean closed=false;
 | 
			
		||||
        private synchronized void init() throws java.io.IOException{
 | 
			
		||||
        private synchronized void init() throws IOException{
 | 
			
		||||
          buffer=new Buffer(rmpsize);
 | 
			
		||||
          packet=new Packet(buffer);
 | 
			
		||||
 | 
			
		||||
@@ -244,17 +248,19 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        byte[] b=new byte[1];
 | 
			
		||||
        public void write(int w) throws java.io.IOException{
 | 
			
		||||
        @Override
 | 
			
		||||
        public void write(int w) throws IOException{
 | 
			
		||||
          b[0]=(byte)w;
 | 
			
		||||
          write(b, 0, 1);
 | 
			
		||||
        }
 | 
			
		||||
        public void write(byte[] buf, int s, int l) throws java.io.IOException{
 | 
			
		||||
        @Override
 | 
			
		||||
        public void write(byte[] buf, int s, int l) throws IOException{
 | 
			
		||||
          if(packet==null){
 | 
			
		||||
            init();
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if(closed){
 | 
			
		||||
            throw new java.io.IOException("Already closed");
 | 
			
		||||
            throw new IOException("Already closed");
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          byte[] _buf=buffer.buffer;
 | 
			
		||||
@@ -277,9 +283,10 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void flush() throws java.io.IOException{
 | 
			
		||||
        @Override
 | 
			
		||||
        public void flush() throws IOException{
 | 
			
		||||
          if(closed){
 | 
			
		||||
            throw new java.io.IOException("Already closed");
 | 
			
		||||
            throw new IOException("Already closed");
 | 
			
		||||
          }
 | 
			
		||||
          if(dataLen==0)
 | 
			
		||||
            return;
 | 
			
		||||
@@ -298,16 +305,17 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
          }
 | 
			
		||||
          catch(Exception e){
 | 
			
		||||
            close();
 | 
			
		||||
            throw new java.io.IOException(e.toString());
 | 
			
		||||
            throw new IOException(e.toString(), e);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        public void close() throws java.io.IOException{
 | 
			
		||||
        @Override
 | 
			
		||||
        public void close() throws IOException{
 | 
			
		||||
          if(packet==null){
 | 
			
		||||
            try{
 | 
			
		||||
              init();
 | 
			
		||||
            }
 | 
			
		||||
            catch(java.io.IOException e){
 | 
			
		||||
            catch(IOException e){
 | 
			
		||||
              // close should be finished silently.
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -325,7 +333,7 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
    return out;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  class MyPipedInputStream extends PipedInputStream{
 | 
			
		||||
  static class MyPipedInputStream extends PipedInputStream{
 | 
			
		||||
    private int BUFFER_SIZE = 1024;
 | 
			
		||||
    private int max_buffer_size = BUFFER_SIZE;
 | 
			
		||||
    MyPipedInputStream() throws IOException{ super(); }
 | 
			
		||||
@@ -427,8 +435,7 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
  }
 | 
			
		||||
  void setRemotePacketSize(int foo){ this.rmpsize=foo; }
 | 
			
		||||
 | 
			
		||||
  public void run(){
 | 
			
		||||
  }
 | 
			
		||||
  abstract void run();
 | 
			
		||||
 | 
			
		||||
  void write(byte[] foo) throws IOException {
 | 
			
		||||
    write(foo, 0, foo.length);
 | 
			
		||||
@@ -546,14 +553,14 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
    synchronized(pool){
 | 
			
		||||
      channels=new Channel[pool.size()];
 | 
			
		||||
      for(int i=0; i<pool.size(); i++){
 | 
			
		||||
	try{
 | 
			
		||||
	  Channel c=((Channel)(pool.elementAt(i)));
 | 
			
		||||
	  if(c.session==session){
 | 
			
		||||
	    channels[count++]=c;
 | 
			
		||||
	  }
 | 
			
		||||
	}
 | 
			
		||||
	catch(Exception e){
 | 
			
		||||
	}
 | 
			
		||||
        try{
 | 
			
		||||
          Channel c=pool.elementAt(i);
 | 
			
		||||
          if(c.session==session){
 | 
			
		||||
            channels[count++]=c;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        catch(Exception e){
 | 
			
		||||
        }
 | 
			
		||||
      } 
 | 
			
		||||
    }
 | 
			
		||||
    for(int i=0; i<count; i++){
 | 
			
		||||
@@ -621,24 +628,25 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
  }
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
  class PassiveInputStream extends MyPipedInputStream{
 | 
			
		||||
    PipedOutputStream out;
 | 
			
		||||
  static class PassiveInputStream extends MyPipedInputStream{
 | 
			
		||||
    PipedOutputStream os;
 | 
			
		||||
    PassiveInputStream(PipedOutputStream out, int size) throws IOException{
 | 
			
		||||
      super(out, size);
 | 
			
		||||
      this.out=out;
 | 
			
		||||
      this.os=out;
 | 
			
		||||
    }
 | 
			
		||||
    PassiveInputStream(PipedOutputStream out) throws IOException{
 | 
			
		||||
      super(out);
 | 
			
		||||
      this.out=out;
 | 
			
		||||
      this.os=out;
 | 
			
		||||
    }
 | 
			
		||||
    @Override
 | 
			
		||||
    public void close() throws IOException{
 | 
			
		||||
      if(out!=null){
 | 
			
		||||
        this.out.close();
 | 
			
		||||
      if(this.os!=null){
 | 
			
		||||
        this.os.close();
 | 
			
		||||
      }
 | 
			
		||||
      out=null;
 | 
			
		||||
      this.os=null;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  class PassiveOutputStream extends PipedOutputStream{
 | 
			
		||||
  static class PassiveOutputStream extends PipedOutputStream{
 | 
			
		||||
    private MyPipedInputStream _sink=null;
 | 
			
		||||
    PassiveOutputStream(PipedInputStream in,
 | 
			
		||||
                        boolean resizable_buffer) throws IOException{
 | 
			
		||||
@@ -647,12 +655,14 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
        this._sink=(MyPipedInputStream)in;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    @Override
 | 
			
		||||
    public void write(int b) throws IOException {
 | 
			
		||||
      if(_sink != null) {
 | 
			
		||||
        _sink.checkSpace(1);
 | 
			
		||||
      }
 | 
			
		||||
      super.write(b);
 | 
			
		||||
    }
 | 
			
		||||
    @Override
 | 
			
		||||
    public void write(byte[] b, int off, int len) throws IOException {
 | 
			
		||||
      if(_sink != null) {
 | 
			
		||||
        _sink.checkSpace(len);
 | 
			
		||||
@@ -678,7 +688,7 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
  public int getId(){ return id; }
 | 
			
		||||
 | 
			
		||||
  protected void sendOpenConfirmation() throws Exception{
 | 
			
		||||
    Buffer buf=new Buffer(100);
 | 
			
		||||
    Buffer buf=new Buffer(200);
 | 
			
		||||
    Packet packet=new Packet(buf);
 | 
			
		||||
    packet.reset();
 | 
			
		||||
    buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
 | 
			
		||||
@@ -691,7 +701,7 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
 | 
			
		||||
  protected void sendOpenFailure(int reasoncode){
 | 
			
		||||
    try{
 | 
			
		||||
      Buffer buf=new Buffer(100);
 | 
			
		||||
      Buffer buf=new Buffer(200);
 | 
			
		||||
      Packet packet=new Packet(buf);
 | 
			
		||||
      packet.reset();
 | 
			
		||||
      buf.putByte((byte)SSH_MSG_CHANNEL_OPEN_FAILURE);
 | 
			
		||||
@@ -706,7 +716,7 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  protected Packet genChannelOpenPacket(){
 | 
			
		||||
    Buffer buf=new Buffer(100);
 | 
			
		||||
    Buffer buf=new Buffer(200);
 | 
			
		||||
    Packet packet=new Packet(buf);
 | 
			
		||||
    // byte   SSH_MSG_CHANNEL_OPEN(90)
 | 
			
		||||
    // string channel type         //
 | 
			
		||||
@@ -750,7 +760,7 @@ public abstract class Channel implements Runnable{
 | 
			
		||||
          this.notifyme=1;
 | 
			
		||||
          wait(t);
 | 
			
		||||
        }
 | 
			
		||||
        catch(java.lang.InterruptedException e){
 | 
			
		||||
        catch(InterruptedException e){
 | 
			
		||||
        }
 | 
			
		||||
        finally{
 | 
			
		||||
          this.notifyme=0;
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.*;
 | 
			
		||||
import java.util.Vector;
 | 
			
		||||
 | 
			
		||||
@@ -37,26 +38,28 @@ class ChannelAgentForwarding extends Channel{
 | 
			
		||||
  static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
 | 
			
		||||
  static private final int LOCAL_MAXIMUM_PACKET_SIZE=0x4000;
 | 
			
		||||
 | 
			
		||||
  private final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1;
 | 
			
		||||
  private final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2;
 | 
			
		||||
  private final byte SSH_AGENTC_RSA_CHALLENGE = 3;
 | 
			
		||||
  private final byte SSH_AGENT_RSA_RESPONSE = 4;
 | 
			
		||||
  private final byte SSH_AGENT_FAILURE = 5;
 | 
			
		||||
  private final byte SSH_AGENT_SUCCESS = 6;
 | 
			
		||||
  private final byte SSH_AGENTC_ADD_RSA_IDENTITY	= 7;
 | 
			
		||||
  private final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8;
 | 
			
		||||
  private final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9;
 | 
			
		||||
  static private final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1;
 | 
			
		||||
  static private final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2;
 | 
			
		||||
  static private final byte SSH_AGENTC_RSA_CHALLENGE = 3;
 | 
			
		||||
  static private final byte SSH_AGENT_RSA_RESPONSE = 4;
 | 
			
		||||
  static private final byte SSH_AGENT_FAILURE = 5;
 | 
			
		||||
  static private final byte SSH_AGENT_SUCCESS = 6;
 | 
			
		||||
  static private final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7;
 | 
			
		||||
  static private final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8;
 | 
			
		||||
  static private final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9;
 | 
			
		||||
 | 
			
		||||
  private final byte SSH2_AGENTC_REQUEST_IDENTITIES=11;
 | 
			
		||||
  private final byte SSH2_AGENT_IDENTITIES_ANSWER=12;
 | 
			
		||||
  private final byte SSH2_AGENTC_SIGN_REQUEST=13;
 | 
			
		||||
  private final byte SSH2_AGENT_SIGN_RESPONSE=14;
 | 
			
		||||
  private final byte SSH2_AGENTC_ADD_IDENTITY=17;
 | 
			
		||||
  private final byte SSH2_AGENTC_REMOVE_IDENTITY=18;
 | 
			
		||||
  private final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES=19;
 | 
			
		||||
  private final byte SSH2_AGENT_FAILURE=30;
 | 
			
		||||
  static private final byte SSH2_AGENTC_REQUEST_IDENTITIES=11;
 | 
			
		||||
  static private final byte SSH2_AGENT_IDENTITIES_ANSWER=12;
 | 
			
		||||
  static private final byte SSH2_AGENTC_SIGN_REQUEST=13;
 | 
			
		||||
  static private final byte SSH2_AGENT_SIGN_RESPONSE=14;
 | 
			
		||||
  static private final byte SSH2_AGENTC_ADD_IDENTITY=17;
 | 
			
		||||
  static private final byte SSH2_AGENTC_REMOVE_IDENTITY=18;
 | 
			
		||||
  static private final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES=19;
 | 
			
		||||
  static private final byte SSH2_AGENT_FAILURE=30;
 | 
			
		||||
 | 
			
		||||
  boolean init=true;
 | 
			
		||||
  //static private final int SSH_AGENT_OLD_SIGNATURE=0x1;
 | 
			
		||||
  static private final int SSH_AGENT_RSA_SHA2_256=0x2;
 | 
			
		||||
  static private final int SSH_AGENT_RSA_SHA2_512=0x4;
 | 
			
		||||
 | 
			
		||||
  private Buffer rbuf=null;
 | 
			
		||||
  private Buffer wbuf=null;
 | 
			
		||||
@@ -79,7 +82,8 @@ class ChannelAgentForwarding extends Channel{
 | 
			
		||||
    connected=true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void run(){
 | 
			
		||||
  @Override
 | 
			
		||||
  void run(){
 | 
			
		||||
    try{
 | 
			
		||||
      sendOpenConfirmation();
 | 
			
		||||
    }
 | 
			
		||||
@@ -89,7 +93,8 @@ class ChannelAgentForwarding extends Channel{
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void write(byte[] foo, int s, int l) throws java.io.IOException {
 | 
			
		||||
  @Override
 | 
			
		||||
  void write(byte[] foo, int s, int l) throws IOException {
 | 
			
		||||
 | 
			
		||||
    if(packet==null){
 | 
			
		||||
      wbuf=new Buffer(rmpsize);
 | 
			
		||||
@@ -118,7 +123,7 @@ class ChannelAgentForwarding extends Channel{
 | 
			
		||||
      _session=getSession();
 | 
			
		||||
    }
 | 
			
		||||
    catch(JSchException e){
 | 
			
		||||
      throw new java.io.IOException(e.toString());
 | 
			
		||||
      throw new IOException(e.toString(), e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    IdentityRepository irepo = _session.getIdentityRepository();
 | 
			
		||||
@@ -128,17 +133,17 @@ class ChannelAgentForwarding extends Channel{
 | 
			
		||||
 | 
			
		||||
    if(typ==SSH2_AGENTC_REQUEST_IDENTITIES){ 
 | 
			
		||||
      mbuf.putByte(SSH2_AGENT_IDENTITIES_ANSWER);
 | 
			
		||||
      Vector identities = irepo.getIdentities();
 | 
			
		||||
      Vector<Identity> identities = irepo.getIdentities();
 | 
			
		||||
      synchronized(identities){
 | 
			
		||||
        int count=0;
 | 
			
		||||
        for(int i=0; i<identities.size(); i++){
 | 
			
		||||
          Identity identity=(Identity)(identities.elementAt(i));
 | 
			
		||||
          Identity identity=identities.elementAt(i);
 | 
			
		||||
          if(identity.getPublicKeyBlob()!=null)
 | 
			
		||||
            count++;
 | 
			
		||||
        }
 | 
			
		||||
        mbuf.putInt(count);
 | 
			
		||||
        for(int i=0; i<identities.size(); i++){
 | 
			
		||||
          Identity identity=(Identity)(identities.elementAt(i));
 | 
			
		||||
          Identity identity=identities.elementAt(i);
 | 
			
		||||
          byte[] pubkeyblob=identity.getPublicKeyBlob();
 | 
			
		||||
          if(pubkeyblob==null)
 | 
			
		||||
            continue;
 | 
			
		||||
@@ -156,15 +161,15 @@ class ChannelAgentForwarding extends Channel{
 | 
			
		||||
      byte[] data=rbuf.getString();
 | 
			
		||||
      int flags=rbuf.getInt();
 | 
			
		||||
 | 
			
		||||
//      if((flags & 1)!=0){ //SSH_AGENT_OLD_SIGNATURE // old OpenSSH 2.0, 2.1
 | 
			
		||||
//      if((flags & SSH_AGENT_OLD_SIGNATURE)!=0){ // old OpenSSH 2.0, 2.1
 | 
			
		||||
//        datafellows = SSH_BUG_SIGBLOB;
 | 
			
		||||
//      }
 | 
			
		||||
 | 
			
		||||
      Vector identities = irepo.getIdentities();
 | 
			
		||||
      Vector<Identity> identities = irepo.getIdentities();
 | 
			
		||||
      Identity identity = null;
 | 
			
		||||
      synchronized(identities){
 | 
			
		||||
        for(int i=0; i<identities.size(); i++){
 | 
			
		||||
          Identity _identity=(Identity)(identities.elementAt(i));
 | 
			
		||||
          Identity _identity=identities.elementAt(i);
 | 
			
		||||
          if(_identity.getPublicKeyBlob()==null)
 | 
			
		||||
            continue;
 | 
			
		||||
          if(!Util.array_equals(blob, _identity.getPublicKeyBlob())){
 | 
			
		||||
@@ -205,7 +210,22 @@ class ChannelAgentForwarding extends Channel{
 | 
			
		||||
      byte[] signature=null;
 | 
			
		||||
 | 
			
		||||
      if(identity!=null){
 | 
			
		||||
        signature=identity.getSignature(data);
 | 
			
		||||
        Buffer kbuf=new Buffer(blob);
 | 
			
		||||
        String keytype=Util.byte2str(kbuf.getString());
 | 
			
		||||
        if(keytype.equals("ssh-rsa")){
 | 
			
		||||
          if((flags & SSH_AGENT_RSA_SHA2_256)!=0){
 | 
			
		||||
            signature=identity.getSignature(data, "rsa-sha2-256");
 | 
			
		||||
          }
 | 
			
		||||
          else if((flags & SSH_AGENT_RSA_SHA2_512)!=0){
 | 
			
		||||
            signature=identity.getSignature(data, "rsa-sha2-512");
 | 
			
		||||
          }
 | 
			
		||||
          else{
 | 
			
		||||
            signature=identity.getSignature(data, "ssh-rsa");
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        else{
 | 
			
		||||
          signature=identity.getSignature(data);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if(signature==null){
 | 
			
		||||
@@ -259,6 +279,7 @@ class ChannelAgentForwarding extends Channel{
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  void eof_remote(){
 | 
			
		||||
    super.eof_remote();
 | 
			
		||||
    eof();
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,71 @@
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
import static com.jcraft.jsch.Session.SSH_MSG_CHANNEL_OPEN;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extension of {@link ChannelDirectTCPIP} to support socket forwarding.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * https://raw.githubusercontent.com/openssh/openssh-portable/master/PROTOCOL
 | 
			
		||||
 */
 | 
			
		||||
public class ChannelDirectStreamLocal extends ChannelDirectTCPIP {
 | 
			
		||||
 | 
			
		||||
    static private final int LOCAL_WINDOW_SIZE_MAX = 0x20000;
 | 
			
		||||
    static private final int LOCAL_MAXIMUM_PACKET_SIZE = 0x4000;
 | 
			
		||||
    static private final byte[] _type = Util.str2byte("direct-streamlocal@openssh.com");
 | 
			
		||||
 | 
			
		||||
    private String socketPath;
 | 
			
		||||
 | 
			
		||||
    ChannelDirectStreamLocal() {
 | 
			
		||||
        super();
 | 
			
		||||
        type = _type;
 | 
			
		||||
        setLocalWindowSizeMax(LOCAL_WINDOW_SIZE_MAX);
 | 
			
		||||
        setLocalWindowSize(LOCAL_WINDOW_SIZE_MAX);
 | 
			
		||||
        setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected Packet genChannelOpenPacket() {
 | 
			
		||||
 | 
			
		||||
        if (socketPath == null) {
 | 
			
		||||
            session.getLogger().log(Logger.FATAL, "socketPath must be set");
 | 
			
		||||
            throw new RuntimeException("socketPath must be set");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
        Similar to direct-tcpip, direct-streamlocal is sent by the client
 | 
			
		||||
        to request that the server make a connection to a Unix domain socket.
 | 
			
		||||
 | 
			
		||||
            byte      SSH_MSG_CHANNEL_OPEN
 | 
			
		||||
            string    "direct-streamlocal@openssh.com"
 | 
			
		||||
            uint32    sender channel
 | 
			
		||||
            uint32    initial window size
 | 
			
		||||
            uint32    maximum packet size
 | 
			
		||||
            string    socket path
 | 
			
		||||
            string    reserved
 | 
			
		||||
            uint32    reserved
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        Buffer buf = new Buffer(50 +
 | 
			
		||||
                socketPath.length() +
 | 
			
		||||
                Session.buffer_margin);
 | 
			
		||||
        Packet packet = new Packet(buf);
 | 
			
		||||
        packet.reset();
 | 
			
		||||
        buf.putByte((byte) SSH_MSG_CHANNEL_OPEN);
 | 
			
		||||
        buf.putString(this.type);
 | 
			
		||||
        buf.putInt(id);
 | 
			
		||||
        buf.putInt(lwsize);
 | 
			
		||||
        buf.putInt(lmpsize);
 | 
			
		||||
        buf.putString(Util.str2byte(socketPath));
 | 
			
		||||
        buf.putString(Util.str2byte(originator_IP_address));
 | 
			
		||||
        buf.putInt(originator_port);
 | 
			
		||||
        return packet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getSocketPath() {
 | 
			
		||||
        return socketPath;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setSocketPath(String socketPath) {
 | 
			
		||||
        this.socketPath = socketPath;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -50,10 +50,12 @@ public class ChannelDirectTCPIP extends Channel{
 | 
			
		||||
    setLocalPacketSize(LOCAL_MAXIMUM_PACKET_SIZE);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  void init (){
 | 
			
		||||
    io=new IO();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void connect(int connectTimeout) throws JSchException{
 | 
			
		||||
    this.connectTimeout=connectTimeout;
 | 
			
		||||
    try{
 | 
			
		||||
@@ -63,7 +65,7 @@ public class ChannelDirectTCPIP extends Channel{
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if(io.in!=null){
 | 
			
		||||
        thread=new Thread(this);
 | 
			
		||||
        thread=new Thread(this::run);
 | 
			
		||||
        thread.setName("DirectTCPIP thread "+_session.getHost());
 | 
			
		||||
        if(_session.daemon_thread){
 | 
			
		||||
          thread.setDaemon(_session.daemon_thread);
 | 
			
		||||
@@ -84,7 +86,8 @@ public class ChannelDirectTCPIP extends Channel{
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void run(){
 | 
			
		||||
  @Override
 | 
			
		||||
  void run(){
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      sendChannelOpen();
 | 
			
		||||
@@ -133,9 +136,11 @@ public class ChannelDirectTCPIP extends Channel{
 | 
			
		||||
    disconnect();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void setInputStream(InputStream in){
 | 
			
		||||
    io.setInputStream(in);
 | 
			
		||||
  }
 | 
			
		||||
  @Override
 | 
			
		||||
  public void setOutputStream(OutputStream out){
 | 
			
		||||
    io.setOutputStream(out);
 | 
			
		||||
  }
 | 
			
		||||
@@ -145,6 +150,7 @@ public class ChannelDirectTCPIP extends Channel{
 | 
			
		||||
  public void setOrgIPAddress(String foo){this.originator_IP_address=foo;}
 | 
			
		||||
  public void setOrgPort(int foo){this.originator_port=foo;}
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  protected Packet genChannelOpenPacket(){
 | 
			
		||||
    Buffer buf = new Buffer(50 + // 6 + 4*8 + 12
 | 
			
		||||
                            host.length() + originator_IP_address.length() +
 | 
			
		||||
 
 | 
			
		||||
@@ -29,12 +29,14 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
public class ChannelExec extends ChannelSession{
 | 
			
		||||
 | 
			
		||||
  byte[] command=new byte[0];
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void start() throws JSchException{
 | 
			
		||||
    Session _session=getSession();
 | 
			
		||||
    try{
 | 
			
		||||
@@ -44,13 +46,11 @@ public class ChannelExec extends ChannelSession{
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      if(e instanceof JSchException) throw (JSchException)e;
 | 
			
		||||
      if(e instanceof Throwable)
 | 
			
		||||
        throw new JSchException("ChannelExec", (Throwable)e);
 | 
			
		||||
      throw new JSchException("ChannelExec");
 | 
			
		||||
      throw new JSchException("ChannelExec", e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(io.in!=null){
 | 
			
		||||
      thread=new Thread(this);
 | 
			
		||||
      thread=new Thread(this::run);
 | 
			
		||||
      thread.setName("Exec thread "+_session.getHost());
 | 
			
		||||
      if(_session.daemon_thread){
 | 
			
		||||
        thread.setDaemon(_session.daemon_thread);
 | 
			
		||||
@@ -66,18 +66,19 @@ public class ChannelExec extends ChannelSession{
 | 
			
		||||
    this.command=command;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  void init() throws JSchException {
 | 
			
		||||
    io.setInputStream(getSession().in);
 | 
			
		||||
    io.setOutputStream(getSession().out);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void setErrStream(java.io.OutputStream out){
 | 
			
		||||
  public void setErrStream(OutputStream out){
 | 
			
		||||
    setExtOutputStream(out);
 | 
			
		||||
  }
 | 
			
		||||
  public void setErrStream(java.io.OutputStream out, boolean dontclose){
 | 
			
		||||
  public void setErrStream(OutputStream out, boolean dontclose){
 | 
			
		||||
    setExtOutputStream(out, dontclose);
 | 
			
		||||
  }
 | 
			
		||||
  public java.io.InputStream getErrStream() throws java.io.IOException {
 | 
			
		||||
  public InputStream getErrStream() throws IOException {
 | 
			
		||||
    return getExtInputStream();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,7 @@ import java.util.Vector;
 | 
			
		||||
 | 
			
		||||
public class ChannelForwardedTCPIP extends Channel{
 | 
			
		||||
 | 
			
		||||
  private static Vector pool = new Vector();
 | 
			
		||||
  private static Vector<Config> pool = new Vector<>();
 | 
			
		||||
 | 
			
		||||
  static private final int LOCAL_WINDOW_SIZE_MAX=0x20000;
 | 
			
		||||
//static private final int LOCAL_WINDOW_SIZE_MAX=0x100000;
 | 
			
		||||
@@ -56,12 +56,13 @@ public class ChannelForwardedTCPIP extends Channel{
 | 
			
		||||
    connected=true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void run(){
 | 
			
		||||
    try{ 
 | 
			
		||||
      if(config instanceof ConfigDaemon){
 | 
			
		||||
        ConfigDaemon _config = (ConfigDaemon)config;
 | 
			
		||||
        Class c=Class.forName(_config.target);
 | 
			
		||||
        daemon=(ForwardedTCPIPDaemon)c.newInstance();
 | 
			
		||||
        Class<? extends ForwardedTCPIPDaemon> c=Class.forName(_config.target).asSubclass(ForwardedTCPIPDaemon.class);
 | 
			
		||||
        daemon=c.getDeclaredConstructor().newInstance();
 | 
			
		||||
 | 
			
		||||
        PipedOutputStream out=new PipedOutputStream();
 | 
			
		||||
        io.setInputStream(new PassiveInputStream(out
 | 
			
		||||
@@ -128,6 +129,7 @@ public class ChannelForwardedTCPIP extends Channel{
 | 
			
		||||
    disconnect();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  void getData(Buffer buf){
 | 
			
		||||
    setRecipient(buf.getInt());
 | 
			
		||||
    setRemoteWindowSize(buf.getUInt());
 | 
			
		||||
@@ -157,8 +159,8 @@ public class ChannelForwardedTCPIP extends Channel{
 | 
			
		||||
      this.config = getPort(_session, null, port);
 | 
			
		||||
 | 
			
		||||
    if(this.config == null){
 | 
			
		||||
      if(JSch.getLogger().isEnabled(Logger.ERROR)){
 | 
			
		||||
        JSch.getLogger().log(Logger.ERROR, 
 | 
			
		||||
      if(_session.getLogger().isEnabled(Logger.ERROR)){
 | 
			
		||||
          _session.getLogger().log(Logger.ERROR, 
 | 
			
		||||
                             "ChannelForwardedTCPIP: "+Util.byte2str(addr)+":"+port+" is not registered.");
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
@@ -167,7 +169,7 @@ public class ChannelForwardedTCPIP extends Channel{
 | 
			
		||||
  private static Config getPort(Session session, String address_to_bind, int rport){
 | 
			
		||||
    synchronized(pool){
 | 
			
		||||
      for(int i=0; i<pool.size(); i++){
 | 
			
		||||
        Config bar = (Config)(pool.elementAt(i));
 | 
			
		||||
        Config bar = pool.elementAt(i);
 | 
			
		||||
        if(bar.session != session) continue;
 | 
			
		||||
        if(bar.rport != rport) {
 | 
			
		||||
          if(bar.rport != 0 || bar.allocated_rport != rport)
 | 
			
		||||
@@ -182,19 +184,21 @@ public class ChannelForwardedTCPIP extends Channel{
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static String[] getPortForwarding(Session session){
 | 
			
		||||
    Vector foo = new Vector();
 | 
			
		||||
    Vector<String> foo = new Vector<>();
 | 
			
		||||
    synchronized(pool){
 | 
			
		||||
      for(int i=0; i<pool.size(); i++){
 | 
			
		||||
        Config config = (Config)(pool.elementAt(i));
 | 
			
		||||
        if(config instanceof ConfigDaemon)
 | 
			
		||||
          foo.addElement(config.allocated_rport+":"+config.target+":");
 | 
			
		||||
        else
 | 
			
		||||
          foo.addElement(config.allocated_rport+":"+config.target+":"+((ConfigLHost)config).lport);
 | 
			
		||||
        Config config = pool.elementAt(i);
 | 
			
		||||
        if(config.session==session){
 | 
			
		||||
          if(config instanceof ConfigDaemon)
 | 
			
		||||
            foo.addElement(config.allocated_rport+":"+config.target+":");
 | 
			
		||||
          else
 | 
			
		||||
            foo.addElement(config.allocated_rport+":"+config.target+":"+((ConfigLHost)config).lport);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    String[] bar=new String[foo.size()];
 | 
			
		||||
    for(int i=0; i<foo.size(); i++){
 | 
			
		||||
      bar[i]=(String)(foo.elementAt(i));
 | 
			
		||||
      bar[i]=foo.elementAt(i);
 | 
			
		||||
    }
 | 
			
		||||
    return bar;
 | 
			
		||||
  }
 | 
			
		||||
@@ -269,7 +273,7 @@ public class ChannelForwardedTCPIP extends Channel{
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Buffer buf=new Buffer(100); // ??
 | 
			
		||||
    Buffer buf=new Buffer(200); // ??
 | 
			
		||||
    Packet packet=new Packet(buf);
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
@@ -287,7 +291,7 @@ public class ChannelForwardedTCPIP extends Channel{
 | 
			
		||||
      session.write(packet);
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
//    throw new JSchException(e.toString());
 | 
			
		||||
//    throw new JSchException(e.toString(), e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  static void delPort(Session session){
 | 
			
		||||
@@ -296,7 +300,7 @@ public class ChannelForwardedTCPIP extends Channel{
 | 
			
		||||
    synchronized(pool){
 | 
			
		||||
      rport=new int[pool.size()];
 | 
			
		||||
      for(int i=0; i<pool.size(); i++){
 | 
			
		||||
        Config config = (Config)(pool.elementAt(i));
 | 
			
		||||
        Config config = pool.elementAt(i);
 | 
			
		||||
        if(config.session == session) {
 | 
			
		||||
          rport[count++]=config.rport; // ((Integer)bar[1]).intValue();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@ class ChannelSession extends Channel{
 | 
			
		||||
 | 
			
		||||
  protected boolean agent_forwarding=false;
 | 
			
		||||
  protected boolean xforwading=false;
 | 
			
		||||
  protected Hashtable env=null;
 | 
			
		||||
  protected Hashtable<byte[], byte[]> env=null;
 | 
			
		||||
 | 
			
		||||
  protected boolean pty=false;
 | 
			
		||||
 | 
			
		||||
@@ -68,16 +68,18 @@ class ChannelSession extends Channel{
 | 
			
		||||
   *
 | 
			
		||||
   * @param enable
 | 
			
		||||
   */
 | 
			
		||||
  @Override
 | 
			
		||||
  public void setXForwarding(boolean enable){
 | 
			
		||||
    xforwading=enable; 
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @deprecated Use {@link #setEnv(String, String)} or {@link #setEnv(byte[], byte[])} instead.
 | 
			
		||||
   * @deprecated Use #setEnv(String, String) or #setEnv(byte[], byte[]) instead.
 | 
			
		||||
   * @see #setEnv(String, String)
 | 
			
		||||
   * @see #setEnv(byte[], byte[])
 | 
			
		||||
   */
 | 
			
		||||
  public void setEnv(Hashtable env){ 
 | 
			
		||||
  @Deprecated
 | 
			
		||||
  public void setEnv(Hashtable<byte[], byte[]> env){ 
 | 
			
		||||
    synchronized(this){
 | 
			
		||||
      this.env=env; 
 | 
			
		||||
    }
 | 
			
		||||
@@ -111,9 +113,9 @@ class ChannelSession extends Channel{
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private Hashtable getEnv(){
 | 
			
		||||
  private Hashtable<byte[], byte[]> getEnv(){
 | 
			
		||||
    if(env==null)
 | 
			
		||||
      env=new Hashtable();
 | 
			
		||||
      env=new Hashtable<>();
 | 
			
		||||
    return env;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -213,9 +215,9 @@ class ChannelSession extends Channel{
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(env!=null){
 | 
			
		||||
      for(Enumeration _env=env.keys(); _env.hasMoreElements();){
 | 
			
		||||
        Object name=_env.nextElement();
 | 
			
		||||
        Object value=env.get(name);
 | 
			
		||||
      for(Enumeration<byte[]> _env=env.keys(); _env.hasMoreElements();){
 | 
			
		||||
        byte[] name=_env.nextElement();
 | 
			
		||||
        byte[] value=env.get(name);
 | 
			
		||||
        request=new RequestEnv();
 | 
			
		||||
        ((RequestEnv)request).setEnv(toByteArray(name), 
 | 
			
		||||
                                     toByteArray(value));
 | 
			
		||||
@@ -231,7 +233,8 @@ class ChannelSession extends Channel{
 | 
			
		||||
    return (byte[])o;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void run(){
 | 
			
		||||
  @Override
 | 
			
		||||
  void run(){
 | 
			
		||||
    //System.err.println(this+":run >");
 | 
			
		||||
 | 
			
		||||
    Buffer buf=new Buffer(rmpsize);
 | 
			
		||||
@@ -239,27 +242,27 @@ class ChannelSession extends Channel{
 | 
			
		||||
    int i=-1;
 | 
			
		||||
    try{
 | 
			
		||||
      while(isConnected() &&
 | 
			
		||||
	    thread!=null && 
 | 
			
		||||
            thread!=null && 
 | 
			
		||||
            io!=null && 
 | 
			
		||||
            io.in!=null){
 | 
			
		||||
        i=io.in.read(buf.buffer, 
 | 
			
		||||
                     14,    
 | 
			
		||||
                     buf.buffer.length-14
 | 
			
		||||
                     -Session.buffer_margin
 | 
			
		||||
		     );
 | 
			
		||||
	if(i==0)continue;
 | 
			
		||||
	if(i==-1){
 | 
			
		||||
	  eof();
 | 
			
		||||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
	if(close)break;
 | 
			
		||||
                     );
 | 
			
		||||
        if(i==0)continue;
 | 
			
		||||
        if(i==-1){
 | 
			
		||||
          eof();
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
        if(close)break;
 | 
			
		||||
        //System.out.println("write: "+i);
 | 
			
		||||
        packet.reset();
 | 
			
		||||
        buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
 | 
			
		||||
        buf.putInt(recipient);
 | 
			
		||||
        buf.putInt(i);
 | 
			
		||||
        buf.skip(i);
 | 
			
		||||
	getSession().write(packet, this, i);
 | 
			
		||||
        getSession().write(packet, this, i);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -38,6 +38,7 @@ public class ChannelShell extends ChannelSession{
 | 
			
		||||
    pty=true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void start() throws JSchException{
 | 
			
		||||
    Session _session=getSession();
 | 
			
		||||
    try{
 | 
			
		||||
@@ -48,13 +49,11 @@ public class ChannelShell extends ChannelSession{
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      if(e instanceof JSchException) throw (JSchException)e;
 | 
			
		||||
      if(e instanceof Throwable)
 | 
			
		||||
        throw new JSchException("ChannelShell", (Throwable)e);
 | 
			
		||||
      throw new JSchException("ChannelShell");
 | 
			
		||||
      throw new JSchException("ChannelShell", e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(io.in!=null){
 | 
			
		||||
      thread=new Thread(this);
 | 
			
		||||
      thread=new Thread(this::run);
 | 
			
		||||
      thread.setName("Shell for "+_session.host);
 | 
			
		||||
      if(_session.daemon_thread){
 | 
			
		||||
        thread.setDaemon(_session.daemon_thread);
 | 
			
		||||
@@ -63,6 +62,7 @@ public class ChannelShell extends ChannelSession{
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  void init() throws JSchException {
 | 
			
		||||
    io.setInputStream(getSession().in);
 | 
			
		||||
    io.setOutputStream(getSession().out);
 | 
			
		||||
 
 | 
			
		||||
@@ -29,15 +29,14 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
import java.io.*;
 | 
			
		||||
 | 
			
		||||
public class ChannelSubsystem extends ChannelSession{
 | 
			
		||||
  boolean xforwading=false;
 | 
			
		||||
  boolean pty=false;
 | 
			
		||||
  boolean want_reply=true;
 | 
			
		||||
  String subsystem="";
 | 
			
		||||
  public void setXForwarding(boolean foo){ xforwading=foo; }
 | 
			
		||||
  public void setPty(boolean foo){ pty=foo; }
 | 
			
		||||
  public void setWantReply(boolean foo){ want_reply=foo; }
 | 
			
		||||
  public void setSubsystem(String foo){ subsystem=foo; }
 | 
			
		||||
  @Override
 | 
			
		||||
  public void start() throws JSchException{
 | 
			
		||||
    Session _session=getSession();
 | 
			
		||||
    try{
 | 
			
		||||
@@ -47,20 +46,18 @@ public class ChannelSubsystem extends ChannelSession{
 | 
			
		||||
        request.request(_session, this);
 | 
			
		||||
      }
 | 
			
		||||
      if(pty){
 | 
			
		||||
	request=new RequestPtyReq();
 | 
			
		||||
	request.request(_session, this);
 | 
			
		||||
        request=new RequestPtyReq();
 | 
			
		||||
        request.request(_session, this);
 | 
			
		||||
      }
 | 
			
		||||
      request=new RequestSubsystem();
 | 
			
		||||
      ((RequestSubsystem)request).request(_session, this, subsystem, want_reply);
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      if(e instanceof JSchException){ throw (JSchException)e; }
 | 
			
		||||
      if(e instanceof Throwable)
 | 
			
		||||
        throw new JSchException("ChannelSubsystem", (Throwable)e);
 | 
			
		||||
      throw new JSchException("ChannelSubsystem");
 | 
			
		||||
      throw new JSchException("ChannelSubsystem", e);
 | 
			
		||||
    }
 | 
			
		||||
    if(io.in!=null){
 | 
			
		||||
      thread=new Thread(this);
 | 
			
		||||
      thread=new Thread(this::run);
 | 
			
		||||
      thread.setName("Subsystem for "+_session.host);
 | 
			
		||||
      if(_session.daemon_thread){
 | 
			
		||||
        thread.setDaemon(_session.daemon_thread);
 | 
			
		||||
@@ -69,15 +66,16 @@ public class ChannelSubsystem extends ChannelSession{
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  void init() throws JSchException {
 | 
			
		||||
    io.setInputStream(getSession().in);
 | 
			
		||||
    io.setOutputStream(getSession().out);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void setErrStream(java.io.OutputStream out){
 | 
			
		||||
  public void setErrStream(OutputStream out){
 | 
			
		||||
    setExtOutputStream(out);
 | 
			
		||||
  }
 | 
			
		||||
  public java.io.InputStream getErrStream() throws java.io.IOException {
 | 
			
		||||
  public InputStream getErrStream() throws IOException {
 | 
			
		||||
    return getExtInputStream();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,9 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.net.*;
 | 
			
		||||
import java.util.Hashtable;
 | 
			
		||||
 | 
			
		||||
class ChannelX11 extends Channel{
 | 
			
		||||
 | 
			
		||||
@@ -46,8 +48,8 @@ class ChannelX11 extends Channel{
 | 
			
		||||
  static byte[] cookie=null;
 | 
			
		||||
  private static byte[] cookie_hex=null;
 | 
			
		||||
 | 
			
		||||
  private static java.util.Hashtable faked_cookie_pool=new java.util.Hashtable();
 | 
			
		||||
  private static java.util.Hashtable faked_cookie_hex_pool=new java.util.Hashtable();
 | 
			
		||||
  private static Hashtable<Session, byte[]> faked_cookie_pool=new Hashtable<>();
 | 
			
		||||
  private static Hashtable<Session, byte[]> faked_cookie_hex_pool=new Hashtable<>();
 | 
			
		||||
 | 
			
		||||
  private static byte[] table={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
 | 
			
		||||
                               0x61,0x62,0x63,0x64,0x65,0x66};
 | 
			
		||||
@@ -64,21 +66,21 @@ class ChannelX11 extends Channel{
 | 
			
		||||
    cookie_hex=Util.str2byte(foo); 
 | 
			
		||||
    cookie=new byte[16];
 | 
			
		||||
    for(int i=0; i<16; i++){
 | 
			
		||||
	cookie[i]=(byte)(((revtable(cookie_hex[i*2])<<4)&0xf0) |
 | 
			
		||||
			 ((revtable(cookie_hex[i*2+1]))&0xf));
 | 
			
		||||
        cookie[i]=(byte)(((revtable(cookie_hex[i*2])<<4)&0xf0) |
 | 
			
		||||
                         ((revtable(cookie_hex[i*2+1]))&0xf));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  static void setHost(String foo){ host=foo; }
 | 
			
		||||
  static void setPort(int foo){ port=foo; }
 | 
			
		||||
  static byte[] getFakedCookie(Session session){
 | 
			
		||||
    synchronized(faked_cookie_hex_pool){
 | 
			
		||||
      byte[] foo=(byte[])faked_cookie_hex_pool.get(session);
 | 
			
		||||
      byte[] foo=faked_cookie_hex_pool.get(session);
 | 
			
		||||
      if(foo==null){
 | 
			
		||||
	Random random=Session.random;
 | 
			
		||||
	foo=new byte[16];
 | 
			
		||||
	synchronized(random){
 | 
			
		||||
	  random.fill(foo, 0, 16);
 | 
			
		||||
	}
 | 
			
		||||
        Random random=Session.random;
 | 
			
		||||
        foo=new byte[16];
 | 
			
		||||
        synchronized(random){
 | 
			
		||||
          random.fill(foo, 0, 16);
 | 
			
		||||
        }
 | 
			
		||||
/*
 | 
			
		||||
System.err.print("faked_cookie: ");
 | 
			
		||||
for(int i=0; i<foo.length; i++){
 | 
			
		||||
@@ -86,14 +88,14 @@ for(int i=0; i<foo.length; i++){
 | 
			
		||||
}
 | 
			
		||||
System.err.println("");
 | 
			
		||||
*/
 | 
			
		||||
	faked_cookie_pool.put(session, foo);
 | 
			
		||||
	byte[] bar=new byte[32];
 | 
			
		||||
	for(int i=0; i<16; i++){
 | 
			
		||||
	  bar[2*i]=table[(foo[i]>>>4)&0xf];
 | 
			
		||||
	  bar[2*i+1]=table[(foo[i])&0xf];
 | 
			
		||||
	}
 | 
			
		||||
	faked_cookie_hex_pool.put(session, bar);
 | 
			
		||||
	foo=bar;
 | 
			
		||||
        faked_cookie_pool.put(session, foo);
 | 
			
		||||
        byte[] bar=new byte[32];
 | 
			
		||||
        for(int i=0; i<16; i++){
 | 
			
		||||
          bar[2*i]=table[(foo[i]>>>4)&0xf];
 | 
			
		||||
          bar[2*i+1]=table[(foo[i])&0xf];
 | 
			
		||||
        }
 | 
			
		||||
        faked_cookie_hex_pool.put(session, bar);
 | 
			
		||||
        foo=bar;
 | 
			
		||||
      }
 | 
			
		||||
      return foo;
 | 
			
		||||
    }
 | 
			
		||||
@@ -130,7 +132,8 @@ System.err.println("");
 | 
			
		||||
    */
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void run(){
 | 
			
		||||
  @Override
 | 
			
		||||
  void run(){
 | 
			
		||||
 | 
			
		||||
    try{ 
 | 
			
		||||
      socket=Util.createSocket(host, port, TIMEOUT);
 | 
			
		||||
@@ -156,19 +159,19 @@ System.err.println("");
 | 
			
		||||
            io!=null &&
 | 
			
		||||
            io.in!=null){
 | 
			
		||||
        i=io.in.read(buf.buffer, 
 | 
			
		||||
		     14, 
 | 
			
		||||
		     buf.buffer.length-14-Session.buffer_margin);
 | 
			
		||||
	if(i<=0){
 | 
			
		||||
	  eof();
 | 
			
		||||
                     14, 
 | 
			
		||||
                     buf.buffer.length-14-Session.buffer_margin);
 | 
			
		||||
        if(i<=0){
 | 
			
		||||
          eof();
 | 
			
		||||
          break;
 | 
			
		||||
	}
 | 
			
		||||
	if(close)break;
 | 
			
		||||
        }
 | 
			
		||||
        if(close)break;
 | 
			
		||||
        packet.reset();
 | 
			
		||||
        buf.putByte((byte)Session.SSH_MSG_CHANNEL_DATA);
 | 
			
		||||
        buf.putInt(recipient);
 | 
			
		||||
        buf.putInt(i);
 | 
			
		||||
        buf.skip(i);
 | 
			
		||||
	getSession().write(packet, this, i);
 | 
			
		||||
        getSession().write(packet, this, i);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
@@ -187,7 +190,8 @@ System.err.println("");
 | 
			
		||||
    return cache;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void write(byte[] foo, int s, int l) throws java.io.IOException {
 | 
			
		||||
  @Override
 | 
			
		||||
  void write(byte[] foo, int s, int l) throws IOException {
 | 
			
		||||
    //if(eof_local)return;
 | 
			
		||||
 | 
			
		||||
    if(init){
 | 
			
		||||
@@ -197,7 +201,7 @@ System.err.println("");
 | 
			
		||||
        _session=getSession();
 | 
			
		||||
      }
 | 
			
		||||
      catch(JSchException e){
 | 
			
		||||
        throw new java.io.IOException(e.toString());
 | 
			
		||||
        throw new IOException(e.toString(), e);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      foo=addCache(foo, s, l);
 | 
			
		||||
@@ -217,7 +221,7 @@ System.err.println("");
 | 
			
		||||
         dlen=((dlen>>>8)&0xff)|((dlen<<8)&0xff00);
 | 
			
		||||
      }
 | 
			
		||||
      else{
 | 
			
		||||
	  // ??
 | 
			
		||||
          // ??
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if(l<12+plen+((-plen)&3)+dlen)
 | 
			
		||||
@@ -228,7 +232,7 @@ System.err.println("");
 | 
			
		||||
      byte[] faked_cookie=null;
 | 
			
		||||
 | 
			
		||||
      synchronized(faked_cookie_pool){
 | 
			
		||||
	faked_cookie=(byte[])faked_cookie_pool.get(_session);
 | 
			
		||||
        faked_cookie=faked_cookie_pool.get(_session);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /*
 | 
			
		||||
@@ -249,7 +253,7 @@ System.err.println("");
 | 
			
		||||
          System.arraycopy(cookie, 0, foo, s+12+plen+((-plen)&3), dlen);
 | 
			
		||||
      }
 | 
			
		||||
      else{
 | 
			
		||||
	  //System.err.println("wrong cookie");
 | 
			
		||||
          //System.err.println("wrong cookie");
 | 
			
		||||
          thread=null;
 | 
			
		||||
          eof();
 | 
			
		||||
          io.close();
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,13 @@ public interface Cipher{
 | 
			
		||||
  static int DECRYPT_MODE=1;
 | 
			
		||||
  int getIVSize(); 
 | 
			
		||||
  int getBlockSize(); 
 | 
			
		||||
  default int getTagSize() {return 0;}
 | 
			
		||||
  void init(int mode, byte[] key, byte[] iv) throws Exception; 
 | 
			
		||||
  default void update(int foo) throws Exception {}
 | 
			
		||||
  void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception;
 | 
			
		||||
  default void updateAAD(byte[] foo, int s1, int len) throws Exception {}
 | 
			
		||||
  default void doFinal(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception {}
 | 
			
		||||
  boolean isCBC();
 | 
			
		||||
  default boolean isAEAD() {return false;}
 | 
			
		||||
  default boolean isChaCha20() {return false;}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,14 +29,19 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
public class CipherNone implements Cipher{
 | 
			
		||||
class CipherNone implements Cipher{
 | 
			
		||||
  private static final int ivsize=8;
 | 
			
		||||
  private static final int bsize=16;
 | 
			
		||||
  @Override
 | 
			
		||||
  public int getIVSize(){return ivsize;} 
 | 
			
		||||
  @Override
 | 
			
		||||
  public int getBlockSize(){return bsize;}
 | 
			
		||||
  @Override
 | 
			
		||||
  public void init(int mode, byte[] key, byte[] iv) throws Exception{
 | 
			
		||||
  }
 | 
			
		||||
  @Override
 | 
			
		||||
  public void update(byte[] foo, int s1, int len, byte[] bar, int s2) throws Exception{
 | 
			
		||||
  }
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean isCBC(){return false; }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,13 @@ package com.jcraft.jsch;
 | 
			
		||||
public interface Compression{
 | 
			
		||||
  static public final int INFLATER=0;
 | 
			
		||||
  static public final int DEFLATER=1;
 | 
			
		||||
  
 | 
			
		||||
  default void init(int type, int level, Session session) {
 | 
			
		||||
    init(type, level);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  default void end() {}
 | 
			
		||||
 | 
			
		||||
  void init(int type, int level);
 | 
			
		||||
  byte[] compress(byte[] buf, int start, int[] len);
 | 
			
		||||
  byte[] uncompress(byte[] buf, int start, int[] len);
 | 
			
		||||
 
 | 
			
		||||
@@ -42,14 +42,20 @@ public interface ConfigRepository {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static final Config defaultConfig = new Config() {
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getHostname() {return null;}
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getUser() {return null;}
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getPort() {return -1;}
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getValue(String key) {return null;}
 | 
			
		||||
    @Override
 | 
			
		||||
    public String[] getValues(String key) {return null;}
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static final ConfigRepository nullConfig = new ConfigRepository(){
 | 
			
		||||
    @Override
 | 
			
		||||
    public Config getConfig(String host) { return defaultConfig; }
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,38 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DH25519 extends DHXEC {
 | 
			
		||||
  public DH25519(){
 | 
			
		||||
    sha_name="sha-256";
 | 
			
		||||
    curve_name="X25519";
 | 
			
		||||
    key_len=32;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,38 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DH448 extends DHXEC {
 | 
			
		||||
  public DH448(){
 | 
			
		||||
    sha_name="sha-512";
 | 
			
		||||
    curve_name="X448";
 | 
			
		||||
    key_len=56;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
public class DHEC256 extends DHECN {
 | 
			
		||||
class DHEC256 extends DHECN {
 | 
			
		||||
  public DHEC256(){
 | 
			
		||||
    sha_name="sha-256";
 | 
			
		||||
    key_size=256;
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
public class DHEC384 extends DHECN {
 | 
			
		||||
class DHEC384 extends DHECN {
 | 
			
		||||
  public DHEC384(){
 | 
			
		||||
    sha_name="sha-384";
 | 
			
		||||
    key_size=384;
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
public class DHEC521 extends DHECN {
 | 
			
		||||
class DHEC521 extends DHECN {
 | 
			
		||||
  public DHEC521(){
 | 
			
		||||
    sha_name="sha-512";
 | 
			
		||||
    key_size=521;
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
public abstract class DHECN extends KeyExchange{
 | 
			
		||||
abstract class DHECN extends KeyExchange{
 | 
			
		||||
 | 
			
		||||
  private static final int SSH_MSG_KEX_ECDH_INIT =                 30;
 | 
			
		||||
  private static final int SSH_MSG_KEX_ECDH_REPLY=                 31;
 | 
			
		||||
@@ -52,17 +52,17 @@ public abstract class DHECN extends KeyExchange{
 | 
			
		||||
  protected String sha_name; 
 | 
			
		||||
  protected int key_size;
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void init(Session session,
 | 
			
		||||
		   byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
 | 
			
		||||
    this.session=session;
 | 
			
		||||
                   byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
 | 
			
		||||
    this.V_S=V_S;      
 | 
			
		||||
    this.V_C=V_C;      
 | 
			
		||||
    this.I_S=I_S;      
 | 
			
		||||
    this.I_C=I_C;      
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class c=Class.forName(session.getConfig(sha_name));
 | 
			
		||||
      sha=(HASH)(c.newInstance());
 | 
			
		||||
      Class<? extends HASH> c=Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class);
 | 
			
		||||
      sha=c.getDeclaredConstructor().newInstance();
 | 
			
		||||
      sha.init();
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
@@ -76,17 +76,15 @@ public abstract class DHECN extends KeyExchange{
 | 
			
		||||
    buf.putByte((byte)SSH_MSG_KEX_ECDH_INIT);
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class c=Class.forName(session.getConfig("ecdh-sha2-nistp"));
 | 
			
		||||
      ecdh=(ECDH)(c.newInstance());
 | 
			
		||||
      Class<? extends ECDH> c=Class.forName(session.getConfig("ecdh-sha2-nistp")).asSubclass(ECDH.class);
 | 
			
		||||
      ecdh=c.getDeclaredConstructor().newInstance();
 | 
			
		||||
      ecdh.init(key_size);
 | 
			
		||||
 | 
			
		||||
      Q_C = ecdh.getQ();
 | 
			
		||||
      buf.putString(Q_C);
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      if(e instanceof Throwable)
 | 
			
		||||
        throw new JSchException(e.toString(), (Throwable)e);
 | 
			
		||||
      throw new JSchException(e.toString());
 | 
			
		||||
      throw new JSchException(e.toString(), e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(V_S==null){  // This is a really ugly hack for Session.checkKexes ;-(
 | 
			
		||||
@@ -95,16 +93,17 @@ public abstract class DHECN extends KeyExchange{
 | 
			
		||||
 | 
			
		||||
    session.write(packet);
 | 
			
		||||
 | 
			
		||||
    if(JSch.getLogger().isEnabled(Logger.INFO)){
 | 
			
		||||
      JSch.getLogger().log(Logger.INFO, 
 | 
			
		||||
    if(session.getLogger().isEnabled(Logger.INFO)){
 | 
			
		||||
        session.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "SSH_MSG_KEX_ECDH_INIT sent");
 | 
			
		||||
      JSch.getLogger().log(Logger.INFO, 
 | 
			
		||||
        session.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "expecting SSH_MSG_KEX_ECDH_REPLY");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state=SSH_MSG_KEX_ECDH_REPLY;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean next(Buffer _buf) throws Exception{
 | 
			
		||||
    int i,j;
 | 
			
		||||
    switch(state){
 | 
			
		||||
@@ -117,9 +116,9 @@ public abstract class DHECN extends KeyExchange{
 | 
			
		||||
      j=_buf.getInt();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      if(j!=31){
 | 
			
		||||
	System.err.println("type: must be 31 "+j);
 | 
			
		||||
	return false;
 | 
			
		||||
      if(j!=SSH_MSG_KEX_ECDH_REPLY){
 | 
			
		||||
        System.err.println("type: must be SSH_MSG_KEX_ECDH_REPLY "+j);
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      K_S=_buf.getString();
 | 
			
		||||
@@ -135,7 +134,7 @@ public abstract class DHECN extends KeyExchange{
 | 
			
		||||
      //   Section 3.2.2 of [SEC1].  If a key fails validation,
 | 
			
		||||
      //   the key exchange MUST fail.
 | 
			
		||||
      if(!ecdh.validate(r_s[0], r_s[1])){
 | 
			
		||||
	return false;
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      K = ecdh.getSecret(r_s[0], r_s[1]);
 | 
			
		||||
@@ -171,7 +170,7 @@ public abstract class DHECN extends KeyExchange{
 | 
			
		||||
      i=0;
 | 
			
		||||
      j=0;
 | 
			
		||||
      j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 | 
			
		||||
	((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 | 
			
		||||
        ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 | 
			
		||||
      String alg=Util.byte2str(K_S, i, j);
 | 
			
		||||
      i+=j;
 | 
			
		||||
 | 
			
		||||
@@ -183,5 +182,6 @@ public abstract class DHECN extends KeyExchange{
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int getState(){return state; }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
public class DHG1 extends KeyExchange{
 | 
			
		||||
class DHG1 extends DHGN{
 | 
			
		||||
 | 
			
		||||
  static final byte[] g={ 2 };
 | 
			
		||||
  static final byte[] p={
 | 
			
		||||
@@ -52,145 +52,10 @@ public class DHG1 extends KeyExchange{
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  private static final int SSH_MSG_KEXDH_INIT=                     30;
 | 
			
		||||
  private static final int SSH_MSG_KEXDH_REPLY=                    31;
 | 
			
		||||
 | 
			
		||||
  private int state;
 | 
			
		||||
 | 
			
		||||
  DH dh;
 | 
			
		||||
 | 
			
		||||
  byte[] V_S;
 | 
			
		||||
  byte[] V_C;
 | 
			
		||||
  byte[] I_S;
 | 
			
		||||
  byte[] I_C;
 | 
			
		||||
 | 
			
		||||
  byte[] e;
 | 
			
		||||
 | 
			
		||||
  private Buffer buf;
 | 
			
		||||
  private Packet packet;
 | 
			
		||||
 | 
			
		||||
  public void init(Session session,
 | 
			
		||||
		   byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
 | 
			
		||||
    this.session=session;
 | 
			
		||||
    this.V_S=V_S;      
 | 
			
		||||
    this.V_C=V_C;      
 | 
			
		||||
    this.I_S=I_S;      
 | 
			
		||||
    this.I_C=I_C;      
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class c=Class.forName(session.getConfig("sha-1"));
 | 
			
		||||
      sha=(HASH)(c.newInstance());
 | 
			
		||||
      sha.init();
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      System.err.println(e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buf=new Buffer();
 | 
			
		||||
    packet=new Packet(buf);
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class c=Class.forName(session.getConfig("dh"));
 | 
			
		||||
      dh=(DH)(c.newInstance());
 | 
			
		||||
      dh.init();
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      //System.err.println(e);
 | 
			
		||||
      throw e;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dh.setP(p);
 | 
			
		||||
    dh.setG(g);
 | 
			
		||||
 | 
			
		||||
    // The client responds with:
 | 
			
		||||
    // byte  SSH_MSG_KEXDH_INIT(30)
 | 
			
		||||
    // mpint e <- g^x mod p
 | 
			
		||||
    //         x is a random number (1 < x < (p-1)/2)
 | 
			
		||||
 | 
			
		||||
    e=dh.getE();
 | 
			
		||||
 | 
			
		||||
    packet.reset();
 | 
			
		||||
    buf.putByte((byte)SSH_MSG_KEXDH_INIT);
 | 
			
		||||
    buf.putMPInt(e);
 | 
			
		||||
    session.write(packet);
 | 
			
		||||
 | 
			
		||||
    if(JSch.getLogger().isEnabled(Logger.INFO)){
 | 
			
		||||
      JSch.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "SSH_MSG_KEXDH_INIT sent");
 | 
			
		||||
      JSch.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "expecting SSH_MSG_KEXDH_REPLY");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state=SSH_MSG_KEXDH_REPLY;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean next(Buffer _buf) throws Exception{
 | 
			
		||||
    int i,j;
 | 
			
		||||
 | 
			
		||||
    switch(state){
 | 
			
		||||
    case SSH_MSG_KEXDH_REPLY:
 | 
			
		||||
      // The server responds with:
 | 
			
		||||
      // byte      SSH_MSG_KEXDH_REPLY(31)
 | 
			
		||||
      // string    server public host key and certificates (K_S)
 | 
			
		||||
      // mpint     f
 | 
			
		||||
      // string    signature of H
 | 
			
		||||
      j=_buf.getInt();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      if(j!=31){
 | 
			
		||||
	System.err.println("type: must be 31 "+j);
 | 
			
		||||
	return false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      K_S=_buf.getString();
 | 
			
		||||
 | 
			
		||||
      byte[] f=_buf.getMPInt();
 | 
			
		||||
      byte[] sig_of_H=_buf.getString();
 | 
			
		||||
 | 
			
		||||
      dh.setF(f);
 | 
			
		||||
 | 
			
		||||
      dh.checkRange();
 | 
			
		||||
 | 
			
		||||
      K=normalize(dh.getK());
 | 
			
		||||
 | 
			
		||||
      //The hash H is computed as the HASH hash of the concatenation of the
 | 
			
		||||
      //following:
 | 
			
		||||
      // string    V_C, the client's version string (CR and NL excluded)
 | 
			
		||||
      // string    V_S, the server's version string (CR and NL excluded)
 | 
			
		||||
      // string    I_C, the payload of the client's SSH_MSG_KEXINIT
 | 
			
		||||
      // string    I_S, the payload of the server's SSH_MSG_KEXINIT
 | 
			
		||||
      // string    K_S, the host key
 | 
			
		||||
      // mpint     e, exchange value sent by the client
 | 
			
		||||
      // mpint     f, exchange value sent by the server
 | 
			
		||||
      // mpint     K, the shared secret
 | 
			
		||||
      // This value is called the exchange hash, and it is used to authenti-
 | 
			
		||||
      // cate the key exchange.
 | 
			
		||||
      buf.reset();
 | 
			
		||||
      buf.putString(V_C); buf.putString(V_S);
 | 
			
		||||
      buf.putString(I_C); buf.putString(I_S);
 | 
			
		||||
      buf.putString(K_S);
 | 
			
		||||
      buf.putMPInt(e); buf.putMPInt(f);
 | 
			
		||||
      buf.putMPInt(K);
 | 
			
		||||
      byte[] foo=new byte[buf.getLength()];
 | 
			
		||||
      buf.getByte(foo);
 | 
			
		||||
      sha.update(foo, 0, foo.length);
 | 
			
		||||
      H=sha.digest();
 | 
			
		||||
      //System.err.print("H -> "); //dump(H, 0, H.length);
 | 
			
		||||
 | 
			
		||||
      i=0;
 | 
			
		||||
      j=0;
 | 
			
		||||
      j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 | 
			
		||||
	((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 | 
			
		||||
      String alg=Util.byte2str(K_S, i, j);
 | 
			
		||||
      i+=j;
 | 
			
		||||
 | 
			
		||||
      boolean result = verify(alg, K_S, i, sig_of_H);
 | 
			
		||||
 | 
			
		||||
      state=STATE_END;
 | 
			
		||||
      return result;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int getState(){return state; }
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] G(){ return g; }
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] P(){ return p; }
 | 
			
		||||
  @Override
 | 
			
		||||
  String sha_name(){ return "sha-1"; }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -29,187 +29,8 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
public class DHG14 extends KeyExchange{
 | 
			
		||||
class DHG14 extends DHG14N{
 | 
			
		||||
 | 
			
		||||
  static final byte[] g={ 2 };
 | 
			
		||||
  static final byte[] p={
 | 
			
		||||
(byte)0x00,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
 | 
			
		||||
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
 | 
			
		||||
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
 | 
			
		||||
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
 | 
			
		||||
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
 | 
			
		||||
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
 | 
			
		||||
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
 | 
			
		||||
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
 | 
			
		||||
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
 | 
			
		||||
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
 | 
			
		||||
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
 | 
			
		||||
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
 | 
			
		||||
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
 | 
			
		||||
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
 | 
			
		||||
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
 | 
			
		||||
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
 | 
			
		||||
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
 | 
			
		||||
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
 | 
			
		||||
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
 | 
			
		||||
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
 | 
			
		||||
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
 | 
			
		||||
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
 | 
			
		||||
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
 | 
			
		||||
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
 | 
			
		||||
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
 | 
			
		||||
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
 | 
			
		||||
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
 | 
			
		||||
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
 | 
			
		||||
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
 | 
			
		||||
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
 | 
			
		||||
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAC,(byte)0xAA,(byte)0x68,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  private static final int SSH_MSG_KEXDH_INIT=                     30;
 | 
			
		||||
  private static final int SSH_MSG_KEXDH_REPLY=                    31;
 | 
			
		||||
 | 
			
		||||
  private int state;
 | 
			
		||||
 | 
			
		||||
  DH dh;
 | 
			
		||||
 | 
			
		||||
  byte[] V_S;
 | 
			
		||||
  byte[] V_C;
 | 
			
		||||
  byte[] I_S;
 | 
			
		||||
  byte[] I_C;
 | 
			
		||||
 | 
			
		||||
  byte[] e;
 | 
			
		||||
 | 
			
		||||
  private Buffer buf;
 | 
			
		||||
  private Packet packet;
 | 
			
		||||
 | 
			
		||||
  public void init(Session session,
 | 
			
		||||
		   byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
 | 
			
		||||
    this.session=session;
 | 
			
		||||
    this.V_S=V_S;      
 | 
			
		||||
    this.V_C=V_C;      
 | 
			
		||||
    this.I_S=I_S;      
 | 
			
		||||
    this.I_C=I_C;      
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class c=Class.forName(session.getConfig("sha-1"));
 | 
			
		||||
      sha=(HASH)(c.newInstance());
 | 
			
		||||
      sha.init();
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      System.err.println(e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buf=new Buffer();
 | 
			
		||||
    packet=new Packet(buf);
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class c=Class.forName(session.getConfig("dh"));
 | 
			
		||||
      dh=(DH)(c.newInstance());
 | 
			
		||||
      dh.init();
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      //System.err.println(e);
 | 
			
		||||
      throw e;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dh.setP(p);
 | 
			
		||||
    dh.setG(g);
 | 
			
		||||
    // The client responds with:
 | 
			
		||||
    // byte  SSH_MSG_KEXDH_INIT(30)
 | 
			
		||||
    // mpint e <- g^x mod p
 | 
			
		||||
    //         x is a random number (1 < x < (p-1)/2)
 | 
			
		||||
 | 
			
		||||
    e=dh.getE();
 | 
			
		||||
    packet.reset();
 | 
			
		||||
    buf.putByte((byte)SSH_MSG_KEXDH_INIT);
 | 
			
		||||
    buf.putMPInt(e);
 | 
			
		||||
 | 
			
		||||
    if(V_S==null){  // This is a really ugly hack for Session.checkKexes ;-(
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    session.write(packet);
 | 
			
		||||
 | 
			
		||||
    if(JSch.getLogger().isEnabled(Logger.INFO)){
 | 
			
		||||
      JSch.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "SSH_MSG_KEXDH_INIT sent");
 | 
			
		||||
      JSch.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "expecting SSH_MSG_KEXDH_REPLY");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state=SSH_MSG_KEXDH_REPLY;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean next(Buffer _buf) throws Exception{
 | 
			
		||||
    int i,j;
 | 
			
		||||
 | 
			
		||||
    switch(state){
 | 
			
		||||
    case SSH_MSG_KEXDH_REPLY:
 | 
			
		||||
      // The server responds with:
 | 
			
		||||
      // byte      SSH_MSG_KEXDH_REPLY(31)
 | 
			
		||||
      // string    server public host key and certificates (K_S)
 | 
			
		||||
      // mpint     f
 | 
			
		||||
      // string    signature of H
 | 
			
		||||
      j=_buf.getInt();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      if(j!=31){
 | 
			
		||||
	System.err.println("type: must be 31 "+j);
 | 
			
		||||
	return false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      K_S=_buf.getString();
 | 
			
		||||
 | 
			
		||||
      byte[] f=_buf.getMPInt();
 | 
			
		||||
      byte[] sig_of_H=_buf.getString();
 | 
			
		||||
 | 
			
		||||
      dh.setF(f);
 | 
			
		||||
 | 
			
		||||
      dh.checkRange();
 | 
			
		||||
 | 
			
		||||
      K=normalize(dh.getK());
 | 
			
		||||
 | 
			
		||||
      //The hash H is computed as the HASH hash of the concatenation of the
 | 
			
		||||
      //following:
 | 
			
		||||
      // string    V_C, the client's version string (CR and NL excluded)
 | 
			
		||||
      // string    V_S, the server's version string (CR and NL excluded)
 | 
			
		||||
      // string    I_C, the payload of the client's SSH_MSG_KEXINIT
 | 
			
		||||
      // string    I_S, the payload of the server's SSH_MSG_KEXINIT
 | 
			
		||||
      // string    K_S, the host key
 | 
			
		||||
      // mpint     e, exchange value sent by the client
 | 
			
		||||
      // mpint     f, exchange value sent by the server
 | 
			
		||||
      // mpint     K, the shared secret
 | 
			
		||||
      // This value is called the exchange hash, and it is used to authenti-
 | 
			
		||||
      // cate the key exchange.
 | 
			
		||||
      buf.reset();
 | 
			
		||||
      buf.putString(V_C); buf.putString(V_S);
 | 
			
		||||
      buf.putString(I_C); buf.putString(I_S);
 | 
			
		||||
      buf.putString(K_S);
 | 
			
		||||
      buf.putMPInt(e); buf.putMPInt(f);
 | 
			
		||||
      buf.putMPInt(K);
 | 
			
		||||
      byte[] foo=new byte[buf.getLength()];
 | 
			
		||||
      buf.getByte(foo);
 | 
			
		||||
      sha.update(foo, 0, foo.length);
 | 
			
		||||
      H=sha.digest();
 | 
			
		||||
      //System.err.print("H -> "); //dump(H, 0, H.length);
 | 
			
		||||
 | 
			
		||||
      i=0;
 | 
			
		||||
      j=0;
 | 
			
		||||
      j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 | 
			
		||||
	((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 | 
			
		||||
      String alg=Util.byte2str(K_S, i, j);
 | 
			
		||||
      i+=j;
 | 
			
		||||
 | 
			
		||||
      boolean result = verify(alg, K_S, i, sig_of_H);
 | 
			
		||||
 | 
			
		||||
      state=STATE_END;
 | 
			
		||||
      return result;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int getState(){return state; }
 | 
			
		||||
  @Override
 | 
			
		||||
  String sha_name(){ return "sha-1"; }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHG14224 extends DHG14N{
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  String sha_name(){ return "sha-224"; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHG14256 extends DHG14N{
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  String sha_name(){ return "sha-256"; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,75 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
abstract class DHG14N extends DHGN{
 | 
			
		||||
 | 
			
		||||
  static final byte[] g={ 2 };
 | 
			
		||||
  static final byte[] p={
 | 
			
		||||
(byte)0x00,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
 | 
			
		||||
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
 | 
			
		||||
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
 | 
			
		||||
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
 | 
			
		||||
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
 | 
			
		||||
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
 | 
			
		||||
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
 | 
			
		||||
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
 | 
			
		||||
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
 | 
			
		||||
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
 | 
			
		||||
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
 | 
			
		||||
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
 | 
			
		||||
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
 | 
			
		||||
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
 | 
			
		||||
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
 | 
			
		||||
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
 | 
			
		||||
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
 | 
			
		||||
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
 | 
			
		||||
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
 | 
			
		||||
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
 | 
			
		||||
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
 | 
			
		||||
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
 | 
			
		||||
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
 | 
			
		||||
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
 | 
			
		||||
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
 | 
			
		||||
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
 | 
			
		||||
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
 | 
			
		||||
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
 | 
			
		||||
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
 | 
			
		||||
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
 | 
			
		||||
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAC,(byte)0xAA,(byte)0x68,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] G(){ return g; }
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] P(){ return p; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHG15 extends DHG15N{
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  String sha_name(){ return "sha-512"; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHG15256 extends DHG15N{
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  String sha_name(){ return "sha-256"; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHG15384 extends DHG15N{
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  String sha_name(){ return "sha-384"; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,91 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
abstract class DHG15N extends DHGN{
 | 
			
		||||
 | 
			
		||||
  static final byte[] g={ 2 };
 | 
			
		||||
  static final byte[] p={
 | 
			
		||||
(byte)0x00,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
 | 
			
		||||
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
 | 
			
		||||
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
 | 
			
		||||
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
 | 
			
		||||
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
 | 
			
		||||
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
 | 
			
		||||
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
 | 
			
		||||
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
 | 
			
		||||
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
 | 
			
		||||
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
 | 
			
		||||
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
 | 
			
		||||
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
 | 
			
		||||
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
 | 
			
		||||
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
 | 
			
		||||
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
 | 
			
		||||
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
 | 
			
		||||
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
 | 
			
		||||
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
 | 
			
		||||
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
 | 
			
		||||
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
 | 
			
		||||
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
 | 
			
		||||
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
 | 
			
		||||
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
 | 
			
		||||
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
 | 
			
		||||
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
 | 
			
		||||
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
 | 
			
		||||
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
 | 
			
		||||
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
 | 
			
		||||
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
 | 
			
		||||
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
 | 
			
		||||
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D,
 | 
			
		||||
(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33,
 | 
			
		||||
(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64,
 | 
			
		||||
(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A,
 | 
			
		||||
(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D,
 | 
			
		||||
(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7,
 | 
			
		||||
(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7,
 | 
			
		||||
(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D,
 | 
			
		||||
(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B,
 | 
			
		||||
(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64,
 | 
			
		||||
(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64,
 | 
			
		||||
(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C,
 | 
			
		||||
(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C,
 | 
			
		||||
(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2,
 | 
			
		||||
(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31,
 | 
			
		||||
(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E,
 | 
			
		||||
(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x3A,(byte)0xD2,(byte)0xCA,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] G(){ return g; }
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] P(){ return p; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHG16 extends DHG16N{
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  String sha_name(){ return "sha-512"; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHG16384 extends DHG16N{
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  String sha_name(){ return "sha-384"; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,107 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
abstract class DHG16N extends DHGN{
 | 
			
		||||
 | 
			
		||||
  static final byte[] g={ 2 };
 | 
			
		||||
  static final byte[] p={
 | 
			
		||||
(byte)0x00,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
 | 
			
		||||
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
 | 
			
		||||
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
 | 
			
		||||
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
 | 
			
		||||
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
 | 
			
		||||
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
 | 
			
		||||
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
 | 
			
		||||
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
 | 
			
		||||
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
 | 
			
		||||
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
 | 
			
		||||
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
 | 
			
		||||
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
 | 
			
		||||
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
 | 
			
		||||
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
 | 
			
		||||
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
 | 
			
		||||
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
 | 
			
		||||
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
 | 
			
		||||
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
 | 
			
		||||
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
 | 
			
		||||
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
 | 
			
		||||
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
 | 
			
		||||
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
 | 
			
		||||
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
 | 
			
		||||
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
 | 
			
		||||
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
 | 
			
		||||
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
 | 
			
		||||
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
 | 
			
		||||
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
 | 
			
		||||
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
 | 
			
		||||
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
 | 
			
		||||
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D,
 | 
			
		||||
(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33,
 | 
			
		||||
(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64,
 | 
			
		||||
(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A,
 | 
			
		||||
(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D,
 | 
			
		||||
(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7,
 | 
			
		||||
(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7,
 | 
			
		||||
(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D,
 | 
			
		||||
(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B,
 | 
			
		||||
(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64,
 | 
			
		||||
(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64,
 | 
			
		||||
(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C,
 | 
			
		||||
(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C,
 | 
			
		||||
(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2,
 | 
			
		||||
(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31,
 | 
			
		||||
(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E,
 | 
			
		||||
(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01,
 | 
			
		||||
(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7,
 | 
			
		||||
(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26,
 | 
			
		||||
(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C,
 | 
			
		||||
(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA,
 | 
			
		||||
(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8,
 | 
			
		||||
(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9,
 | 
			
		||||
(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6,
 | 
			
		||||
(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D,
 | 
			
		||||
(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2,
 | 
			
		||||
(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED,
 | 
			
		||||
(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF,
 | 
			
		||||
(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C,
 | 
			
		||||
(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9,
 | 
			
		||||
(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1,
 | 
			
		||||
(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F,
 | 
			
		||||
(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x06,(byte)0x31,(byte)0x99,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] G(){ return g; }
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] P(){ return p; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,141 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHG17 extends DHGN{
 | 
			
		||||
 | 
			
		||||
  static final byte[] g={ 2 };
 | 
			
		||||
  static final byte[] p={
 | 
			
		||||
(byte)0x00,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
 | 
			
		||||
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
 | 
			
		||||
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
 | 
			
		||||
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
 | 
			
		||||
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
 | 
			
		||||
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
 | 
			
		||||
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
 | 
			
		||||
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
 | 
			
		||||
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
 | 
			
		||||
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
 | 
			
		||||
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
 | 
			
		||||
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
 | 
			
		||||
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
 | 
			
		||||
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
 | 
			
		||||
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
 | 
			
		||||
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
 | 
			
		||||
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
 | 
			
		||||
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
 | 
			
		||||
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
 | 
			
		||||
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
 | 
			
		||||
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
 | 
			
		||||
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
 | 
			
		||||
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
 | 
			
		||||
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
 | 
			
		||||
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
 | 
			
		||||
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
 | 
			
		||||
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
 | 
			
		||||
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
 | 
			
		||||
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
 | 
			
		||||
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
 | 
			
		||||
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D,
 | 
			
		||||
(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33,
 | 
			
		||||
(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64,
 | 
			
		||||
(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A,
 | 
			
		||||
(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D,
 | 
			
		||||
(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7,
 | 
			
		||||
(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7,
 | 
			
		||||
(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D,
 | 
			
		||||
(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B,
 | 
			
		||||
(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64,
 | 
			
		||||
(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64,
 | 
			
		||||
(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C,
 | 
			
		||||
(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C,
 | 
			
		||||
(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2,
 | 
			
		||||
(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31,
 | 
			
		||||
(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E,
 | 
			
		||||
(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01,
 | 
			
		||||
(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7,
 | 
			
		||||
(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26,
 | 
			
		||||
(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C,
 | 
			
		||||
(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA,
 | 
			
		||||
(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8,
 | 
			
		||||
(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9,
 | 
			
		||||
(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6,
 | 
			
		||||
(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D,
 | 
			
		||||
(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2,
 | 
			
		||||
(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED,
 | 
			
		||||
(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF,
 | 
			
		||||
(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C,
 | 
			
		||||
(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9,
 | 
			
		||||
(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1,
 | 
			
		||||
(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F,
 | 
			
		||||
(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x02,(byte)0x84,(byte)0x92,
 | 
			
		||||
(byte)0x36,(byte)0xC3,(byte)0xFA,(byte)0xB4,(byte)0xD2,(byte)0x7C,(byte)0x70,(byte)0x26,
 | 
			
		||||
(byte)0xC1,(byte)0xD4,(byte)0xDC,(byte)0xB2,(byte)0x60,(byte)0x26,(byte)0x46,(byte)0xDE,
 | 
			
		||||
(byte)0xC9,(byte)0x75,(byte)0x1E,(byte)0x76,(byte)0x3D,(byte)0xBA,(byte)0x37,(byte)0xBD,
 | 
			
		||||
(byte)0xF8,(byte)0xFF,(byte)0x94,(byte)0x06,(byte)0xAD,(byte)0x9E,(byte)0x53,(byte)0x0E,
 | 
			
		||||
(byte)0xE5,(byte)0xDB,(byte)0x38,(byte)0x2F,(byte)0x41,(byte)0x30,(byte)0x01,(byte)0xAE,
 | 
			
		||||
(byte)0xB0,(byte)0x6A,(byte)0x53,(byte)0xED,(byte)0x90,(byte)0x27,(byte)0xD8,(byte)0x31,
 | 
			
		||||
(byte)0x17,(byte)0x97,(byte)0x27,(byte)0xB0,(byte)0x86,(byte)0x5A,(byte)0x89,(byte)0x18,
 | 
			
		||||
(byte)0xDA,(byte)0x3E,(byte)0xDB,(byte)0xEB,(byte)0xCF,(byte)0x9B,(byte)0x14,(byte)0xED,
 | 
			
		||||
(byte)0x44,(byte)0xCE,(byte)0x6C,(byte)0xBA,(byte)0xCE,(byte)0xD4,(byte)0xBB,(byte)0x1B,
 | 
			
		||||
(byte)0xDB,(byte)0x7F,(byte)0x14,(byte)0x47,(byte)0xE6,(byte)0xCC,(byte)0x25,(byte)0x4B,
 | 
			
		||||
(byte)0x33,(byte)0x20,(byte)0x51,(byte)0x51,(byte)0x2B,(byte)0xD7,(byte)0xAF,(byte)0x42,
 | 
			
		||||
(byte)0x6F,(byte)0xB8,(byte)0xF4,(byte)0x01,(byte)0x37,(byte)0x8C,(byte)0xD2,(byte)0xBF,
 | 
			
		||||
(byte)0x59,(byte)0x83,(byte)0xCA,(byte)0x01,(byte)0xC6,(byte)0x4B,(byte)0x92,(byte)0xEC,
 | 
			
		||||
(byte)0xF0,(byte)0x32,(byte)0xEA,(byte)0x15,(byte)0xD1,(byte)0x72,(byte)0x1D,(byte)0x03,
 | 
			
		||||
(byte)0xF4,(byte)0x82,(byte)0xD7,(byte)0xCE,(byte)0x6E,(byte)0x74,(byte)0xFE,(byte)0xF6,
 | 
			
		||||
(byte)0xD5,(byte)0x5E,(byte)0x70,(byte)0x2F,(byte)0x46,(byte)0x98,(byte)0x0C,(byte)0x82,
 | 
			
		||||
(byte)0xB5,(byte)0xA8,(byte)0x40,(byte)0x31,(byte)0x90,(byte)0x0B,(byte)0x1C,(byte)0x9E,
 | 
			
		||||
(byte)0x59,(byte)0xE7,(byte)0xC9,(byte)0x7F,(byte)0xBE,(byte)0xC7,(byte)0xE8,(byte)0xF3,
 | 
			
		||||
(byte)0x23,(byte)0xA9,(byte)0x7A,(byte)0x7E,(byte)0x36,(byte)0xCC,(byte)0x88,(byte)0xBE,
 | 
			
		||||
(byte)0x0F,(byte)0x1D,(byte)0x45,(byte)0xB7,(byte)0xFF,(byte)0x58,(byte)0x5A,(byte)0xC5,
 | 
			
		||||
(byte)0x4B,(byte)0xD4,(byte)0x07,(byte)0xB2,(byte)0x2B,(byte)0x41,(byte)0x54,(byte)0xAA,
 | 
			
		||||
(byte)0xCC,(byte)0x8F,(byte)0x6D,(byte)0x7E,(byte)0xBF,(byte)0x48,(byte)0xE1,(byte)0xD8,
 | 
			
		||||
(byte)0x14,(byte)0xCC,(byte)0x5E,(byte)0xD2,(byte)0x0F,(byte)0x80,(byte)0x37,(byte)0xE0,
 | 
			
		||||
(byte)0xA7,(byte)0x97,(byte)0x15,(byte)0xEE,(byte)0xF2,(byte)0x9B,(byte)0xE3,(byte)0x28,
 | 
			
		||||
(byte)0x06,(byte)0xA1,(byte)0xD5,(byte)0x8B,(byte)0xB7,(byte)0xC5,(byte)0xDA,(byte)0x76,
 | 
			
		||||
(byte)0xF5,(byte)0x50,(byte)0xAA,(byte)0x3D,(byte)0x8A,(byte)0x1F,(byte)0xBF,(byte)0xF0,
 | 
			
		||||
(byte)0xEB,(byte)0x19,(byte)0xCC,(byte)0xB1,(byte)0xA3,(byte)0x13,(byte)0xD5,(byte)0x5C,
 | 
			
		||||
(byte)0xDA,(byte)0x56,(byte)0xC9,(byte)0xEC,(byte)0x2E,(byte)0xF2,(byte)0x96,(byte)0x32,
 | 
			
		||||
(byte)0x38,(byte)0x7F,(byte)0xE8,(byte)0xD7,(byte)0x6E,(byte)0x3C,(byte)0x04,(byte)0x68,
 | 
			
		||||
(byte)0x04,(byte)0x3E,(byte)0x8F,(byte)0x66,(byte)0x3F,(byte)0x48,(byte)0x60,(byte)0xEE,
 | 
			
		||||
(byte)0x12,(byte)0xBF,(byte)0x2D,(byte)0x5B,(byte)0x0B,(byte)0x74,(byte)0x74,(byte)0xD6,
 | 
			
		||||
(byte)0xE6,(byte)0x94,(byte)0xF9,(byte)0x1E,(byte)0x6D,(byte)0xCC,(byte)0x40,(byte)0x24,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] G(){ return g; }
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] P(){ return p; }
 | 
			
		||||
  @Override
 | 
			
		||||
  String sha_name(){ return "sha-512"; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,173 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHG18 extends DHGN{
 | 
			
		||||
 | 
			
		||||
  static final byte[] g={ 2 };
 | 
			
		||||
  static final byte[] p={
 | 
			
		||||
(byte)0x00,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
 | 
			
		||||
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
 | 
			
		||||
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
 | 
			
		||||
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
 | 
			
		||||
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
 | 
			
		||||
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
 | 
			
		||||
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
 | 
			
		||||
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
 | 
			
		||||
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
 | 
			
		||||
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
 | 
			
		||||
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
 | 
			
		||||
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
 | 
			
		||||
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
 | 
			
		||||
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
 | 
			
		||||
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE4,(byte)0x5B,(byte)0x3D,
 | 
			
		||||
(byte)0xC2,(byte)0x00,(byte)0x7C,(byte)0xB8,(byte)0xA1,(byte)0x63,(byte)0xBF,(byte)0x05,
 | 
			
		||||
(byte)0x98,(byte)0xDA,(byte)0x48,(byte)0x36,(byte)0x1C,(byte)0x55,(byte)0xD3,(byte)0x9A,
 | 
			
		||||
(byte)0x69,(byte)0x16,(byte)0x3F,(byte)0xA8,(byte)0xFD,(byte)0x24,(byte)0xCF,(byte)0x5F,
 | 
			
		||||
(byte)0x83,(byte)0x65,(byte)0x5D,(byte)0x23,(byte)0xDC,(byte)0xA3,(byte)0xAD,(byte)0x96,
 | 
			
		||||
(byte)0x1C,(byte)0x62,(byte)0xF3,(byte)0x56,(byte)0x20,(byte)0x85,(byte)0x52,(byte)0xBB,
 | 
			
		||||
(byte)0x9E,(byte)0xD5,(byte)0x29,(byte)0x07,(byte)0x70,(byte)0x96,(byte)0x96,(byte)0x6D,
 | 
			
		||||
(byte)0x67,(byte)0x0C,(byte)0x35,(byte)0x4E,(byte)0x4A,(byte)0xBC,(byte)0x98,(byte)0x04,
 | 
			
		||||
(byte)0xF1,(byte)0x74,(byte)0x6C,(byte)0x08,(byte)0xCA,(byte)0x18,(byte)0x21,(byte)0x7C,
 | 
			
		||||
(byte)0x32,(byte)0x90,(byte)0x5E,(byte)0x46,(byte)0x2E,(byte)0x36,(byte)0xCE,(byte)0x3B,
 | 
			
		||||
(byte)0xE3,(byte)0x9E,(byte)0x77,(byte)0x2C,(byte)0x18,(byte)0x0E,(byte)0x86,(byte)0x03,
 | 
			
		||||
(byte)0x9B,(byte)0x27,(byte)0x83,(byte)0xA2,(byte)0xEC,(byte)0x07,(byte)0xA2,(byte)0x8F,
 | 
			
		||||
(byte)0xB5,(byte)0xC5,(byte)0x5D,(byte)0xF0,(byte)0x6F,(byte)0x4C,(byte)0x52,(byte)0xC9,
 | 
			
		||||
(byte)0xDE,(byte)0x2B,(byte)0xCB,(byte)0xF6,(byte)0x95,(byte)0x58,(byte)0x17,(byte)0x18,
 | 
			
		||||
(byte)0x39,(byte)0x95,(byte)0x49,(byte)0x7C,(byte)0xEA,(byte)0x95,(byte)0x6A,(byte)0xE5,
 | 
			
		||||
(byte)0x15,(byte)0xD2,(byte)0x26,(byte)0x18,(byte)0x98,(byte)0xFA,(byte)0x05,(byte)0x10,
 | 
			
		||||
(byte)0x15,(byte)0x72,(byte)0x8E,(byte)0x5A,(byte)0x8A,(byte)0xAA,(byte)0xC4,(byte)0x2D,
 | 
			
		||||
(byte)0xAD,(byte)0x33,(byte)0x17,(byte)0x0D,(byte)0x04,(byte)0x50,(byte)0x7A,(byte)0x33,
 | 
			
		||||
(byte)0xA8,(byte)0x55,(byte)0x21,(byte)0xAB,(byte)0xDF,(byte)0x1C,(byte)0xBA,(byte)0x64,
 | 
			
		||||
(byte)0xEC,(byte)0xFB,(byte)0x85,(byte)0x04,(byte)0x58,(byte)0xDB,(byte)0xEF,(byte)0x0A,
 | 
			
		||||
(byte)0x8A,(byte)0xEA,(byte)0x71,(byte)0x57,(byte)0x5D,(byte)0x06,(byte)0x0C,(byte)0x7D,
 | 
			
		||||
(byte)0xB3,(byte)0x97,(byte)0x0F,(byte)0x85,(byte)0xA6,(byte)0xE1,(byte)0xE4,(byte)0xC7,
 | 
			
		||||
(byte)0xAB,(byte)0xF5,(byte)0xAE,(byte)0x8C,(byte)0xDB,(byte)0x09,(byte)0x33,(byte)0xD7,
 | 
			
		||||
(byte)0x1E,(byte)0x8C,(byte)0x94,(byte)0xE0,(byte)0x4A,(byte)0x25,(byte)0x61,(byte)0x9D,
 | 
			
		||||
(byte)0xCE,(byte)0xE3,(byte)0xD2,(byte)0x26,(byte)0x1A,(byte)0xD2,(byte)0xEE,(byte)0x6B,
 | 
			
		||||
(byte)0xF1,(byte)0x2F,(byte)0xFA,(byte)0x06,(byte)0xD9,(byte)0x8A,(byte)0x08,(byte)0x64,
 | 
			
		||||
(byte)0xD8,(byte)0x76,(byte)0x02,(byte)0x73,(byte)0x3E,(byte)0xC8,(byte)0x6A,(byte)0x64,
 | 
			
		||||
(byte)0x52,(byte)0x1F,(byte)0x2B,(byte)0x18,(byte)0x17,(byte)0x7B,(byte)0x20,(byte)0x0C,
 | 
			
		||||
(byte)0xBB,(byte)0xE1,(byte)0x17,(byte)0x57,(byte)0x7A,(byte)0x61,(byte)0x5D,(byte)0x6C,
 | 
			
		||||
(byte)0x77,(byte)0x09,(byte)0x88,(byte)0xC0,(byte)0xBA,(byte)0xD9,(byte)0x46,(byte)0xE2,
 | 
			
		||||
(byte)0x08,(byte)0xE2,(byte)0x4F,(byte)0xA0,(byte)0x74,(byte)0xE5,(byte)0xAB,(byte)0x31,
 | 
			
		||||
(byte)0x43,(byte)0xDB,(byte)0x5B,(byte)0xFC,(byte)0xE0,(byte)0xFD,(byte)0x10,(byte)0x8E,
 | 
			
		||||
(byte)0x4B,(byte)0x82,(byte)0xD1,(byte)0x20,(byte)0xA9,(byte)0x21,(byte)0x08,(byte)0x01,
 | 
			
		||||
(byte)0x1A,(byte)0x72,(byte)0x3C,(byte)0x12,(byte)0xA7,(byte)0x87,(byte)0xE6,(byte)0xD7,
 | 
			
		||||
(byte)0x88,(byte)0x71,(byte)0x9A,(byte)0x10,(byte)0xBD,(byte)0xBA,(byte)0x5B,(byte)0x26,
 | 
			
		||||
(byte)0x99,(byte)0xC3,(byte)0x27,(byte)0x18,(byte)0x6A,(byte)0xF4,(byte)0xE2,(byte)0x3C,
 | 
			
		||||
(byte)0x1A,(byte)0x94,(byte)0x68,(byte)0x34,(byte)0xB6,(byte)0x15,(byte)0x0B,(byte)0xDA,
 | 
			
		||||
(byte)0x25,(byte)0x83,(byte)0xE9,(byte)0xCA,(byte)0x2A,(byte)0xD4,(byte)0x4C,(byte)0xE8,
 | 
			
		||||
(byte)0xDB,(byte)0xBB,(byte)0xC2,(byte)0xDB,(byte)0x04,(byte)0xDE,(byte)0x8E,(byte)0xF9,
 | 
			
		||||
(byte)0x2E,(byte)0x8E,(byte)0xFC,(byte)0x14,(byte)0x1F,(byte)0xBE,(byte)0xCA,(byte)0xA6,
 | 
			
		||||
(byte)0x28,(byte)0x7C,(byte)0x59,(byte)0x47,(byte)0x4E,(byte)0x6B,(byte)0xC0,(byte)0x5D,
 | 
			
		||||
(byte)0x99,(byte)0xB2,(byte)0x96,(byte)0x4F,(byte)0xA0,(byte)0x90,(byte)0xC3,(byte)0xA2,
 | 
			
		||||
(byte)0x23,(byte)0x3B,(byte)0xA1,(byte)0x86,(byte)0x51,(byte)0x5B,(byte)0xE7,(byte)0xED,
 | 
			
		||||
(byte)0x1F,(byte)0x61,(byte)0x29,(byte)0x70,(byte)0xCE,(byte)0xE2,(byte)0xD7,(byte)0xAF,
 | 
			
		||||
(byte)0xB8,(byte)0x1B,(byte)0xDD,(byte)0x76,(byte)0x21,(byte)0x70,(byte)0x48,(byte)0x1C,
 | 
			
		||||
(byte)0xD0,(byte)0x06,(byte)0x91,(byte)0x27,(byte)0xD5,(byte)0xB0,(byte)0x5A,(byte)0xA9,
 | 
			
		||||
(byte)0x93,(byte)0xB4,(byte)0xEA,(byte)0x98,(byte)0x8D,(byte)0x8F,(byte)0xDD,(byte)0xC1,
 | 
			
		||||
(byte)0x86,(byte)0xFF,(byte)0xB7,(byte)0xDC,(byte)0x90,(byte)0xA6,(byte)0xC0,(byte)0x8F,
 | 
			
		||||
(byte)0x4D,(byte)0xF4,(byte)0x35,(byte)0xC9,(byte)0x34,(byte)0x02,(byte)0x84,(byte)0x92,
 | 
			
		||||
(byte)0x36,(byte)0xC3,(byte)0xFA,(byte)0xB4,(byte)0xD2,(byte)0x7C,(byte)0x70,(byte)0x26,
 | 
			
		||||
(byte)0xC1,(byte)0xD4,(byte)0xDC,(byte)0xB2,(byte)0x60,(byte)0x26,(byte)0x46,(byte)0xDE,
 | 
			
		||||
(byte)0xC9,(byte)0x75,(byte)0x1E,(byte)0x76,(byte)0x3D,(byte)0xBA,(byte)0x37,(byte)0xBD,
 | 
			
		||||
(byte)0xF8,(byte)0xFF,(byte)0x94,(byte)0x06,(byte)0xAD,(byte)0x9E,(byte)0x53,(byte)0x0E,
 | 
			
		||||
(byte)0xE5,(byte)0xDB,(byte)0x38,(byte)0x2F,(byte)0x41,(byte)0x30,(byte)0x01,(byte)0xAE,
 | 
			
		||||
(byte)0xB0,(byte)0x6A,(byte)0x53,(byte)0xED,(byte)0x90,(byte)0x27,(byte)0xD8,(byte)0x31,
 | 
			
		||||
(byte)0x17,(byte)0x97,(byte)0x27,(byte)0xB0,(byte)0x86,(byte)0x5A,(byte)0x89,(byte)0x18,
 | 
			
		||||
(byte)0xDA,(byte)0x3E,(byte)0xDB,(byte)0xEB,(byte)0xCF,(byte)0x9B,(byte)0x14,(byte)0xED,
 | 
			
		||||
(byte)0x44,(byte)0xCE,(byte)0x6C,(byte)0xBA,(byte)0xCE,(byte)0xD4,(byte)0xBB,(byte)0x1B,
 | 
			
		||||
(byte)0xDB,(byte)0x7F,(byte)0x14,(byte)0x47,(byte)0xE6,(byte)0xCC,(byte)0x25,(byte)0x4B,
 | 
			
		||||
(byte)0x33,(byte)0x20,(byte)0x51,(byte)0x51,(byte)0x2B,(byte)0xD7,(byte)0xAF,(byte)0x42,
 | 
			
		||||
(byte)0x6F,(byte)0xB8,(byte)0xF4,(byte)0x01,(byte)0x37,(byte)0x8C,(byte)0xD2,(byte)0xBF,
 | 
			
		||||
(byte)0x59,(byte)0x83,(byte)0xCA,(byte)0x01,(byte)0xC6,(byte)0x4B,(byte)0x92,(byte)0xEC,
 | 
			
		||||
(byte)0xF0,(byte)0x32,(byte)0xEA,(byte)0x15,(byte)0xD1,(byte)0x72,(byte)0x1D,(byte)0x03,
 | 
			
		||||
(byte)0xF4,(byte)0x82,(byte)0xD7,(byte)0xCE,(byte)0x6E,(byte)0x74,(byte)0xFE,(byte)0xF6,
 | 
			
		||||
(byte)0xD5,(byte)0x5E,(byte)0x70,(byte)0x2F,(byte)0x46,(byte)0x98,(byte)0x0C,(byte)0x82,
 | 
			
		||||
(byte)0xB5,(byte)0xA8,(byte)0x40,(byte)0x31,(byte)0x90,(byte)0x0B,(byte)0x1C,(byte)0x9E,
 | 
			
		||||
(byte)0x59,(byte)0xE7,(byte)0xC9,(byte)0x7F,(byte)0xBE,(byte)0xC7,(byte)0xE8,(byte)0xF3,
 | 
			
		||||
(byte)0x23,(byte)0xA9,(byte)0x7A,(byte)0x7E,(byte)0x36,(byte)0xCC,(byte)0x88,(byte)0xBE,
 | 
			
		||||
(byte)0x0F,(byte)0x1D,(byte)0x45,(byte)0xB7,(byte)0xFF,(byte)0x58,(byte)0x5A,(byte)0xC5,
 | 
			
		||||
(byte)0x4B,(byte)0xD4,(byte)0x07,(byte)0xB2,(byte)0x2B,(byte)0x41,(byte)0x54,(byte)0xAA,
 | 
			
		||||
(byte)0xCC,(byte)0x8F,(byte)0x6D,(byte)0x7E,(byte)0xBF,(byte)0x48,(byte)0xE1,(byte)0xD8,
 | 
			
		||||
(byte)0x14,(byte)0xCC,(byte)0x5E,(byte)0xD2,(byte)0x0F,(byte)0x80,(byte)0x37,(byte)0xE0,
 | 
			
		||||
(byte)0xA7,(byte)0x97,(byte)0x15,(byte)0xEE,(byte)0xF2,(byte)0x9B,(byte)0xE3,(byte)0x28,
 | 
			
		||||
(byte)0x06,(byte)0xA1,(byte)0xD5,(byte)0x8B,(byte)0xB7,(byte)0xC5,(byte)0xDA,(byte)0x76,
 | 
			
		||||
(byte)0xF5,(byte)0x50,(byte)0xAA,(byte)0x3D,(byte)0x8A,(byte)0x1F,(byte)0xBF,(byte)0xF0,
 | 
			
		||||
(byte)0xEB,(byte)0x19,(byte)0xCC,(byte)0xB1,(byte)0xA3,(byte)0x13,(byte)0xD5,(byte)0x5C,
 | 
			
		||||
(byte)0xDA,(byte)0x56,(byte)0xC9,(byte)0xEC,(byte)0x2E,(byte)0xF2,(byte)0x96,(byte)0x32,
 | 
			
		||||
(byte)0x38,(byte)0x7F,(byte)0xE8,(byte)0xD7,(byte)0x6E,(byte)0x3C,(byte)0x04,(byte)0x68,
 | 
			
		||||
(byte)0x04,(byte)0x3E,(byte)0x8F,(byte)0x66,(byte)0x3F,(byte)0x48,(byte)0x60,(byte)0xEE,
 | 
			
		||||
(byte)0x12,(byte)0xBF,(byte)0x2D,(byte)0x5B,(byte)0x0B,(byte)0x74,(byte)0x74,(byte)0xD6,
 | 
			
		||||
(byte)0xE6,(byte)0x94,(byte)0xF9,(byte)0x1E,(byte)0x6D,(byte)0xBE,(byte)0x11,(byte)0x59,
 | 
			
		||||
(byte)0x74,(byte)0xA3,(byte)0x92,(byte)0x6F,(byte)0x12,(byte)0xFE,(byte)0xE5,(byte)0xE4,
 | 
			
		||||
(byte)0x38,(byte)0x77,(byte)0x7C,(byte)0xB6,(byte)0xA9,(byte)0x32,(byte)0xDF,(byte)0x8C,
 | 
			
		||||
(byte)0xD8,(byte)0xBE,(byte)0xC4,(byte)0xD0,(byte)0x73,(byte)0xB9,(byte)0x31,(byte)0xBA,
 | 
			
		||||
(byte)0x3B,(byte)0xC8,(byte)0x32,(byte)0xB6,(byte)0x8D,(byte)0x9D,(byte)0xD3,(byte)0x00,
 | 
			
		||||
(byte)0x74,(byte)0x1F,(byte)0xA7,(byte)0xBF,(byte)0x8A,(byte)0xFC,(byte)0x47,(byte)0xED,
 | 
			
		||||
(byte)0x25,(byte)0x76,(byte)0xF6,(byte)0x93,(byte)0x6B,(byte)0xA4,(byte)0x24,(byte)0x66,
 | 
			
		||||
(byte)0x3A,(byte)0xAB,(byte)0x63,(byte)0x9C,(byte)0x5A,(byte)0xE4,(byte)0xF5,(byte)0x68,
 | 
			
		||||
(byte)0x34,(byte)0x23,(byte)0xB4,(byte)0x74,(byte)0x2B,(byte)0xF1,(byte)0xC9,(byte)0x78,
 | 
			
		||||
(byte)0x23,(byte)0x8F,(byte)0x16,(byte)0xCB,(byte)0xE3,(byte)0x9D,(byte)0x65,(byte)0x2D,
 | 
			
		||||
(byte)0xE3,(byte)0xFD,(byte)0xB8,(byte)0xBE,(byte)0xFC,(byte)0x84,(byte)0x8A,(byte)0xD9,
 | 
			
		||||
(byte)0x22,(byte)0x22,(byte)0x2E,(byte)0x04,(byte)0xA4,(byte)0x03,(byte)0x7C,(byte)0x07,
 | 
			
		||||
(byte)0x13,(byte)0xEB,(byte)0x57,(byte)0xA8,(byte)0x1A,(byte)0x23,(byte)0xF0,(byte)0xC7,
 | 
			
		||||
(byte)0x34,(byte)0x73,(byte)0xFC,(byte)0x64,(byte)0x6C,(byte)0xEA,(byte)0x30,(byte)0x6B,
 | 
			
		||||
(byte)0x4B,(byte)0xCB,(byte)0xC8,(byte)0x86,(byte)0x2F,(byte)0x83,(byte)0x85,(byte)0xDD,
 | 
			
		||||
(byte)0xFA,(byte)0x9D,(byte)0x4B,(byte)0x7F,(byte)0xA2,(byte)0xC0,(byte)0x87,(byte)0xE8,
 | 
			
		||||
(byte)0x79,(byte)0x68,(byte)0x33,(byte)0x03,(byte)0xED,(byte)0x5B,(byte)0xDD,(byte)0x3A,
 | 
			
		||||
(byte)0x06,(byte)0x2B,(byte)0x3C,(byte)0xF5,(byte)0xB3,(byte)0xA2,(byte)0x78,(byte)0xA6,
 | 
			
		||||
(byte)0x6D,(byte)0x2A,(byte)0x13,(byte)0xF8,(byte)0x3F,(byte)0x44,(byte)0xF8,(byte)0x2D,
 | 
			
		||||
(byte)0xDF,(byte)0x31,(byte)0x0E,(byte)0xE0,(byte)0x74,(byte)0xAB,(byte)0x6A,(byte)0x36,
 | 
			
		||||
(byte)0x45,(byte)0x97,(byte)0xE8,(byte)0x99,(byte)0xA0,(byte)0x25,(byte)0x5D,(byte)0xC1,
 | 
			
		||||
(byte)0x64,(byte)0xF3,(byte)0x1C,(byte)0xC5,(byte)0x08,(byte)0x46,(byte)0x85,(byte)0x1D,
 | 
			
		||||
(byte)0xF9,(byte)0xAB,(byte)0x48,(byte)0x19,(byte)0x5D,(byte)0xED,(byte)0x7E,(byte)0xA1,
 | 
			
		||||
(byte)0xB1,(byte)0xD5,(byte)0x10,(byte)0xBD,(byte)0x7E,(byte)0xE7,(byte)0x4D,(byte)0x73,
 | 
			
		||||
(byte)0xFA,(byte)0xF3,(byte)0x6B,(byte)0xC3,(byte)0x1E,(byte)0xCF,(byte)0xA2,(byte)0x68,
 | 
			
		||||
(byte)0x35,(byte)0x90,(byte)0x46,(byte)0xF4,(byte)0xEB,(byte)0x87,(byte)0x9F,(byte)0x92,
 | 
			
		||||
(byte)0x40,(byte)0x09,(byte)0x43,(byte)0x8B,(byte)0x48,(byte)0x1C,(byte)0x6C,(byte)0xD7,
 | 
			
		||||
(byte)0x88,(byte)0x9A,(byte)0x00,(byte)0x2E,(byte)0xD5,(byte)0xEE,(byte)0x38,(byte)0x2B,
 | 
			
		||||
(byte)0xC9,(byte)0x19,(byte)0x0D,(byte)0xA6,(byte)0xFC,(byte)0x02,(byte)0x6E,(byte)0x47,
 | 
			
		||||
(byte)0x95,(byte)0x58,(byte)0xE4,(byte)0x47,(byte)0x56,(byte)0x77,(byte)0xE9,(byte)0xAA,
 | 
			
		||||
(byte)0x9E,(byte)0x30,(byte)0x50,(byte)0xE2,(byte)0x76,(byte)0x56,(byte)0x94,(byte)0xDF,
 | 
			
		||||
(byte)0xC8,(byte)0x1F,(byte)0x56,(byte)0xE8,(byte)0x80,(byte)0xB9,(byte)0x6E,(byte)0x71,
 | 
			
		||||
(byte)0x60,(byte)0xC9,(byte)0x80,(byte)0xDD,(byte)0x98,(byte)0xED,(byte)0xD3,(byte)0xDF,
 | 
			
		||||
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] G(){ return g; }
 | 
			
		||||
  @Override
 | 
			
		||||
  byte[] P(){ return p; }
 | 
			
		||||
  @Override
 | 
			
		||||
  String sha_name(){ return "sha-512"; }
 | 
			
		||||
}
 | 
			
		||||
@@ -29,16 +29,16 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
public class DHGEX extends KeyExchange{
 | 
			
		||||
abstract class DHGEX extends KeyExchange{
 | 
			
		||||
 | 
			
		||||
  private static final int SSH_MSG_KEX_DH_GEX_GROUP=               31;
 | 
			
		||||
  private static final int SSH_MSG_KEX_DH_GEX_INIT=                32;
 | 
			
		||||
  private static final int SSH_MSG_KEX_DH_GEX_REPLY=               33;
 | 
			
		||||
  private static final int SSH_MSG_KEX_DH_GEX_REQUEST=             34;
 | 
			
		||||
 | 
			
		||||
  static int min=1024;
 | 
			
		||||
  static int preferred=1024;
 | 
			
		||||
  int max=1024;
 | 
			
		||||
  int min;
 | 
			
		||||
  int preferred;
 | 
			
		||||
  int max;
 | 
			
		||||
 | 
			
		||||
  private int state;
 | 
			
		||||
 | 
			
		||||
@@ -56,19 +56,19 @@ public class DHGEX extends KeyExchange{
 | 
			
		||||
  private byte[] g;
 | 
			
		||||
  private byte[] e;
 | 
			
		||||
 | 
			
		||||
  protected String hash="sha-1";
 | 
			
		||||
  protected String hash;
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void init(Session session,
 | 
			
		||||
		   byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
 | 
			
		||||
    this.session=session;
 | 
			
		||||
                   byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
 | 
			
		||||
    this.V_S=V_S;      
 | 
			
		||||
    this.V_C=V_C;      
 | 
			
		||||
    this.I_S=I_S;      
 | 
			
		||||
    this.I_C=I_C;      
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class c=Class.forName(session.getConfig(hash));
 | 
			
		||||
      sha=(HASH)(c.newInstance());
 | 
			
		||||
      Class<? extends HASH> c=Class.forName(session.getConfig(hash)).asSubclass(HASH.class);
 | 
			
		||||
      sha=c.getDeclaredConstructor().newInstance();
 | 
			
		||||
      sha.init();
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
@@ -79,11 +79,14 @@ public class DHGEX extends KeyExchange{
 | 
			
		||||
    packet=new Packet(buf);
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class c=Class.forName(session.getConfig("dh"));
 | 
			
		||||
      // Since JDK8, SunJCE has lifted the keysize restrictions
 | 
			
		||||
      // from 1024 to 2048 for DH.
 | 
			
		||||
      preferred = max = check2048(c, max); 
 | 
			
		||||
      dh=(com.jcraft.jsch.DH)(c.newInstance());
 | 
			
		||||
      Class<? extends DH> c=Class.forName(session.getConfig("dh")).asSubclass(DH.class);
 | 
			
		||||
      min=Integer.parseInt(session.getConfig("dhgex_min"));
 | 
			
		||||
      max=Integer.parseInt(session.getConfig("dhgex_max"));
 | 
			
		||||
      preferred=Integer.parseInt(session.getConfig("dhgex_preferred"));
 | 
			
		||||
      if(checkInvalidSize(min) || checkInvalidSize(max) || checkInvalidSize(preferred) || preferred < min || max < preferred){
 | 
			
		||||
        throw new JSchException("Invalid DHGEX sizes: min=" + min + " max=" + max + " preferred=" + preferred);
 | 
			
		||||
      }
 | 
			
		||||
      dh=c.getDeclaredConstructor().newInstance();
 | 
			
		||||
      dh.init();
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
@@ -97,16 +100,17 @@ public class DHGEX extends KeyExchange{
 | 
			
		||||
    buf.putInt(max);
 | 
			
		||||
    session.write(packet); 
 | 
			
		||||
 | 
			
		||||
    if(JSch.getLogger().isEnabled(Logger.INFO)){
 | 
			
		||||
      JSch.getLogger().log(Logger.INFO, 
 | 
			
		||||
    if(session.getLogger().isEnabled(Logger.INFO)){
 | 
			
		||||
      session.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "SSH_MSG_KEX_DH_GEX_REQUEST("+min+"<"+preferred+"<"+max+") sent");
 | 
			
		||||
      JSch.getLogger().log(Logger.INFO, 
 | 
			
		||||
      session.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "expecting SSH_MSG_KEX_DH_GEX_GROUP");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state=SSH_MSG_KEX_DH_GEX_GROUP;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean next(Buffer _buf) throws Exception{
 | 
			
		||||
    int i,j;
 | 
			
		||||
    switch(state){
 | 
			
		||||
@@ -118,8 +122,8 @@ public class DHGEX extends KeyExchange{
 | 
			
		||||
      _buf.getByte();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      if(j!=SSH_MSG_KEX_DH_GEX_GROUP){
 | 
			
		||||
	System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP "+j);
 | 
			
		||||
	return false;
 | 
			
		||||
        System.err.println("type: must be SSH_MSG_KEX_DH_GEX_GROUP "+j);
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      p=_buf.getMPInt();
 | 
			
		||||
@@ -139,10 +143,10 @@ public class DHGEX extends KeyExchange{
 | 
			
		||||
      buf.putMPInt(e);
 | 
			
		||||
      session.write(packet);
 | 
			
		||||
 | 
			
		||||
      if(JSch.getLogger().isEnabled(Logger.INFO)){
 | 
			
		||||
        JSch.getLogger().log(Logger.INFO, 
 | 
			
		||||
      if(session.getLogger().isEnabled(Logger.INFO)){
 | 
			
		||||
        session.getLogger().log(Logger.INFO, 
 | 
			
		||||
                             "SSH_MSG_KEX_DH_GEX_INIT sent");
 | 
			
		||||
        JSch.getLogger().log(Logger.INFO, 
 | 
			
		||||
        session.getLogger().log(Logger.INFO, 
 | 
			
		||||
                             "expecting SSH_MSG_KEX_DH_GEX_REPLY");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@@ -160,8 +164,8 @@ public class DHGEX extends KeyExchange{
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      if(j!=SSH_MSG_KEX_DH_GEX_REPLY){
 | 
			
		||||
	System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY "+j);
 | 
			
		||||
	return false;
 | 
			
		||||
        System.err.println("type: must be SSH_MSG_KEX_DH_GEX_REPLY "+j);
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      K_S=_buf.getString();
 | 
			
		||||
@@ -212,7 +216,7 @@ public class DHGEX extends KeyExchange{
 | 
			
		||||
      i=0;
 | 
			
		||||
      j=0;
 | 
			
		||||
      j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 | 
			
		||||
	((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 | 
			
		||||
        ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 | 
			
		||||
      String alg=Util.byte2str(K_S, i, j);
 | 
			
		||||
      i+=j;
 | 
			
		||||
 | 
			
		||||
@@ -224,22 +228,10 @@ public class DHGEX extends KeyExchange{
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int getState(){return state; }
 | 
			
		||||
 | 
			
		||||
  protected int check2048(Class c, int _max) throws Exception {
 | 
			
		||||
    DH dh=(com.jcraft.jsch.DH)(c.newInstance());
 | 
			
		||||
    dh.init();
 | 
			
		||||
    byte[] foo = new byte[257];
 | 
			
		||||
    foo[1]=(byte)0xdd;
 | 
			
		||||
    foo[256]=0x73;
 | 
			
		||||
    dh.setP(foo);
 | 
			
		||||
    byte[] bar = {(byte)0x02};
 | 
			
		||||
    dh.setG(bar);
 | 
			
		||||
    try {
 | 
			
		||||
      dh.getE();
 | 
			
		||||
      _max=2048;
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){ }
 | 
			
		||||
    return _max;
 | 
			
		||||
  static boolean checkInvalidSize(int size) {
 | 
			
		||||
    return (size < 1024 || size > 8192 || size % 1024 != 0);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2006-2016 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
@@ -27,11 +27,10 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch.jgss;
 | 
			
		||||
 | 
			
		||||
import com.jcraft.jsch.JSchException;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class GSSContextKrb5 {
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHGEX1 extends DHGEX {
 | 
			
		||||
  DHGEX1(){
 | 
			
		||||
    hash="sha-1";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHGEX224 extends DHGEX {
 | 
			
		||||
  DHGEX224(){
 | 
			
		||||
    hash="sha-224";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -29,7 +29,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
public class DHGEX256 extends DHGEX {
 | 
			
		||||
class DHGEX256 extends DHGEX {
 | 
			
		||||
  DHGEX256(){
 | 
			
		||||
    hash="sha-256";
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHGEX384 extends DHGEX {
 | 
			
		||||
  DHGEX384(){
 | 
			
		||||
    hash="sha-384";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,36 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
class DHGEX512 extends DHGEX {
 | 
			
		||||
  DHGEX512(){
 | 
			
		||||
    hash="sha-512";
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,184 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2002-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
abstract class DHGN extends KeyExchange{
 | 
			
		||||
 | 
			
		||||
  private static final int SSH_MSG_KEXDH_INIT=                     30;
 | 
			
		||||
  private static final int SSH_MSG_KEXDH_REPLY=                    31;
 | 
			
		||||
 | 
			
		||||
  private int state;
 | 
			
		||||
 | 
			
		||||
  DH dh;
 | 
			
		||||
 | 
			
		||||
  byte[] V_S;
 | 
			
		||||
  byte[] V_C;
 | 
			
		||||
  byte[] I_S;
 | 
			
		||||
  byte[] I_C;
 | 
			
		||||
 | 
			
		||||
  byte[] e;
 | 
			
		||||
 | 
			
		||||
  private Buffer buf;
 | 
			
		||||
  private Packet packet;
 | 
			
		||||
 | 
			
		||||
  abstract byte[] G();
 | 
			
		||||
  abstract byte[] P();
 | 
			
		||||
  abstract String sha_name();
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void init(Session session,
 | 
			
		||||
                   byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
 | 
			
		||||
    this.V_S=V_S;      
 | 
			
		||||
    this.V_C=V_C;      
 | 
			
		||||
    this.I_S=I_S;      
 | 
			
		||||
    this.I_C=I_C;      
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class<? extends HASH> c=Class.forName(session.getConfig(sha_name())).asSubclass(HASH.class);
 | 
			
		||||
      sha=c.getDeclaredConstructor().newInstance();
 | 
			
		||||
      sha.init();
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      System.err.println(e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buf=new Buffer();
 | 
			
		||||
    packet=new Packet(buf);
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class<? extends DH> c=Class.forName(session.getConfig("dh")).asSubclass(DH.class);
 | 
			
		||||
      dh=c.getDeclaredConstructor().newInstance();
 | 
			
		||||
      dh.init();
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      //System.err.println(e);
 | 
			
		||||
      throw e;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dh.setP(P());
 | 
			
		||||
    dh.setG(G());
 | 
			
		||||
    // The client responds with:
 | 
			
		||||
    // byte  SSH_MSG_KEXDH_INIT(30)
 | 
			
		||||
    // mpint e <- g^x mod p
 | 
			
		||||
    //         x is a random number (1 < x < (p-1)/2)
 | 
			
		||||
 | 
			
		||||
    e=dh.getE();
 | 
			
		||||
    packet.reset();
 | 
			
		||||
    buf.putByte((byte)SSH_MSG_KEXDH_INIT);
 | 
			
		||||
    buf.putMPInt(e);
 | 
			
		||||
 | 
			
		||||
    if(V_S==null){  // This is a really ugly hack for Session.checkKexes ;-(
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    session.write(packet);
 | 
			
		||||
 | 
			
		||||
    if(session.getLogger().isEnabled(Logger.INFO)){
 | 
			
		||||
      session.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "SSH_MSG_KEXDH_INIT sent");
 | 
			
		||||
      session.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "expecting SSH_MSG_KEXDH_REPLY");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state=SSH_MSG_KEXDH_REPLY;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean next(Buffer _buf) throws Exception{
 | 
			
		||||
    int i,j;
 | 
			
		||||
 | 
			
		||||
    switch(state){
 | 
			
		||||
    case SSH_MSG_KEXDH_REPLY:
 | 
			
		||||
      // The server responds with:
 | 
			
		||||
      // byte      SSH_MSG_KEXDH_REPLY(31)
 | 
			
		||||
      // string    server public host key and certificates (K_S)
 | 
			
		||||
      // mpint     f
 | 
			
		||||
      // string    signature of H
 | 
			
		||||
      j=_buf.getInt();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      if(j!=31){
 | 
			
		||||
        System.err.println("type: must be 31 "+j);
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      K_S=_buf.getString();
 | 
			
		||||
 | 
			
		||||
      byte[] f=_buf.getMPInt();
 | 
			
		||||
      byte[] sig_of_H=_buf.getString();
 | 
			
		||||
 | 
			
		||||
      dh.setF(f);
 | 
			
		||||
 | 
			
		||||
      dh.checkRange();
 | 
			
		||||
 | 
			
		||||
      K=normalize(dh.getK());
 | 
			
		||||
 | 
			
		||||
      //The hash H is computed as the HASH hash of the concatenation of the
 | 
			
		||||
      //following:
 | 
			
		||||
      // string    V_C, the client's version string (CR and NL excluded)
 | 
			
		||||
      // string    V_S, the server's version string (CR and NL excluded)
 | 
			
		||||
      // string    I_C, the payload of the client's SSH_MSG_KEXINIT
 | 
			
		||||
      // string    I_S, the payload of the server's SSH_MSG_KEXINIT
 | 
			
		||||
      // string    K_S, the host key
 | 
			
		||||
      // mpint     e, exchange value sent by the client
 | 
			
		||||
      // mpint     f, exchange value sent by the server
 | 
			
		||||
      // mpint     K, the shared secret
 | 
			
		||||
      // This value is called the exchange hash, and it is used to authenti-
 | 
			
		||||
      // cate the key exchange.
 | 
			
		||||
      buf.reset();
 | 
			
		||||
      buf.putString(V_C); buf.putString(V_S);
 | 
			
		||||
      buf.putString(I_C); buf.putString(I_S);
 | 
			
		||||
      buf.putString(K_S);
 | 
			
		||||
      buf.putMPInt(e); buf.putMPInt(f);
 | 
			
		||||
      buf.putMPInt(K);
 | 
			
		||||
      byte[] foo=new byte[buf.getLength()];
 | 
			
		||||
      buf.getByte(foo);
 | 
			
		||||
      sha.update(foo, 0, foo.length);
 | 
			
		||||
      H=sha.digest();
 | 
			
		||||
      //System.err.print("H -> "); //dump(H, 0, H.length);
 | 
			
		||||
 | 
			
		||||
      i=0;
 | 
			
		||||
      j=0;
 | 
			
		||||
      j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 | 
			
		||||
        ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 | 
			
		||||
      String alg=Util.byte2str(K_S, i, j);
 | 
			
		||||
      i+=j;
 | 
			
		||||
 | 
			
		||||
      boolean result = verify(alg, K_S, i, sig_of_H);
 | 
			
		||||
 | 
			
		||||
      state=STATE_END;
 | 
			
		||||
      return result;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int getState(){return state; }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,200 @@
 | 
			
		||||
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
 | 
			
		||||
/*
 | 
			
		||||
Copyright (c) 2015-2018 ymnk, JCraft,Inc. All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
  1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
     this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
  2. Redistributions in binary form must reproduce the above copyright 
 | 
			
		||||
     notice, this list of conditions and the following disclaimer in 
 | 
			
		||||
     the documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
  3. The names of the authors may not be used to endorse or promote products
 | 
			
		||||
     derived from this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 | 
			
		||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 | 
			
		||||
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 | 
			
		||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 | 
			
		||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 | 
			
		||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
package com.jcraft.jsch;
 | 
			
		||||
 | 
			
		||||
abstract class DHXEC extends KeyExchange{
 | 
			
		||||
 | 
			
		||||
  private static final int SSH_MSG_KEX_ECDH_INIT =                 30;
 | 
			
		||||
  private static final int SSH_MSG_KEX_ECDH_REPLY=                 31;
 | 
			
		||||
  private int state;
 | 
			
		||||
 | 
			
		||||
  byte[] Q_C;
 | 
			
		||||
 | 
			
		||||
  byte[] V_S;
 | 
			
		||||
  byte[] V_C;
 | 
			
		||||
  byte[] I_S;
 | 
			
		||||
  byte[] I_C;
 | 
			
		||||
 | 
			
		||||
  byte[] e;
 | 
			
		||||
 | 
			
		||||
  private Buffer buf;
 | 
			
		||||
  private Packet packet;
 | 
			
		||||
 | 
			
		||||
  private XDH xdh;
 | 
			
		||||
 | 
			
		||||
  protected String sha_name;
 | 
			
		||||
  protected String curve_name;
 | 
			
		||||
  protected int key_len;
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public void init(Session session,
 | 
			
		||||
                   byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C) throws Exception{
 | 
			
		||||
    this.V_S=V_S;      
 | 
			
		||||
    this.V_C=V_C;      
 | 
			
		||||
    this.I_S=I_S;      
 | 
			
		||||
    this.I_C=I_C;      
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class<? extends HASH> c=Class.forName(session.getConfig(sha_name)).asSubclass(HASH.class);
 | 
			
		||||
      sha=c.getDeclaredConstructor().newInstance();
 | 
			
		||||
      sha.init();
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception e){
 | 
			
		||||
      System.err.println(e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    buf=new Buffer();
 | 
			
		||||
    packet=new Packet(buf);
 | 
			
		||||
 | 
			
		||||
    packet.reset();
 | 
			
		||||
    buf.putByte((byte)SSH_MSG_KEX_ECDH_INIT);
 | 
			
		||||
 | 
			
		||||
    try{
 | 
			
		||||
      Class<? extends XDH> c=Class.forName(session.getConfig("xdh")).asSubclass(XDH.class);
 | 
			
		||||
      xdh=c.getDeclaredConstructor().newInstance();
 | 
			
		||||
      xdh.init(curve_name, key_len);
 | 
			
		||||
 | 
			
		||||
      Q_C = xdh.getQ();
 | 
			
		||||
      buf.putString(Q_C);
 | 
			
		||||
    }
 | 
			
		||||
    catch(Exception | NoClassDefFoundError e){
 | 
			
		||||
      throw new JSchException(e.toString(), e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(V_S==null){  // This is a really ugly hack for Session.checkKexes ;-(
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    session.write(packet);
 | 
			
		||||
 | 
			
		||||
    if(session.getLogger().isEnabled(Logger.INFO)){
 | 
			
		||||
      session.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "SSH_MSG_KEX_ECDH_INIT sent");
 | 
			
		||||
      session.getLogger().log(Logger.INFO, 
 | 
			
		||||
                           "expecting SSH_MSG_KEX_ECDH_REPLY");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    state=SSH_MSG_KEX_ECDH_REPLY;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean next(Buffer _buf) throws Exception{
 | 
			
		||||
    int i,j;
 | 
			
		||||
    switch(state){
 | 
			
		||||
    case SSH_MSG_KEX_ECDH_REPLY:
 | 
			
		||||
      // The server responds with:
 | 
			
		||||
      // byte     SSH_MSG_KEX_ECDH_REPLY
 | 
			
		||||
      // string   K_S, server's public host key
 | 
			
		||||
      // string   Q_S, server's ephemeral public key octet string
 | 
			
		||||
      // string   the signature on the exchange hash
 | 
			
		||||
      j=_buf.getInt();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      j=_buf.getByte();
 | 
			
		||||
      if(j!=SSH_MSG_KEX_ECDH_REPLY){
 | 
			
		||||
        System.err.println("type: must be SSH_MSG_KEX_ECDH_REPLY "+j);
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      K_S=_buf.getString();
 | 
			
		||||
 | 
			
		||||
      byte[] Q_S=_buf.getString();
 | 
			
		||||
 | 
			
		||||
      // RFC 5656,
 | 
			
		||||
      // 4. ECDH Key Exchange
 | 
			
		||||
      //   All elliptic curve public keys MUST be validated after they are
 | 
			
		||||
      //   received.  An example of a validation algorithm can be found in
 | 
			
		||||
      //   Section 3.2.2 of [SEC1].  If a key fails validation,
 | 
			
		||||
      //   the key exchange MUST fail.
 | 
			
		||||
      if(!xdh.validate(Q_S)){
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      K = xdh.getSecret(Q_S);
 | 
			
		||||
      K=normalize(K);
 | 
			
		||||
 | 
			
		||||
      byte[] sig_of_H=_buf.getString();
 | 
			
		||||
 | 
			
		||||
      //The hash H is computed as the HASH hash of the concatenation of the
 | 
			
		||||
      //following:
 | 
			
		||||
      // string   V_C, client's identification string (CR and LF excluded)
 | 
			
		||||
      // string   V_S, server's identification string (CR and LF excluded)
 | 
			
		||||
      // string   I_C, payload of the client's SSH_MSG_KEXINIT
 | 
			
		||||
      // string   I_S, payload of the server's SSH_MSG_KEXINIT
 | 
			
		||||
      // string   K_S, server's public host key
 | 
			
		||||
      // string   Q_C, client's ephemeral public key octet string
 | 
			
		||||
      // string   Q_S, server's ephemeral public key octet string
 | 
			
		||||
      // mpint    K,   shared secret
 | 
			
		||||
 | 
			
		||||
      // This value is called the exchange hash, and it is used to authenti-
 | 
			
		||||
      // cate the key exchange.
 | 
			
		||||
      // RFC 8731,
 | 
			
		||||
      // 3.1. Shared Secret Encoding
 | 
			
		||||
      //   The shared secret, K, is defined in [RFC4253] and [RFC5656] as an
 | 
			
		||||
      //   integer encoded as a multiple precision integer (mpint).
 | 
			
		||||
      //   Curve25519/448 outputs a binary string X, which is the 32- or 56-byte
 | 
			
		||||
      //   point obtained by scalar multiplication of the other side's public
 | 
			
		||||
      //   key and the local private key scalar.  The 32 or 56 bytes of X are
 | 
			
		||||
      //   converted into K by interpreting the octets as an unsigned fixed-
 | 
			
		||||
      //   length integer encoded in network byte order.
 | 
			
		||||
      //
 | 
			
		||||
      //   The mpint K is then encoded using the process described in Section 5
 | 
			
		||||
      //   of [RFC4251], and the resulting bytes are fed as described in
 | 
			
		||||
      //   [RFC4253] to the key exchange method's hash function to generate
 | 
			
		||||
      //   encryption keys.
 | 
			
		||||
      buf.reset();
 | 
			
		||||
      buf.putString(V_C); buf.putString(V_S);
 | 
			
		||||
      buf.putString(I_C); buf.putString(I_S);
 | 
			
		||||
      buf.putString(K_S);
 | 
			
		||||
      buf.putString(Q_C); buf.putString(Q_S);
 | 
			
		||||
      buf.putMPInt(K);
 | 
			
		||||
      byte[] foo=new byte[buf.getLength()];
 | 
			
		||||
      buf.getByte(foo);
 | 
			
		||||
 | 
			
		||||
      sha.update(foo, 0, foo.length);
 | 
			
		||||
      H=sha.digest();
 | 
			
		||||
 | 
			
		||||
      i=0;
 | 
			
		||||
      j=0;
 | 
			
		||||
      j=((K_S[i++]<<24)&0xff000000)|((K_S[i++]<<16)&0x00ff0000)|
 | 
			
		||||
        ((K_S[i++]<<8)&0x0000ff00)|((K_S[i++])&0x000000ff);
 | 
			
		||||
      String alg=Util.byte2str(K_S, i, j);
 | 
			
		||||
      i+=j;
 | 
			
		||||
 | 
			
		||||
      boolean result = verify(alg, K_S, i, sig_of_H);
 | 
			
		||||
 | 
			
		||||
      state=STATE_END;
 | 
			
		||||
      return result;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int getState(){return state; }
 | 
			
		||||
}
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user