mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
Compare commits
1143 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 930facc457 | |||
| 5a428458b5 | |||
| fa12c90f23 | |||
| 2e16ccb041 | |||
| df7dda0e96 | |||
| 28c86b4784 | |||
| 175a4ddf95 | |||
| e4b24b0d99 | |||
| 989fcd9564 | |||
| 4877ef1407 | |||
| c1487e3f74 | |||
| 6d4650bba9 | |||
| fb6f02696d | |||
| 8ed4abebb7 | |||
| f90de9c0de | |||
| 206d2a58d2 | |||
| 6001d2fb3a | |||
| 1ceab73dfe | |||
| dc38b949a8 | |||
| 96b740d4da | |||
| 1455f7849b | |||
| 7f14a4da90 | |||
| 0d04064969 | |||
| 37fbda3126 | |||
| 023e62fbd4 | |||
| b818007398 | |||
| 7c1bb82dd4 | |||
| e3a6fa4cac | |||
| 6e6aa88b3a | |||
| c266bd6eba | |||
| e383c2b79a | |||
| 56a5b23d98 | |||
| 10eb41aca7 | |||
| a0a50e3433 | |||
| 07449e9018 | |||
| 5027373b54 | |||
| 1d1e08fc15 | |||
| 6eabf32464 | |||
| acb4a2e5a0 | |||
| ba1b5211a2 | |||
| eb8d248fd9 | |||
| f248a86ce2 | |||
| 8e9b55958d | |||
| 6decd0ee76 | |||
| 16384c12c2 | |||
| 9be5c50e31 | |||
| 46421d8821 | |||
| 13cb356aef | |||
| b210b72460 | |||
| 6aa63f48e1 | |||
| eaba4a4ab7 | |||
| fbc61bce2a | |||
| 5c98e34966 | |||
| 9b461d372d | |||
| b57a81c7c2 | |||
| 7cf41805ec | |||
| 59efa059fd | |||
| e462d66746 | |||
| cd0c3f533a | |||
| 0027b17ef9 | |||
| 9ee5325f29 | |||
| ac433edcf8 | |||
| f71e7e58e1 | |||
| 4af1e9263a | |||
| 01d3a75faa | |||
| d015ab4e93 | |||
| abcf3600a6 | |||
| ac6c497721 | |||
| 2dafecc665 | |||
| 3a48f0a04a | |||
| 1caf3a8956 | |||
| ba1dd07b01 | |||
| 695a97276f | |||
| 0d50753754 | |||
| e357786980 | |||
| 54ab0ba860 | |||
| 44675fffe5 | |||
| e5c6fb0e50 | |||
| 82666fb5f0 | |||
| 9ab86ca310 | |||
| 7153b4c7be | |||
| e73f4f30cb | |||
| e365a20d6e | |||
| 4a9f9eefd2 | |||
| 2ff632bb87 | |||
| f5be0708be | |||
| 92908ab673 | |||
| c20f8699f3 | |||
| 81e60a3916 | |||
| 4f8e25a6c0 | |||
| 4038088c5f | |||
| bc972faf2a | |||
| 0720fec295 | |||
| fba37c7c12 | |||
| debaa48e58 | |||
| c4a63657cd | |||
| a723783c01 | |||
| 26a922e16a | |||
| 9a20d33d55 | |||
| 3abe9946d4 | |||
| dcf4857b6e | |||
| 701ae43bd6 | |||
| cb67d0a45b | |||
| 1684bc3acc | |||
| ee32ef2f09 | |||
| c9ed86a81a | |||
| 8421e85229 | |||
| 0b2eead1be | |||
| 0d30d4a4f3 | |||
| ac55638e46 | |||
| e57c45da71 | |||
| 4b93e2e57c | |||
| 2bab5a65f4 | |||
| 66f379f80b | |||
| 4a8749349f | |||
| 54fe2accb6 | |||
| ec21b57106 | |||
| 9e62523b6d | |||
| 2b69ba5716 | |||
| dadfecf8f3 | |||
| e5695194d5 | |||
| e1c192ddd3 | |||
| ee5e6cb125 | |||
| 5ca9bbff28 | |||
| 1761335092 | |||
| b87e135b3c | |||
| c1154a87cc | |||
| a683880f7e | |||
| 23acff2a87 | |||
| 484d723c75 | |||
| ecab439d0a | |||
| d02732c16d | |||
| f55106612c | |||
| efde505eb5 | |||
| 7ae296dcac | |||
| 8a20f439c0 | |||
| 57a8251313 | |||
| 6039a4e6b1 | |||
| ea59519c09 | |||
| 84e7345607 | |||
| 4357817faf | |||
| fb4f378b86 | |||
| ee081b3037 | |||
| 33d3d92f62 | |||
| 9ba8659536 | |||
| 3c14d32e19 | |||
| 6cb866233b | |||
| e98bffdacc | |||
| 96400768b5 | |||
| dd8474cecf | |||
| 7b98265a2a | |||
| 03a20c26db | |||
| fd0731c52a | |||
| 7856fb22e4 | |||
| d38a4535bb | |||
| 757ad7266f | |||
| da8274de1b | |||
| 22bd12cfd6 | |||
| 6d868cb541 | |||
| ca2ad6fa68 | |||
| 718dd6d1a9 | |||
| b4db0d7d70 | |||
| 0de45907ff | |||
| 9fbc3773b6 | |||
| 4707d43e84 | |||
| dabae2d63a | |||
| 3c9204da0f | |||
| 4b11524fcf | |||
| 7a8c279e4f | |||
| b3708d1bd4 | |||
| 3ffb476aa9 | |||
| 7641975cc6 | |||
| dbc23af348 | |||
| dac8dbd330 | |||
| a47dd34500 | |||
| b160d1b1e9 | |||
| 90d5c4fd2c | |||
| 3311bb56e4 | |||
| d6ff7e4480 | |||
| b7ea939ac7 | |||
| 46a2930fa0 | |||
| e8c6309e93 | |||
| b9a72db110 | |||
| a6d8d0e3b6 | |||
| a7a7e66bb8 | |||
| a2ad1d35e7 | |||
| dd16cc7d89 | |||
| 9673ec1a96 | |||
| 8d8c9b808b | |||
| d379d66751 | |||
| f44989a18d | |||
| 7a5b880a7a | |||
| c859e9bf70 | |||
| 6e4361d129 | |||
| e5cd1be194 | |||
| 5a3faba0a3 | |||
| 0b15b5b55f | |||
| ecd06e4b0f | |||
| 8bf5d98d04 | |||
| b73b1e430e | |||
| 563ec61d52 | |||
| ba02fae57f | |||
| 5c61abe256 | |||
| 0d93f9a678 | |||
| bff79e1c34 | |||
| 68db96483c | |||
| 2bdf88373d | |||
| cdb43876bf | |||
| 6f1cecdaa9 | |||
| 363d78d61c | |||
| 02d9258c9c | |||
| 8a567c63b1 | |||
| 880139b1ff | |||
| a8450cc826 | |||
| 82aac5d383 | |||
| a24c14ef62 | |||
| 902702ee01 | |||
| 9d653a3607 | |||
| bee770bd2e | |||
| 3e77ae505d | |||
| 66b7a447ca | |||
| 3eded4d59b | |||
| 7682caffb6 | |||
| df980b266a | |||
| 99d2afc642 | |||
| 5e44aab51f | |||
| cf14685ab3 | |||
| bcd22c50d3 | |||
| 5f9bfbef99 | |||
| b6f04755a0 | |||
| d32b773a80 | |||
| 74a68eaf18 | |||
| bf0520ea65 | |||
| a20f194c0a | |||
| f16a905143 | |||
| cbe19df41a | |||
| 58d7b5d283 | |||
| e7e3807b9e | |||
| 1aec5e253d | |||
| 671d69c89a | |||
| 55042edf52 | |||
| 8e5d8297ca | |||
| 0c73ef776f | |||
| 7bec0dc4b9 | |||
| 5373602a60 | |||
| 95060abc6b | |||
| 5046005b0e | |||
| 576a9fde5b | |||
| 46463f13c6 | |||
| 35c8fb2399 | |||
| 8cda23ccaf | |||
| f7831cc6a0 | |||
| 2be0a78f6f | |||
| b505d9b020 | |||
| 9320d992b5 | |||
| c9f81e447a | |||
| 9d5edba4aa | |||
| f689b2fb94 | |||
| 0c22f40bf0 | |||
| 8957823dae | |||
| 243ec39eb8 | |||
| 529435316a | |||
| f541fd668b | |||
| ec29371d3f | |||
| 1add172770 | |||
| 37f401f2cd | |||
| f88c8231eb | |||
| 04b318f753 | |||
| 2af0e1ffb6 | |||
| 806ed69432 | |||
| 491e5e0190 | |||
| 93d9d053ee | |||
| 58de8d2830 | |||
| 6d26bbd3fb | |||
| e7c432e0de | |||
| 8c00d6e09e | |||
| 310d8f79bc | |||
| 8127e3427e | |||
| 4a12b055e7 | |||
| de7c71931c | |||
| 5a6fc7761c | |||
| 7410cb21a0 | |||
| 99d4142c13 | |||
| 27de528e57 | |||
| 521360f667 | |||
| 4e003ec6f5 | |||
| 98c8a0c550 | |||
| 039eb0d924 | |||
| e7636cee4e | |||
| 4b844ebb71 | |||
| c704ed4898 | |||
| ada4ef461e | |||
| 8dd4193f4e | |||
| 704d6f0516 | |||
| 097f3e8149 | |||
| 9d8988b08b | |||
| 0dcdc2d0bf | |||
| 83ed86575e | |||
| 40e7b08238 | |||
| 0ac7648bd6 | |||
| 41f1233a27 | |||
| 0bba3d94c7 | |||
| 67c5b1a281 | |||
| dbf6c98ddb | |||
| af666374ea | |||
| 45d10ab435 | |||
| 602ad36e6f | |||
| 6fc3c38b28 | |||
| a0e2aed195 | |||
| 9aff89ea9a | |||
| 60a8ab9bcf | |||
| 0d21883546 | |||
| 9fde45d272 | |||
| 61c15ea56d | |||
| d821e43fe9 | |||
| 03e5ee1098 | |||
| 646b2f028c | |||
| 794bdeafce | |||
| bd4d3b3e11 | |||
| 58c8cecee8 | |||
| 801406ce58 | |||
| 20a93a30b3 | |||
| 38d3c6c634 | |||
| 43bf4a4616 | |||
| 059edeaf18 | |||
| e1e9462fb1 | |||
| 125e70c04b | |||
| e4fc9502fe | |||
| 72a6627059 | |||
| 73cf5105dd | |||
| c69e128e83 | |||
| fcb037122d | |||
| 7eab23aa19 | |||
| 4d839e40ca | |||
| 7a06e3ac0c | |||
| 8392c34f65 | |||
| 67b8486b99 | |||
| 308018e6e6 | |||
| 6c625d078f | |||
| a69afe11f4 | |||
| 4ff15e433b | |||
| 6c81d03c50 | |||
| 9f0b322249 | |||
| e8831b0dfc | |||
| d6e9ba2ea9 | |||
| 2c8c5a7558 | |||
| d2e76a5e61 | |||
| 2263c24019 | |||
| 19e414e65c | |||
| f5a52c1aa2 | |||
| 1cf5039c81 | |||
| 90a5e39872 | |||
| 30868b107e | |||
| 546d4a3bda | |||
| 33eaf71e5b | |||
| a61e73b91b | |||
| f03a3a9b50 | |||
| e2225be331 | |||
| f1f23a5099 | |||
| db3bcb017c | |||
| ab0ce1393e | |||
| b941b9e21a | |||
| b838e0d69e | |||
| 8459f5552d | |||
| 293d249024 | |||
| 38a39aec17 | |||
| f4fb855cb6 | |||
| 8fa34e8659 | |||
| eb2f2de29c | |||
| 1b2c5a028a | |||
| 4057c08df9 | |||
| 074d2054ec | |||
| cf2ea4cc56 | |||
| cff6b6bba7 | |||
| 595111fb56 | |||
| cfc0485579 | |||
| 7e7d4176f2 | |||
| 8abaa7bc02 | |||
| 714e079b17 | |||
| 6983491586 | |||
| 2cea64ccff | |||
| 0ef81716c5 | |||
| c780ddf081 | |||
| 30b778c4f6 | |||
| 5e0c7553e2 | |||
| b5fe0acd89 | |||
| 01551fe71a | |||
| edd4176890 | |||
| f4f27ac0ae | |||
| aeb297548c | |||
| eb3aa46ff7 | |||
| 05fbf5bdce | |||
| 8a5f05fe2e | |||
| 590841d139 | |||
| 44caf01cae | |||
| db36341251 | |||
| 0a63816ece | |||
| ceb0155f5f | |||
| 723e677b2b | |||
| fab24ee956 | |||
| 94f4c8b302 | |||
| 008a2410a7 | |||
| b43f337af9 | |||
| 21895cf00f | |||
| 721d016d86 | |||
| 89aaa9c072 | |||
| bcb00a9d23 | |||
| 34cd40fdd9 | |||
| c8001cedce | |||
| 880353888b | |||
| 2c67d20233 | |||
| 42c08a4d5b | |||
| 01bf0f3af5 | |||
| e765968c2c | |||
| 3837463e41 | |||
| 545a2ddc24 | |||
| 4f6f0b4685 | |||
| 1d1bad8b3b | |||
| af5769f231 | |||
| 42c6337c4d | |||
| 37a49c9d39 | |||
| 3b2f778114 | |||
| b55cc03f6d | |||
| 2e6eead045 | |||
| e77c3303a1 | |||
| e83c4f315c | |||
| 833c75d874 | |||
| 9688003648 | |||
| a2609d5bbe | |||
| 227f129455 | |||
| 4e683e5b37 | |||
| c5a0a00dd8 | |||
| de0bce163f | |||
| 9dcb58c1ea | |||
| 4729642f87 | |||
| 751cbfa635 | |||
| e40cae149b | |||
| 758dfbaa67 | |||
| 29ec49b806 | |||
| 8afb5595d0 | |||
| 8430e9ddc6 | |||
| 7439fafe2b | |||
| e1655a40bd | |||
| 92fc521d5b | |||
| 023d34f2b6 | |||
| 8fc064a5a4 | |||
| b9a329f416 | |||
| 4997fa7301 | |||
| e267d67d6e | |||
| 83b04a97ef | |||
| 7852c9e9f9 | |||
| 009adc09bc | |||
| 4d3929576d | |||
| 7712def225 | |||
| 9509919431 | |||
| 15cc62f559 | |||
| ae46cbbf5e | |||
| 1664fcdc84 | |||
| 2c45f4af37 | |||
| b3d1747c0b | |||
| 693952d0eb | |||
| 0ad5bd6e48 | |||
| 89c34f89c9 | |||
| 70971a73ad | |||
| 2c5b377712 | |||
| ae4b5a711b | |||
| 252bc52d47 | |||
| 655783db1e | |||
| 10b2af3656 | |||
| 54c3a963a4 | |||
| a7836eaded | |||
| 10fcbdc81d | |||
| b2a5885787 | |||
| 9886a4feb4 | |||
| dcd04f7064 | |||
| 5773ce8b83 | |||
| 0c3eb19de6 | |||
| 5e72e30d58 | |||
| c9d8ad3d4a | |||
| 62bd4f6d9f | |||
| 15e1d55a77 | |||
| 04cab2ee0c | |||
| fd28868ea8 | |||
| 129e6ad487 | |||
| 082f7229f2 | |||
| 1c6001ed92 | |||
| 2ec48ef1e6 | |||
| 04397f3cb0 | |||
| 8697756083 | |||
| 7be5ec589c | |||
| d3fbf529eb | |||
| e47818b5df | |||
| 201c9ebf4c | |||
| 0626192659 | |||
| 0acdd3f885 | |||
| 6f0fd1072d | |||
| d17579b928 | |||
| 090039ec29 | |||
| df8bbcd00a | |||
| fffc77cc82 | |||
| 9ee5af9fd2 | |||
| 5462f3d341 | |||
| 46dca0d212 | |||
| 603572c796 | |||
| db6c2d9d7c | |||
| b6c6375492 | |||
| 3f5255c116 | |||
| 68f3974aa2 | |||
| 2c062d8d51 | |||
| 1097157f69 | |||
| 21784aa951 | |||
| f980f7285a | |||
| 622b6bc786 | |||
| 61fc0485b7 | |||
| be2af9c871 | |||
| 898e4a45e3 | |||
| e47c6406f8 | |||
| 1d0ed83bad | |||
| 404f6ea9da | |||
| 8d75f867fd | |||
| 83f60e6252 | |||
| c4bd6576d8 | |||
| 12df911162 | |||
| f5a37ee185 | |||
| 92d71ad150 | |||
| 8824b30c4a | |||
| 741e281a37 | |||
| 354295ae7a | |||
| 09af0640c7 | |||
| 1485eeecf6 | |||
| 8b78df6a14 | |||
| 686ee6c246 | |||
| ca8114d9af | |||
| b2392c90c2 | |||
| d207fa67e5 | |||
| 2e41fe756a | |||
| d533ea5c37 | |||
| 4365e176d8 | |||
| 486b03e031 | |||
| 1dbf08327c | |||
| 0d15bb3544 | |||
| e3b48206e9 | |||
| a0e364a50f | |||
| 0db3fc55c6 | |||
| 95c3fca389 | |||
| 68a72fb8fd | |||
| 473410ece2 | |||
| 4f760a790a | |||
| ad7ee4428f | |||
| 92cf756ad2 | |||
| 3d746f08ba | |||
| e272459fc9 | |||
| a793ae52f9 | |||
| f2349a9bdd | |||
| 7082798c03 | |||
| f4fc5fae2b | |||
| 5799e43b3a | |||
| f929d6cc31 | |||
| 9f92efc554 | |||
| 3338b83910 | |||
| a4c104431d | |||
| 31ba521244 | |||
| 50dfe15f09 | |||
| 4b06d19787 | |||
| 66d147eb8b | |||
| d2591922a6 | |||
| bcc6f79373 | |||
| 015edd6053 | |||
| bec562bfb2 | |||
| 01a7c93771 | |||
| 502bae625f | |||
| a34d511922 | |||
| e65aa19109 | |||
| 30585b8de4 | |||
| 0bd4234214 | |||
| db4ceb6d68 | |||
| 1612a5d7cd | |||
| f60f4539b5 | |||
| db7c8a9dfc | |||
| 9d1f4266c2 | |||
| 0614c4fc32 | |||
| 58e452b711 | |||
| b478696bed | |||
| f3584d9eaf | |||
| d9998167f4 | |||
| 874e300220 | |||
| 49e4b90cc3 | |||
| f492f2cd71 | |||
| 2800a282ec | |||
| 593e93304c | |||
| 77b6108ca8 | |||
| 90bf2b6b19 | |||
| dd91d52df4 | |||
| de29317fa6 | |||
| 44faee6208 | |||
| 41ccf19e58 | |||
| 05c390980a | |||
| 4446ed0792 | |||
| 11942da0c0 | |||
| 9a0604a1a8 | |||
| 93ca874e61 | |||
| 9ba21c4346 | |||
| c0e7798cad | |||
| 0aea5a2201 | |||
| 63873ec1d5 | |||
| 23f269d4b3 | |||
| 9ebacb23c4 | |||
| d1e83f46d8 | |||
| 5f2dd23a6e | |||
| d29b24e9a6 | |||
| 4f1415e127 | |||
| c604313c09 | |||
| e6bc14a8de | |||
| 4a5729d371 | |||
| d9ac76a317 | |||
| 867df35d44 | |||
| e946d61b92 | |||
| fa2ffbd70f | |||
| 1123f03134 | |||
| 49e86d08bf | |||
| 5f00826e65 | |||
| 82382f31f1 | |||
| 833cbf7302 | |||
| 4e329adaca | |||
| dbc9e4c3c2 | |||
| d9cff40fd5 | |||
| ef248712d6 | |||
| 9765ba1bac | |||
| afcccaa864 | |||
| 7caef2ceb9 | |||
| cb4480ad78 | |||
| 6388349c16 | |||
| 73a111aeac | |||
| 5869bdc9dd | |||
| ff7f75abed | |||
| 28ac3bd9eb | |||
| 49f07874f8 | |||
| 59779b7f2a | |||
| 677df359ae | |||
| 4e4aca675f | |||
| 76163e6012 | |||
| 85b319825d | |||
| 8edf8a6140 | |||
| acba74142c | |||
| c06f34923e | |||
| bb00342b5d | |||
| 25b43986d3 | |||
| 9b5984182f | |||
| ae9dfb1595 | |||
| 001a4a8675 | |||
| 13a1e92321 | |||
| fb97c8edaf | |||
| ffce59ea7e | |||
| dd7ef2d744 | |||
| a76f840368 | |||
| c4bac7359b | |||
| 67e028502d | |||
| e05b31a76b | |||
| d1b95e369d | |||
| 64a71f25f2 | |||
| 76e906579b | |||
| 23dc66622b | |||
| 997bbd336c | |||
| d8a0225b1a | |||
| ce656ca374 | |||
| dd202b4c72 | |||
| 522ff32432 | |||
| a96cb520dd | |||
| fe9cd52312 | |||
| d4355ad076 | |||
| 057d0eb39e | |||
| 82f35621e2 | |||
| 633856b350 | |||
| 1c0c9004c6 | |||
| 833533adc3 | |||
| 846df6a164 | |||
| f5de9e8a23 | |||
| 404a0ca032 | |||
| 6e8612172b | |||
| aed9e39287 | |||
| 597100d9e3 | |||
| b2775e0811 | |||
| 2425f0dcc7 | |||
| ede60340f6 | |||
| a9d58ab3f3 | |||
| 6d6b6f41c9 | |||
| f5f97e4bfc | |||
| c7ed50a225 | |||
| f843c531b4 | |||
| 2389a7d136 | |||
| e1d0306a29 | |||
| 04cbe3f825 | |||
| 9796ac1c53 | |||
| 5721b9f86d | |||
| aa090a9cd4 | |||
| 03c30bef47 | |||
| c59453f31b | |||
| 49e7f19cb7 | |||
| 469c56f1a6 | |||
| 239c56e77d | |||
| e32ca20604 | |||
| d00ef0af32 | |||
| e616e57be6 | |||
| 5485db8509 | |||
| df75d2917f | |||
| 0478ea5162 | |||
| 433e90072f | |||
| 5c646ea663 | |||
| e095d3f886 | |||
| 9a6315d0b2 | |||
| 8e81f0bb8f | |||
| d6bdebc865 | |||
| 7ddf368fd1 | |||
| 301c6a4430 | |||
| adaf91e383 | |||
| 40de9dfe98 | |||
| 18a8e2358c | |||
| e2a4008742 | |||
| 258633b672 | |||
| 96cc35b84d | |||
| 787efa3c5d | |||
| 848862ae84 | |||
| 6d3c170e96 | |||
| a921523014 | |||
| 29e5133c63 | |||
| 8d4aebe8e7 | |||
| c0139b1b49 | |||
| 920d55ee6d | |||
| 4348b80b02 | |||
| 1a62ed853b | |||
| f858cc7747 | |||
| 394b439a06 | |||
| b515660bac | |||
| 88719df0af | |||
| 495dfa0f59 | |||
| f7372819a1 | |||
| 9d622ecef7 | |||
| 221004354e | |||
| 442baa6aa9 | |||
| 2e4f748093 | |||
| 56a846ab3b | |||
| f67e24b49e | |||
| f40a3e49cb | |||
| 04b815bb49 | |||
| 3292979696 | |||
| 3e24ca9be1 | |||
| 38e5350219 | |||
| 39d5c40945 | |||
| ebcb132acf | |||
| 53447c793a | |||
| 54a2df818b | |||
| 09a3b3bd26 | |||
| f02d4cd21a | |||
| eb650ff089 | |||
| da263b1e56 | |||
| 44ee4aaef7 | |||
| 56874bd418 | |||
| bf1594fdef | |||
| e31821cf92 | |||
| 4efe3b4387 | |||
| 69d0537425 | |||
| 0852e09815 | |||
| 2fc8799241 | |||
| ea01205421 | |||
| 1ad31aa178 | |||
| 349b943a7e | |||
| 268006d027 | |||
| e2bad18153 | |||
| 4749ddf9a8 | |||
| de1c568714 | |||
| 0b90e66ad8 | |||
| 90fe75a764 | |||
| c27fd27789 | |||
| 5580f5ae62 | |||
| d4e94b2fbc | |||
| bb673dd992 | |||
| 2dfacc4858 | |||
| cce4e31b0f | |||
| 99615999b8 | |||
| cfca25d65d | |||
| 665a2cdfd0 | |||
| a2768728d3 | |||
| 2790082705 | |||
| ae8a15d524 | |||
| e39d7b5d4d | |||
| 1ae26ecfa5 | |||
| 1e58912226 | |||
| 87807db64a | |||
| 6221c97283 | |||
| 80226717b6 | |||
| 959f7af2ab | |||
| 2308990661 | |||
| 9f304f372a | |||
| 341580191f | |||
| 07065676f2 | |||
| 47c9dc6e31 | |||
| 2514494d02 | |||
| 1c28c2d475 | |||
| 41a92d56c4 | |||
| 6a6b024314 | |||
| 12c95971a2 | |||
| 62ca3b6331 | |||
| c69f2fd75d | |||
| 0fc45bc57a | |||
| 0b9614f0bd | |||
| e8a073a42c | |||
| 97b33ec9c4 | |||
| f6458870ae | |||
| 665f24db1e | |||
| a59be9d2af | |||
| 1036139cb7 | |||
| f1854e46be | |||
| bfad3e57c7 | |||
| 24ee24325b | |||
| c9f6db312f | |||
| 6f60ba113e | |||
| db112b226e | |||
| a87049e443 | |||
| 730b018b45 | |||
| 60e72f14d8 | |||
| e89b2855ce | |||
| 56fb73088e | |||
| 6623513c2a | |||
| 3da3325c9b | |||
| c73d3564d4 | |||
| 2b822ecd22 | |||
| a81c921504 | |||
| c902044cc3 | |||
| 072945b237 | |||
| ca49e9899d | |||
| f67d82452b | |||
| 1c3b7ce051 | |||
| cd6d8114ad | |||
| 1baa5a5d99 | |||
| a83dac9437 | |||
| e033c04d7a | |||
| bbd06d37da | |||
| 70b900649e | |||
| ed442de0a4 | |||
| b9d5d11b2b | |||
| 04b12852ba | |||
| 88f57b0e4a | |||
| 9294f3109b | |||
| 2c5c7b00cf | |||
| cf5cab6695 | |||
| c9837c662d | |||
| 27a1621f3a | |||
| 96184c3820 | |||
| aba8908254 | |||
| 87634aa557 | |||
| 769e4999d3 | |||
| 153a113744 | |||
| 7fc0776d50 | |||
| c00397319f | |||
| 09746d3f59 | |||
| 16cc42e0db | |||
| c040c68993 | |||
| a020aa8784 | |||
| ebc1156ac7 | |||
| 67cfd2f404 | |||
| 0ab5b1edbe | |||
| 3bfaa53a80 | |||
| 1e21f2bc8b | |||
| 4f6c374597 | |||
| b2714a195f | |||
| b9c1682c58 | |||
| d948bd023c | |||
| 84e4efd272 | |||
| 0ed6a36313 | |||
| c680cae29e | |||
| 5a370ae9d6 | |||
| c8786a07a1 | |||
| c73aef26ae | |||
| fe39b96ecb | |||
| 956486b7e5 | |||
| 08739fa84b | |||
| 866386626b | |||
| b8b59649fb | |||
| aa4fb45888 | |||
| effef5f8ad | |||
| 0dc14116ea | |||
| fd8fc6ab97 | |||
| e168efdfb0 | |||
| 6f04bf76fd | |||
| e5b28ee295 | |||
| 410263850a | |||
| 4a03bfab10 | |||
| 73c43fc187 | |||
| 00ed215b39 | |||
| 8fa6424f65 | |||
| 4e7e6c576e | |||
| d5ada8f400 | |||
| 0648c02ff7 | |||
| 87a7c5536d | |||
| b5f43cd600 | |||
| 71443b4259 | |||
| 7f930d2e34 | |||
| 7a99b655ec | |||
| 48706db16f | |||
| a6100265bf | |||
| 903d78ab5a | |||
| fc7f7228b6 | |||
| 489ac39ce8 | |||
| aaa41ba3b3 | |||
| 204002c1a0 | |||
| 1f68c5b9fe | |||
| 2d5ca636e7 | |||
| 84dd95261b | |||
| a0b4a0e063 | |||
| 415e6b1522 | |||
| 5da2e530e9 | |||
| e2c3919cab | |||
| 4071cf3505 | |||
| 11fdad2ea7 | |||
| ad095058d5 | |||
| 1df6a36f0a | |||
| 162848d8bc | |||
| 0b835f8019 | |||
| 9568520f9a | |||
| 3b37d11337 | |||
| 6d20fde551 | |||
| cb21c6be20 | |||
| 3894220d4c | |||
| 46e77369ee | |||
| 9076770970 | |||
| c156a82675 | |||
| 299f248e68 | |||
| 886c341c6c | |||
| 1f810f871b | |||
| 774d18de46 | |||
| c8f1c82fa9 | |||
| b4a92a0d89 | |||
| 1c9fd7fdad | |||
| 93eda8922c | |||
| d904ee6fff | |||
| 45cdc07e66 | |||
| d9abe7d205 | |||
| 41ff097bb8 | |||
| d1d38b64e2 | |||
| 6f1d364d1d | |||
| 9f07a0cba6 | |||
| fa1bc43159 | |||
| f64354f8e6 | |||
| 7fcb42d501 | |||
| 8b073bbe14 | |||
| a61d1745ef | |||
| 41d87f8216 | |||
| 83aff33b9c | |||
| 4c878fbd5f | |||
| 9bd482418c | |||
| 9bebfb8d45 | |||
| dd78d9983a | |||
| 4892939590 | |||
| a63eec5be4 | |||
| 55e44cd7cb | |||
| 013c1d9500 | |||
| b070569319 | |||
| 597ed72148 | |||
| 0b7af33179 | |||
| 1b3a7c3d21 | |||
| a295f4ceb3 | |||
| 47749306c0 | |||
| fc3cb18d0f | |||
| 5095369a36 | |||
| ba56e863f3 | |||
| 7cbe2afc11 | |||
| a7886e4a3b | |||
| b140a36bbf | |||
| d4fc09d257 | |||
| 008c87c5b1 | |||
| f043f7657a | |||
| a2971cc90e | |||
| 069473dc82 | |||
| 1781de6ea0 | |||
| 1583bfb733 | |||
| 5b972d94b7 | |||
| 34ed968d4f | |||
| 587e0e5dc3 | |||
| ba60c63b1d | |||
| ba8d919c68 | |||
| 562d0baf8d | |||
| fdd1a833ce | |||
| b6711aa619 | |||
| 57fff2105a | |||
| 5f6e4c188f | |||
| 02fcbc241e | |||
| 0043ee5886 | |||
| 100e155b75 | |||
| cf5871c663 | |||
| f465462af1 | |||
| d3a30c29fb | |||
| cc4a68a36d | |||
| 95fee7ec90 | |||
| aadd691360 | |||
| 435801c8f7 | |||
| b95eae5de1 | |||
| 9c30cabd27 | |||
| 94b9211369 | |||
| eca0922214 | |||
| a435a7a36c | |||
| 6ca5250eaa | |||
| 73e640048c | |||
| 505d5fa35f | |||
| 37e0a54cce | |||
| 01284f999f | |||
| ce1a4e1bf5 | |||
| db35ebb718 | |||
| a37503d616 | |||
| a7cd693fb6 | |||
| 5739c0cc22 | |||
| fe2bb72fb2 | |||
| 917dd3c39c | |||
| b37a529612 | |||
| 2320c482e7 | |||
| f41cd9bd66 | |||
| e271d67718 | |||
| c55adf3383 | |||
| e4368041a4 | |||
| 3c780075da | |||
| 9eb72cba9d | |||
| 36718c9323 | |||
| 3956623de2 | |||
| 192324f558 | |||
| a445cde227 | |||
| e7b6425dbd | |||
| 14a44ad0ab | |||
| 6557ef65e8 | |||
| 02aba06903 | |||
| cd8239df87 | |||
| 888352a1f0 | |||
| 279d12ac9b | |||
| fb6d35bc15 | |||
| d0c1195651 | |||
| a223818c91 | |||
| 665aa24334 | |||
| 817cdfcb03 | |||
| 036cf970f5 | |||
| 2604f04afa | |||
| 111d94c868 | |||
| 126ae5beb4 | |||
| be8b4db8bc | |||
| 6039bb4358 | |||
| 176f0deccd | |||
| 47261f0aa3 | |||
| dbb0da1222 | |||
| a5013a26b1 | |||
| 0a07ab4e75 | |||
| f1a2ce031a | |||
| a6ee565e35 | |||
| 7b488485fc | |||
| b37f82b693 | |||
| e98464a936 | |||
| ebc4e124cb | |||
| 1ca258ba1f | |||
| 01c855cf15 | |||
| 01d81dcf08 | |||
| a702b514b6 | |||
| f32bf11d22 | |||
| 453a3f4298 | |||
| 8971202db1 | |||
| fd66227c01 | |||
| c1486faa17 | |||
| 261530d671 | |||
| d1b2057415 | |||
| 83d2bf89fb | |||
| a4c8e60509 | |||
| cce872f55d | |||
| a1b7ff9c9c | |||
| fb3e2b5a5a | |||
| ec9acc9db6 | |||
| 253abf72e9 | |||
| 9072756695 | |||
| e8f1f66232 | |||
| 7b27db56c9 | |||
| a626ec2fc7 | |||
| e55fa36251 | |||
| fbc75abd45 | |||
| 12cbce4252 | |||
| 4c686bb278 | |||
| 55ebcfe8c1 | |||
| bd89a0ab72 | |||
| 887803e377 | |||
| ad88d475d8 | |||
| 0a826ea93c | |||
| 248a302a29 | |||
| 8ad1809b65 | |||
| 1eaf64f46a | |||
| fd989d6f48 | |||
| 444bbd6cbb | |||
| b8cc25fa96 | |||
| 611d51f7f7 | |||
| 5babc3d512 | |||
| 37b1f06f00 | |||
| 239f7b7e0f | |||
| 0d74177abe | |||
| 45517f0042 | |||
| 976b117cdc | |||
| ce7287089e | |||
| b3d0e11d5a | |||
| 3ff5457f5b | |||
| fff8efbcf2 | |||
| c4ac763317 | |||
| fcd61b5f0f | |||
| 2d1e3e680f | |||
| fadd32f371 | |||
| 964f8d2c16 | |||
| 702348ed58 | |||
| 24416f4a12 | |||
| a91c9544fb | |||
| bd95545eb0 | |||
| 2e5334eca7 | |||
| d86f4b7cc0 | |||
| 5d7da66d8b | |||
| b042b46544 | |||
| c852ed93ed | |||
| 4f06104f05 | |||
| 36773ecd96 | |||
| 1726a0991d | |||
| e8284afbfa | |||
| 7e8a543c35 | |||
| b9d3f2a553 | |||
| 3c0ff01d9b | |||
| c6e013057e | |||
| d1a7969101 | |||
| c35e9d2839 | |||
| 13f16ab7ad | |||
| 2e03fa5f77 | |||
| 8e750d348b | |||
| d6bf6293f2 | |||
| 34aca7ae9b | |||
| 7b92b73834 | |||
| ca827fa6b6 | |||
| c67b325a25 | |||
| b91306bd34 | |||
| a2c4a181e5 | |||
| cd5e7325cd | |||
| a785f18f99 | |||
| 19569142fe | |||
| 8ac000e1ef | |||
| eedef1a532 | |||
| e836e98833 | |||
| 0e42061f4a | |||
| 51c92ff0b3 |
@@ -1,24 +0,0 @@
|
||||
# EditorConfig (https://editorconfig.org/)
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
insert_final_newline = true
|
||||
|
||||
[*.java]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.c]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.gradle]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.sh]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
@@ -1 +0,0 @@
|
||||
*.ai binary
|
||||
@@ -1,3 +0,0 @@
|
||||
ko_fi: adbenitez
|
||||
liberapay: adbenitez
|
||||
custom: "https://arcanechat.me/#contribute"
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report something that isn't working.
|
||||
title: ''
|
||||
assignees: ''
|
||||
labels: bug
|
||||
---
|
||||
|
||||
<!--
|
||||
Please fill out as much of this form as you can (leaving out stuff that is not applicable is ok).
|
||||
-->
|
||||
|
||||
- Android version:
|
||||
- Device:
|
||||
- ArcaneChat version:
|
||||
- Expected behavior:
|
||||
- Actual behavior:
|
||||
- Steps to reproduce the problem:
|
||||
- Screenshots:
|
||||
- Logs:
|
||||
|
||||
<!--
|
||||
Debug logs can be copied from within the app with
|
||||
Settings menu -> Advanced -> View log
|
||||
|
||||
Logs may contain private data
|
||||
which shall be removed or anonymised prior to posting.
|
||||
-->
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Request a new feature.
|
||||
title: ''
|
||||
assignees: ''
|
||||
labels: enhancement
|
||||
---
|
||||
|
||||
<!--
|
||||
Please fill out as much of this form as you can (leaving out stuff that is not applicable is ok).
|
||||
-->
|
||||
|
||||
### Describe your feature:
|
||||
|
||||
### Why do you think it is useful:
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
name: Other
|
||||
about: Start with a new blank issue.
|
||||
title: ''
|
||||
assignees: ''
|
||||
---
|
||||
@@ -1,314 +0,0 @@
|
||||
# GitHub Copilot Instructions for ArcaneChat Android
|
||||
|
||||
## Project Overview
|
||||
|
||||
ArcaneChat is a Delta Chat Android client built on top of the official Delta Chat client with several improvements. It is a messenger app that uses email infrastructure for secure communication.
|
||||
|
||||
**Technology Stack:**
|
||||
- **Language:** Java (Java 8 compatibility)
|
||||
- **Build System:** Gradle with Android Gradle Plugin 8.11.1
|
||||
- **Min SDK:** 21 (Android 5.0)
|
||||
- **Target SDK:** 36 (Android 16)
|
||||
- **NDK Version:** 27.0.12077973
|
||||
- **Native Components:** Rust (deltachat-core-rust submodule)
|
||||
- **UI Framework:** Android SDK, Material Design Components
|
||||
- **Testing:** JUnit 4, Espresso, Mockito, PowerMock, AssertJ
|
||||
|
||||
## Repository Structure
|
||||
|
||||
- `src/main/` - Main application source code
|
||||
- `src/main/java/org/thoughtcrime/securesms/` - Main UI components
|
||||
- `src/main/java/com/b44t/messenger/` - Delta Chat core integration
|
||||
- `src/main/java/chat/delta/rpc/` - JSON-RPC bindings (generated, don't edit manually)
|
||||
- `src/main/res/` - Android resources (layouts, strings, drawables)
|
||||
- `src/androidTest/` - Instrumented tests (UI tests, benchmarks)
|
||||
- `src/androidTest/java/com/b44t/messenger/uitests/` - UI tests
|
||||
- `src/androidTest/java/com/b44t/messenger/uibenchmarks/` - Performance benchmarks
|
||||
- `src/gplay/` - Google Play flavor-specific code
|
||||
- `src/foss/` - F-Droid/FOSS flavor-specific code
|
||||
- `jni/deltachat-core-rust/` - Native Rust core library (submodule, **don't edit directly**)
|
||||
- `scripts/` - Build and helper scripts
|
||||
- `scripts/ndk-make.sh` - Build native libraries
|
||||
- `scripts/install-toolchains.sh` - Install Rust cross-compilation toolchains
|
||||
- `scripts/generate-rpc-bindings.sh` - Generate JSON-RPC bindings
|
||||
- `docs/` - Documentation
|
||||
- `fastlane/` - App store metadata and screenshots
|
||||
- `.github/workflows/` - CI/CD workflows (GitHub Actions)
|
||||
|
||||
## Build Instructions
|
||||
|
||||
### Prerequisites
|
||||
|
||||
1. **Initialize submodules:**
|
||||
```bash
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
This MUST be done first before any build attempts.
|
||||
|
||||
2. **Set up environment variables:**
|
||||
```bash
|
||||
export ANDROID_NDK_ROOT=/path/to/ndk/27.0.12077973
|
||||
export PATH=${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/:${ANDROID_NDK_ROOT}
|
||||
```
|
||||
Note: Path format varies by OS (linux-x86_64, darwin-x86_64, etc.)
|
||||
|
||||
3. **Install Rust toolchains:**
|
||||
```bash
|
||||
scripts/install-toolchains.sh
|
||||
```
|
||||
Required for building the native Rust components.
|
||||
|
||||
4. **Build native libraries:**
|
||||
```bash
|
||||
scripts/ndk-make.sh
|
||||
```
|
||||
**IMPORTANT:** First run takes 30-60 minutes as it builds for all architectures (armeabi-v7a, arm64-v8a, x86, x86_64).
|
||||
For faster development builds, build for a single architecture:
|
||||
```bash
|
||||
scripts/ndk-make.sh armeabi-v7a
|
||||
```
|
||||
|
||||
5. **Build APK:**
|
||||
```bash
|
||||
./gradlew assembleDebug
|
||||
```
|
||||
Build time: ~2-5 minutes after native libraries are built.
|
||||
|
||||
### Build Flavors
|
||||
|
||||
- **gplay:** Google Play version with Firebase Cloud Messaging (applicationId: `com.github.arcanechat`)
|
||||
- **foss:** F-Droid version without proprietary services (applicationId: `chat.delta.lite`)
|
||||
|
||||
### Build Outputs
|
||||
|
||||
- Debug APKs: `build/outputs/apk/gplay/debug/` and `build/outputs/apk/fat/debug/`
|
||||
- Release APKs require signing configuration in `~/.gradle/gradle.properties`
|
||||
|
||||
### Common Build Issues
|
||||
|
||||
1. **Missing NDK or incorrect version:**
|
||||
- Error: `ANDROID_NDK_ROOT not set` or native library missing
|
||||
- Solution: Install NDK 27.0.12077973 and set ANDROID_NDK_ROOT environment variable
|
||||
|
||||
2. **Submodules not initialized:**
|
||||
- Error: Missing deltachat-core-rust files
|
||||
- Solution: Run `git submodule update --init --recursive`
|
||||
|
||||
3. **Gradle wrapper validation:**
|
||||
- Always validate gradle wrapper before building: `./gradlew wrapper --gradle-version=current`
|
||||
- Wrapper is validated in CI via `gradle/actions/wrapper-validation@v4`
|
||||
|
||||
4. **Clean build issues:**
|
||||
- If build fails, try: `./gradlew clean && scripts/ndk-make.sh && ./gradlew assembleDebug`
|
||||
- Remove `build/` directory if clean doesn't work
|
||||
|
||||
## Testing
|
||||
|
||||
### Running Unit Tests
|
||||
|
||||
```bash
|
||||
./gradlew test
|
||||
```
|
||||
Expected duration: 1-3 minutes
|
||||
|
||||
### Running Instrumented Tests
|
||||
|
||||
1. **Disable animations** on your device/emulator:
|
||||
- Developer Options → Set "Window animation scale", "Transition animation scale", and "Animator duration scale" to 0x
|
||||
- **CRITICAL:** Tests will fail if animations are enabled
|
||||
|
||||
2. **Run tests:**
|
||||
```bash
|
||||
./gradlew connectedAndroidTest
|
||||
```
|
||||
Expected duration: 10-30 minutes depending on device/emulator
|
||||
|
||||
### Online Tests
|
||||
|
||||
Some tests require real email credentials. Configure in `~/.gradle/gradle.properties`:
|
||||
```properties
|
||||
TEST_ADDR=youraccount@yourdomain.org
|
||||
TEST_MAIL_PW=yourpassword
|
||||
```
|
||||
|
||||
### UI Tests and Benchmarks
|
||||
|
||||
- Located in `src/androidTest/java/com/b44t/messenger/`
|
||||
- Test categories: `uitests/online/`, `uitests/offline/`, `uibenchmarks/`
|
||||
- Run via Android Studio: Run → Edit Configurations → Android Instrumented Test
|
||||
|
||||
## Coding Conventions
|
||||
|
||||
### General Guidelines
|
||||
|
||||
1. **Embrace existing style:** Match the coding style of the file you're editing
|
||||
2. **Minimize changes:** Don't refactor or rename in the same PR as bug fixes/features
|
||||
3. **Readable over paradigmatic:** Favor readability over strict Java patterns
|
||||
4. **Avoid premature optimization:** Keep things simple and on point
|
||||
5. **No excessive abstraction:** Avoid unnecessary factories, one-liner functions, or abstraction layers
|
||||
6. **Comments:** Only add comments if they match existing style or explain complex logic
|
||||
|
||||
### Architecture
|
||||
|
||||
- **UI/Model Separation:** Delta Chat Core (Rust) handles the model layer
|
||||
- **High-level interface:** Core provides data in UI-ready form; avoid additional transformations in UI layer
|
||||
- **Direct approach:** Prefer direct implementation over excessive class hierarchies
|
||||
|
||||
### Key Principles
|
||||
|
||||
- Work hard to avoid options and up-front choices
|
||||
- Avoid speaking about keys/encryption in primary UI
|
||||
- App must work offline and with poor network
|
||||
- Users don't read much text
|
||||
- Consistency matters
|
||||
- Primary UI should only show highly useful features
|
||||
|
||||
## Common Development Tasks
|
||||
|
||||
### Adding New Features
|
||||
|
||||
1. Consider the UX philosophy (minimal options, offline-first, simplicity)
|
||||
2. Check if core library changes are needed before implementing in UI
|
||||
3. Match existing code style in modified files
|
||||
4. Add instrumented tests for UI changes when appropriate
|
||||
5. Update relevant documentation
|
||||
|
||||
### Modifying Core Integration
|
||||
|
||||
- Core library is in `jni/deltachat-core-rust/` submodule
|
||||
- Java bindings are in `src/main/java/com/b44t/messenger/Dc*.java`
|
||||
- JSON-RPC bindings in `chat.delta.rpc.*` package (generated via dcrpcgen)
|
||||
|
||||
### Generating JSON-RPC Bindings
|
||||
|
||||
To regenerate JSON-RPC bindings after core changes:
|
||||
```bash
|
||||
./scripts/generate-rpc-bindings.sh
|
||||
```
|
||||
**Note:** Requires Rust tooling and [dcrpcgen tool](https://github.com/chatmail/dcrpcgen) installed
|
||||
|
||||
### Working with Translations
|
||||
|
||||
- Translations managed via Transifex (not in repository)
|
||||
- English source strings: `res/values/strings.xml`
|
||||
- Don't mix string changes with refactoring
|
||||
|
||||
### Debugging Native Code
|
||||
|
||||
Decode crash symbols:
|
||||
```bash
|
||||
$ANDROID_NDK_ROOT/ndk-stack --sym obj/local/armeabi-v7a --dump crash.txt > decoded.txt
|
||||
```
|
||||
|
||||
## Validation and Quality Checks
|
||||
|
||||
### Pre-commit Checks
|
||||
|
||||
Before committing changes, always run:
|
||||
|
||||
1. **Gradle wrapper validation:**
|
||||
```bash
|
||||
./gradlew wrapper --gradle-version=current
|
||||
```
|
||||
|
||||
2. **Build verification:**
|
||||
```bash
|
||||
./gradlew assembleDebug
|
||||
```
|
||||
|
||||
3. **Unit tests:**
|
||||
```bash
|
||||
./gradlew test
|
||||
```
|
||||
|
||||
4. **Code style:** Match existing code style in modified files (no automatic formatter configured)
|
||||
|
||||
### When to Rebuild Native Libraries
|
||||
|
||||
Rebuild native libraries (`scripts/ndk-make.sh`) when:
|
||||
- Updating deltachat-core-rust submodule
|
||||
- Modifying anything in `jni/` directory
|
||||
- Changing NDK version
|
||||
- After `git clean -fdx` or fresh clone
|
||||
|
||||
**DO NOT** rebuild native libraries for:
|
||||
- Pure Java/Kotlin code changes
|
||||
- Resource file changes
|
||||
- Gradle configuration changes (unless changing native library linking)
|
||||
- Documentation updates
|
||||
|
||||
## WebXDC Support
|
||||
|
||||
ArcaneChat has extended WebXDC support:
|
||||
- `window.webxdc.arcanechat` - Version detection
|
||||
- `sendToChat()` - Extra properties: `subject`, `html`, `type` (sticker/image/audio/video/file)
|
||||
- External link support in apps
|
||||
- `manifest.toml` - `orientation` field for landscape mode
|
||||
|
||||
## Important Files
|
||||
|
||||
- `build.gradle` - Main build configuration (Android Gradle Plugin 8.11.1, Java 8 compatibility)
|
||||
- `CONTRIBUTING.md` - Contribution guidelines
|
||||
- `BUILDING.md` - Detailed build setup instructions
|
||||
- `RELEASE.md` - Release process
|
||||
- `proguard-rules.pro` - ProGuard configuration (enabled for both debug and release)
|
||||
- `google-services.json` - Firebase configuration (gplay flavor only)
|
||||
- `settings.gradle` - Gradle settings
|
||||
- `.github/workflows/` - CI/CD configuration
|
||||
|
||||
## Dependencies and Constraints
|
||||
|
||||
- **Java Version:** Java 8 compatibility (do not use Java 9+ features)
|
||||
- **Gradle:** Use wrapper (`./gradlew`) to ensure correct Gradle version
|
||||
- **NDK:** Must use version 27.0.12077973 (specified in build.gradle)
|
||||
- **Min SDK:** 21 (Android 5.0) - code must be compatible
|
||||
- **Target SDK:** 36 (Android 16) - test on this API level when possible
|
||||
- **ProGuard:** Always enabled - ensure ProGuard rules are correct for new dependencies
|
||||
- **Multi-dex:** Enabled - app exceeds 65k method limit
|
||||
|
||||
## Package Structure
|
||||
|
||||
- `org.thoughtcrime.securesms.*` - Main UI components (legacy namespace from Signal)
|
||||
- `com.b44t.messenger.*` - Delta Chat core integration
|
||||
- `chat.delta.rpc.*` - JSON-RPC bindings (generated)
|
||||
|
||||
## Notes for AI Assistants
|
||||
|
||||
- This is a fork of Delta Chat Android with ArcaneChat-specific improvements
|
||||
- Maintain compatibility with Delta Chat core library
|
||||
- Test on both gplay and foss flavors when making changes
|
||||
- Native library must be rebuilt after core changes
|
||||
- ProGuard is enabled in both debug and release builds
|
||||
- Multi-dex is enabled due to app size
|
||||
|
||||
## CI/CD Workflows
|
||||
|
||||
### Preview APK Workflow (.github/workflows/preview-apk.yml)
|
||||
|
||||
Runs on every pull request to build and upload a preview APK:
|
||||
|
||||
1. **Setup steps:**
|
||||
- Checks out repository with submodules
|
||||
- Validates Fastlane metadata
|
||||
- Sets up Rust cache (working-directory: jni/deltachat-core-rust)
|
||||
- Sets up Java 17 (Temurin distribution)
|
||||
- Sets up Android SDK
|
||||
- Caches Gradle dependencies
|
||||
- Sets up NDK r27
|
||||
|
||||
2. **Build process:**
|
||||
```bash
|
||||
scripts/install-toolchains.sh && scripts/ndk-make.sh armeabi-v7a
|
||||
./gradlew --no-daemon -PABI_FILTER=armeabi-v7a assembleFossDebug
|
||||
```
|
||||
Note: Builds only armeabi-v7a for faster CI builds
|
||||
|
||||
3. **Output:** Uploads APK artifact to GitHub Actions
|
||||
|
||||
### Important CI Considerations
|
||||
|
||||
- Always validate Gradle wrapper before committing changes
|
||||
- Fastlane metadata must be valid (validated in CI)
|
||||
- Use `--no-daemon` flag for Gradle in CI environments
|
||||
- CI builds use FOSS flavor to avoid Google Services dependencies
|
||||
- Expected CI build time: 15-25 minutes for full workflow
|
||||
@@ -1,22 +0,0 @@
|
||||
version: 2
|
||||
mergeable:
|
||||
- when: pull_request.*
|
||||
name: "Changelog check"
|
||||
validate:
|
||||
- do: or
|
||||
validate:
|
||||
- do: description
|
||||
must_include:
|
||||
regex: '#skip-changelog'
|
||||
- do: and
|
||||
validate:
|
||||
- do: dependent
|
||||
changed:
|
||||
file: '**/*.java'
|
||||
required: ['CHANGELOG.md']
|
||||
fail:
|
||||
- do: checks
|
||||
status: 'action_required'
|
||||
payload:
|
||||
title: CHANGELOG.md might need an update
|
||||
summary: "Please update CHANGELOG.md or add #skip-changelog to the description"
|
||||
@@ -1,53 +0,0 @@
|
||||
name: Core Cache
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'jni/deltachat-core-rust'
|
||||
- 'jni/Android.mk'
|
||||
- 'jni/Application.mk'
|
||||
- 'jni/dc_wrapper.c'
|
||||
- 'scripts/ndk-make.sh'
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
|
||||
- uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1
|
||||
- uses: nttld/setup-ndk@ed92fe6cadad69be94a966a7ee3271275e62f779 # v1.6.0
|
||||
id: setup-ndk
|
||||
with:
|
||||
ndk-version: "r29"
|
||||
|
||||
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
with:
|
||||
workspaces: jni/deltachat-core-rust
|
||||
|
||||
- name: Get deltachat-core-rust submodule hash
|
||||
id: core-hash
|
||||
run: echo "hash=$(git rev-parse HEAD:jni/deltachat-core-rust)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache compiled core
|
||||
id: cache-core
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
jni/arm64-v8a
|
||||
libs/arm64-v8a
|
||||
key: core-arm64-v8a-${{ steps.core-hash.outputs.hash }}-${{ hashFiles('jni/Android.mk', 'jni/Application.mk', 'jni/dc_wrapper.c', 'scripts/ndk-make.sh') }}-ndk-r27
|
||||
|
||||
- name: Compile core
|
||||
if: steps.cache-core.outputs.cache-hit != 'true'
|
||||
env:
|
||||
ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
run: |
|
||||
export PATH="${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/"
|
||||
scripts/install-toolchains.sh && scripts/ndk-make.sh arm64-v8a
|
||||
@@ -1,49 +0,0 @@
|
||||
name: Code Format
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
||||
|
||||
jobs:
|
||||
spotless:
|
||||
name: Check code format (Spotless)
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: temurin
|
||||
- name: Restore Gradle cache
|
||||
id: gradle-cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/actions/wrapper-validation@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
|
||||
- name: Check formatting
|
||||
run: ./gradlew spotlessCheck
|
||||
- name: Save Gradle cache
|
||||
if: github.event_name == 'push' && steps.gradle-cache.outputs.cache-hit != 'true'
|
||||
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
@@ -1,99 +0,0 @@
|
||||
name: Upload Preview APK
|
||||
|
||||
on: pull_request
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Upload Preview APK
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
submodules: recursive
|
||||
persist-credentials: false
|
||||
|
||||
- name: Validate Fastlane Metadata
|
||||
uses: ashutoshgngwr/validate-fastlane-supply-metadata@c8857fdbbd3e00f9a5cbe8604bcecfa95ce8fef8 # v2.1.0
|
||||
|
||||
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: 'temurin'
|
||||
|
||||
- uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
|
||||
- name: Validate Gradle Wrapper
|
||||
uses: gradle/actions/wrapper-validation@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
|
||||
|
||||
- uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1
|
||||
- uses: nttld/setup-ndk@ed92fe6cadad69be94a966a7ee3271275e62f779 # v1.6.0
|
||||
id: setup-ndk
|
||||
with:
|
||||
ndk-version: "r29"
|
||||
|
||||
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
with:
|
||||
workspaces: jni/deltachat-core-rust
|
||||
|
||||
- name: Get deltachat-core-rust submodule hash
|
||||
id: core-hash
|
||||
run: echo "hash=$(git rev-parse HEAD:jni/deltachat-core-rust)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore compiled core
|
||||
id: core-cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
jni/arm64-v8a
|
||||
libs/arm64-v8a
|
||||
key: core-arm64-v8a-${{ steps.core-hash.outputs.hash }}-${{ hashFiles('jni/Android.mk', 'jni/Application.mk', 'jni/dc_wrapper.c', 'scripts/ndk-make.sh') }}-ndk-r27
|
||||
|
||||
- name: Compile core
|
||||
if: steps.core-cache.outputs.cache-hit != 'true'
|
||||
env:
|
||||
ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
run: |
|
||||
export PATH="${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/"
|
||||
scripts/install-toolchains.sh && scripts/ndk-make.sh arm64-v8a
|
||||
|
||||
- name: Build APK
|
||||
run: ./gradlew --no-daemon -PABI_FILTER=arm64-v8a assembleFossDebug
|
||||
|
||||
- name: Upload APK
|
||||
id: upload
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: app-preview.apk
|
||||
path: 'build/outputs/apk/foss/debug/*.apk'
|
||||
|
||||
- name: Add artifact links to PR
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||
env:
|
||||
ARTIFACT_URL: ${{ steps.upload.outputs.artifact-url }}
|
||||
with:
|
||||
script: |
|
||||
const url = process.env.ARTIFACT_URL;
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.issue.number,
|
||||
body: `**To test the changes in this pull request, install this apk:**\n\n[📦 app-preview.apk](${url})`,
|
||||
});
|
||||
@@ -1,74 +0,0 @@
|
||||
name: Upload Release APK
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*.*.*'
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
match: ${{ steps.check-tag.outputs.match }}
|
||||
steps:
|
||||
- id: check-tag
|
||||
run: |
|
||||
if [[ "${{ github.event.ref }}" =~ ^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
|
||||
echo ::set-output name=match::true
|
||||
fi
|
||||
|
||||
build:
|
||||
needs: check
|
||||
if: needs.check.outputs.match == 'true'
|
||||
name: Upload Release APK
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
with:
|
||||
working-directory: jni/deltachat-core-rust
|
||||
- uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
|
||||
with:
|
||||
java-version: 17
|
||||
distribution: 'temurin'
|
||||
- uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1
|
||||
- uses: nttld/setup-ndk@ed92fe6cadad69be94a966a7ee3271275e62f779 # v1.6.0
|
||||
id: setup-ndk
|
||||
with:
|
||||
ndk-version: r27
|
||||
|
||||
- name: Compile core
|
||||
env:
|
||||
ANDROID_NDK_ROOT: ${{ steps.setup-ndk.outputs.ndk-path }}
|
||||
run: |
|
||||
export PATH="${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/:${ANDROID_NDK_ROOT}"
|
||||
./scripts/install-toolchains.sh && ./scripts/ndk-make.sh
|
||||
|
||||
- name: Build APK
|
||||
run: |
|
||||
mkdir -p ~/.gradle
|
||||
echo -n ${{ secrets.KEYSTORE_FILE }} | base64 -d >> ~/keystore.jks
|
||||
echo "DC_RELEASE_STORE_FILE=$HOME/keystore.jks" >> ~/.gradle/gradle.properties
|
||||
echo "DC_RELEASE_STORE_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> ~/.gradle/gradle.properties
|
||||
echo "DC_RELEASE_KEY_ALIAS_FDROID=${{ secrets.ALIAS_FDROID }}" >> ~/.gradle/gradle.properties
|
||||
echo "DC_RELEASE_KEY_ALIAS_GPLAY=${{ secrets.ALIAS_GPLAY }}" >> ~/.gradle/gradle.properties
|
||||
echo "DC_RELEASE_KEY_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }}" >> ~/.gradle/gradle.properties
|
||||
./gradlew assembleFossRelease
|
||||
rm build/outputs/apk/foss/release/*universal*
|
||||
./gradlew assembleGplayRelease
|
||||
mv build/outputs/apk/gplay/release/*universal* build/outputs/apk/foss/release/ArcaneChat-gplay.apk
|
||||
mv build/outputs/mapping/fossRelease/mapping.txt build/outputs/mapping/fossRelease/mapping-foss.txt
|
||||
mv build/outputs/mapping/gplayRelease/mapping.txt build/outputs/mapping/fossRelease/mapping-gplay.txt
|
||||
|
||||
- name: Release on GitHub
|
||||
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
|
||||
with:
|
||||
token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
body: '[<img src="store/get-it-on-gplay.png" alt="Get it on Google Play" height="48">](https://play.google.com/store/apps/details?id=com.github.arcanechat) [<img src="store/get-it-on-fdroid.png" alt="Get it on F-Droid" height="48">](https://f-droid.org/packages/chat.delta.lite) [<img src="store/get-it-on-github.png" alt="Get it on GitHub" height="48">](https://github.com/ArcaneChat/android/releases/latest/download/ArcaneChat-gplay.apk)'
|
||||
prerelease: ${{ contains(github.event.ref, '-beta') }}
|
||||
fail_on_unmatched_files: true
|
||||
files: |
|
||||
build/outputs/apk/foss/release/*.apk
|
||||
build/outputs/mapping/fossRelease/mapping-*.txt
|
||||
@@ -1,26 +0,0 @@
|
||||
name: GitHub Actions Security Analysis with zizmor
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["main"]
|
||||
pull_request:
|
||||
branches: ["**"]
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
zizmor:
|
||||
name: Run zizmor
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write # Required for upload-sarif (used by zizmor-action) to upload SARIF files.
|
||||
contents: read
|
||||
actions: read
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Run zizmor
|
||||
uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3
|
||||
@@ -1,6 +0,0 @@
|
||||
rules:
|
||||
unpinned-uses:
|
||||
config:
|
||||
policies:
|
||||
actions/*: ref-pin
|
||||
dependabot/*: ref-pin
|
||||
+6
-46
@@ -1,51 +1,11 @@
|
||||
*.keystore
|
||||
.classpath
|
||||
project.properties
|
||||
.project
|
||||
.settings
|
||||
bin/
|
||||
gen/
|
||||
/gplay/
|
||||
.idea/
|
||||
*.iml
|
||||
*.so
|
||||
out
|
||||
tests
|
||||
lint.xml
|
||||
local.properties
|
||||
ant.properties
|
||||
.DS_Store
|
||||
build.log
|
||||
build-log.xml
|
||||
.gradle
|
||||
build
|
||||
signing.properties
|
||||
library/lib/
|
||||
library/obj/
|
||||
ffpr
|
||||
test/androidTestEspresso/res/values/arrays.xml
|
||||
.gradle/
|
||||
build/
|
||||
obj/
|
||||
jni/libspeex/.deps/
|
||||
ndkArch
|
||||
|
||||
# ignore debug symbols created by ./tools/upload-release.sh
|
||||
*-symbols.zip
|
||||
*.iml
|
||||
local.properties
|
||||
*.keystore
|
||||
libs/
|
||||
|
||||
# ignore private scripts and directories, eg. local2github.prv.sh
|
||||
*.prv*
|
||||
|
||||
# contains files for ndk-build when done from gradle.
|
||||
.externalNativeBuild
|
||||
|
||||
# no vi tmp files
|
||||
*.swp
|
||||
|
||||
jni/x86
|
||||
jni/x86_64
|
||||
jni/armeabi
|
||||
jni/armeabi-v7a
|
||||
jni/arm64-v8a
|
||||
|
||||
artwork/drawable*/
|
||||
artwork/mipmap-*/
|
||||
*~
|
||||
|
||||
+3
-3
@@ -1,3 +1,3 @@
|
||||
[submodule "jni/deltachat-core-rust"]
|
||||
path = jni/deltachat-core-rust
|
||||
url = https://github.com/ArcaneChat/core
|
||||
[submodule "MessengerProj/jni/messenger-backend"]
|
||||
path = MessengerProj/jni/messenger-backend
|
||||
url = https://github.com/r10s/messenger-backend.git
|
||||
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
lang_map = id: in, ja_JP: ja, nl_NL: nl, pt_BR: pt-rBR, zh_CN: zh-rCN, zh_TW: zh-rTW
|
||||
|
||||
[o:delta-chat:p:delta-chat-app:r:stringsxml]
|
||||
file_filter = src/main/res/values-<lang>/strings.xml
|
||||
source_file = src/main/res/values/strings.xml
|
||||
source_lang = en
|
||||
type = ANDROID
|
||||
|
||||
-257
@@ -1,257 +0,0 @@
|
||||
# Building and Testing
|
||||
|
||||
This document describes how to set up the build environment,
|
||||
build and test the app. Before diving into developing, please
|
||||
first read [CONTRIBUTING.md](./CONTRIBUTING.md) for general
|
||||
contribution hints and conventions.
|
||||
|
||||
Please follow all steps precisely.
|
||||
If you run into troubles,
|
||||
ask on one of the [communication channels](https://delta.chat/contribute) for help
|
||||
|
||||
|
||||
## Check Out Repository
|
||||
|
||||
When checking out _deltachat-android_, make sure also to check out the
|
||||
subproject _deltachat-core-rust_:
|
||||
|
||||
- When using Git, you can do this initially by
|
||||
`$ git clone --recursive https://github.com/deltachat/deltachat-android`
|
||||
or later by `git submodule update --init --recursive`. If you do this in your
|
||||
home directory, this results in the folder `~/deltachat-android` which is just fine.
|
||||
|
||||
## Generate JSON-RPC bindings
|
||||
|
||||
To generate/update the JSON-RPC bindings (ex. `chat.delta.rpc.*` package)
|
||||
install Rust tooling (read sections below) and the [dcrpcgen tool](https://github.com/chatmail/dcrpcgen)
|
||||
then generate the code running the script:
|
||||
|
||||
```
|
||||
./scripts/update-rpc-bindings.sh
|
||||
```
|
||||
|
||||
## Build Using Nix
|
||||
|
||||
The repository contains [Nix](https://nixos.org/) development environment
|
||||
described in `flake.nix` file.
|
||||
If you don't have Nix installed,
|
||||
the easiest way is to follow the [Lix installation instructions](https://lix.systems/install/)
|
||||
as this results in a setup with [Flakes](https://nixos.wiki/wiki/Flakes) feature enabled out of the box
|
||||
and can be cleanly uninstalled with `/nix/nix-installer uninstall` once you don't need it anymore.
|
||||
|
||||
Once you have Nix with Flakes feature set up start the development environment shell:
|
||||
```
|
||||
nix develop
|
||||
```
|
||||
Nix development environment contains Rust with cross-compilation toolchains and Android SDK.
|
||||
|
||||
To [build an APK](https://developer.android.com/studio/build/building-cmdline) run the following 2 steps.
|
||||
Note that the first step may take some time to build for all architectures. You can optionally read
|
||||
[the first comment block in the `ndk-make.sh` script](./scripts/ndk-make.sh)
|
||||
for pointers on how to build for a specific architecture.
|
||||
```
|
||||
$ scripts/ndk-make.sh
|
||||
$ ./gradlew assembleDebug
|
||||
```
|
||||
|
||||
Resulting APK files can be found in
|
||||
`build/outputs/apk/gplay/debug/` and
|
||||
`build/outputs/apk/foss/debug/`.
|
||||
|
||||
## Build Using Dockerfile
|
||||
|
||||
Another way to build APK is to use provided `Dockerfile`
|
||||
with [Docker](https://www.docker.com/) or [Podman](https://podman.io/).
|
||||
Podman is a drop-in replacement for Docker that does not require root privileges.
|
||||
|
||||
If you don't have Docker or Podman setup yet, read [how to setup Podman](#setup-podman)
|
||||
below. If you don't want to use Docker or Podman, read [how to manually install the
|
||||
build environment](#install-build-environment).
|
||||
|
||||
First, build the image `deltachat-android` by running
|
||||
```
|
||||
podman build --build-arg UID=$(id -u) --build-arg GID=$(id -g) . -t deltachat-android
|
||||
```
|
||||
or
|
||||
```
|
||||
docker build --build-arg UID=$(id -u) --build-arg GID=$(id -g) . -t deltachat-android
|
||||
```
|
||||
|
||||
Then, run the image:
|
||||
```
|
||||
podman run --userns=keep-id -it --name deltachat -v $(pwd):/home/app:z -w /home/app localhost/deltachat-android
|
||||
```
|
||||
or
|
||||
```
|
||||
docker run -it --name deltachat -v $(pwd):/home/app:z -w /home/app localhost/deltachat-android
|
||||
```
|
||||
|
||||
You can leave the container with Ctrl+D or by typing `exit` and re-enter it with
|
||||
`docker start -ia deltachat` or `podman start -ia deltachat`.
|
||||
|
||||
Within the container, install toolchains and build the native library:
|
||||
```
|
||||
deltachat@6012dcb974fe:/home/app$ scripts/install-toolchains.sh
|
||||
deltachat@6012dcb974fe:/home/app$ scripts/ndk-make.sh
|
||||
```
|
||||
|
||||
Then, [build an APK](https://developer.android.com/studio/build/building-cmdline):
|
||||
```
|
||||
deltachat@6012dcb974fe:/home/app$ ./gradlew assembleDebug
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
- Executing `./gradlew assembleDebug` inside the container fails with `The SDK directory '/home/user/Android/Sdk' does not exist.`:
|
||||
|
||||
The problem is that Android Studio (outside the container) automatically creates a file `local.properties` with a content like `sdk.dir=/home/username/Android/Sdk`,
|
||||
so, Gradle-inside-the-container looks for the Sdk at `/home/username/Android/Sdk`, where it can't find it.
|
||||
You could:
|
||||
- either: remove the file or just the line starting with `sdk.dir`
|
||||
- or: run `./gradlew assembleDebug` from outside the container (however, there may be incompatibility issues if different versions are installed inside and outside the container)
|
||||
|
||||
- Running the image fails with `ERRO[0000] The storage 'driver' option must be set in /etc/containers/storage.conf, guarantee proper operation.`:
|
||||
|
||||
In /etc/containers/storage.conf, replace the line: `driver = ""` with: `driver = "overlay"`.
|
||||
You can also set the `driver` option to something else, you just need to set it to _something_.
|
||||
[Read about possible options here](https://github.com/containers/storage/blob/main/docs/containers-storage.conf.5.md#storage-table).
|
||||
|
||||
## <a name="setup-podman"></a>Setup Podman
|
||||
|
||||
These instructions were only tested on a Manjaro machine so far. If anything doesn't work, please open an issue.
|
||||
|
||||
First, [Install Podman](https://podman.io/getting-started/installation).
|
||||
|
||||
Then, if you want to run Podman without root, run:
|
||||
```
|
||||
sudo touch /etc/subgid
|
||||
sudo touch /etc/subuid
|
||||
sudo usermod --add-subuids 165536-231072 --add-subgids 165536-231072 yourusername
|
||||
```
|
||||
(replace `yourusername` with your username).
|
||||
See https://wiki.archlinux.org/index.php/Podman#Rootless_Podman for more information.
|
||||
|
||||
## <a name="install-build-environment"></a>Install Build Environment (without Docker or Podman)
|
||||
|
||||
To setup build environment manually:
|
||||
- _Either_, in Android Studio, go to "Tools / SDK Manager / SDK Tools", enable "Show Package Details",
|
||||
select "CMake" and the desired NDK (install the same NDK version as the [Dockerfile](./Dockerfile)), hit "Apply".
|
||||
- _Or_ read [Dockerfile](./Dockerfile) and mimic what it does.
|
||||
|
||||
Then, in both cases, install Rust using [rustup](https://rustup.rs/)
|
||||
and Rust toolchains for cross-compilation by executing `scripts/install-toolchains.sh`.
|
||||
|
||||
Then, configure `ANDROID_NDK_ROOT` environment variable to point to the Android NDK
|
||||
installation directory e.g. by adding this to your `.bashrc`:
|
||||
|
||||
```bash
|
||||
export ANDROID_NDK_ROOT=${HOME}/Android/Sdk/ndk/[version] # (or wherever your NDK is) Note that there is no `/` at the end!
|
||||
export PATH=${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/:${ANDROID_NDK_ROOT}
|
||||
```
|
||||
|
||||
After that, call `scripts/ndk-make.sh` in the root directory to build core-rust.
|
||||
Afterwards run the project in Android Studio. The project requires API 25.
|
||||
|
||||
With chance, that's it :) - if not, read on how to set up a proper development
|
||||
environment.
|
||||
|
||||
|
||||
## Install Development Environment
|
||||
|
||||
1. Some libs required by Android Studio may be missing on 64 bit Linux machines
|
||||
[Source](https://developer.android.com/studio/install.html)], so for Ubuntu execute
|
||||
`$ sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386 lib32z1 libbz2-1.0:i386`
|
||||
and for Fedora execute
|
||||
`$ sudo yum install zlib.i686 ncurses-libs.i686 bzip2-libs.i686`.
|
||||
|
||||
2. Download Android Studio from <https://developer.android.com> (android-studio-ide-...-linux.zip)
|
||||
and unpack the archive which contains a single folder called `android-studio`;
|
||||
move this folder e.g. to `~/android-studio`.
|
||||
|
||||
3. To launch Android Studio for the first time, open a terminal, navigate to
|
||||
`~/android-studio/bin`, execute `./studio.sh` and use all the standard values
|
||||
from the wizard.
|
||||
|
||||
4. Android Studio now asks you if you want to open an existing project;
|
||||
choose `~/deltachat-android` as created in the "Build" chapter (Android Studio starts to
|
||||
build the project, however, there are some steps missing before this will
|
||||
succeed).
|
||||
|
||||
5. If components are missing, click on the corresponding error
|
||||
message and install eg. required SDKs and the "Build-Tools" (you should
|
||||
also find the option at "Tools / Android / SDK Manager / SDK Platforms").
|
||||
Now the build should succeed - but the app still misses the native part.
|
||||
|
||||
6. Download Android NDK from
|
||||
[NDK Archives](https://developer.android.com/ndk/downloads)
|
||||
and extract the archive containing a single folder
|
||||
called something like `android-ndk-r23b-linux`; move this folder e.g. to `~/android-ndk`.
|
||||
|
||||
7. Export the folder path to your environment as `ANDROID_NDK_ROOT` and add it to `PATH`.
|
||||
You can achieve this e.g. by adding this to your `.bashrc`
|
||||
```bash
|
||||
export ANDROID_NDK_ROOT=${HOME}/android-ndk
|
||||
export PATH=${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/:${ANDROID_NDK_ROOT}
|
||||
```
|
||||
|
||||
## Run UI Tests and Benchmarks
|
||||
|
||||
- You don't necessarily need a dedicated testing device.
|
||||
Backup your current account first, maybe there are some bugs in switching accounts.
|
||||
|
||||
- You can run benchmarks on either an emulated device or a real device.
|
||||
You need at least Android 9. For better benchmark results,
|
||||
you should run the benchmark on a real device and make sure that the core is compiled in release mode.
|
||||
|
||||
- Disable animations on your device, otherwise the test may fail:
|
||||
at "Developer options"
|
||||
set all of "Window animation scale", "Transition animation scale" and "Animator duration scale" to 0x
|
||||
|
||||
- In Android Studio: "File" / "Sync project with gradle files"
|
||||
|
||||
- In Android Studio: "Run" / "Edit configurations" / "+" / "Android Instrumented test":
|
||||
Either select a specific class or select "All in Module" / "OK" /
|
||||
Select your configuration in the toolbar / Click on the green "run" button in the toolbar to run the tests
|
||||
|
||||
### Get the benchmark results
|
||||
|
||||
When the benchmark is done, you will get a result like
|
||||
`MEASURED RESULTS (Benchmark) - Going thorough all 10 chats: 11635,11207,11363,11352,11279,11183,11137,11145,11032,11057`.
|
||||
You can paste `11635,11207,11363,11352,11279,11183,11137,11145,11032,11057`
|
||||
into a cell in a LibreOffice spreadsheet, do "Data" / "Text to columns",
|
||||
choose `,` as a separator, hit "OK", and create a diagram.
|
||||
|
||||
### Run online tests
|
||||
|
||||
For some tests, you need to provide the credentials to an actual email account.
|
||||
You have 2 ways to do this:
|
||||
|
||||
1. (Recommended): Put them into the file ~/.gradle/gradle.properties (create it if it doesn't exist):
|
||||
```
|
||||
TEST_ADDR=youraccount@yourdomain.org
|
||||
TEST_MAIL_PW=youpassword
|
||||
```
|
||||
|
||||
2. Or set them via environment variables.
|
||||
|
||||
## Decoding Symbols in Crash Reports
|
||||
|
||||
```
|
||||
$ANDROID_NDK_ROOT/ndk-stack --sym obj/local/armeabi-v7a --dump crash.txt > decoded.txt
|
||||
```
|
||||
|
||||
`obj/local/armeabi-v7a` is the extracted path from `deltachat-gplay-release-X.X.X.apk-symbols.zip` file from https://download.delta.chat/android/symbols/
|
||||
|
||||
Replace `armeabi-v7a` by the correct architecture the logs come from (can be guessed by trial and error)
|
||||
|
||||
|
||||
### Deobfuscating Java Stack Traces
|
||||
|
||||
Because the app uses code minification (ProGuard/R8), Java stack traces in crash reports are obfuscated.
|
||||
To decode them, use `retrace` with the `mapping.txt` file that is included in the symbols zip:
|
||||
|
||||
```
|
||||
retrace mapping.txt crash.txt > decoded-crash.txt
|
||||
```
|
||||
|
||||
`mapping.txt` is extracted from the same `deltachat-gplay-release-X.X.X.apk-symbols.zip` file available at https://download.delta.chat/android/symbols/
|
||||
File diff suppressed because it is too large
Load Diff
+226
@@ -0,0 +1,226 @@
|
||||
# Delta Chat Changelog
|
||||
|
||||
## v0.9.6
|
||||
2017-10-18
|
||||
|
||||
* Support keys generated with multiple subkeys eg. from K-9
|
||||
* Show PDFs and other attachments with bad names
|
||||
* Bug fixes
|
||||
|
||||
## v0.9.5
|
||||
2017-10-08
|
||||
|
||||
* Backup export and import function
|
||||
* Query password before export
|
||||
* Move replies from normal E-Mail-Clients to the "Chats" folder
|
||||
* Improve helping MUAs on showing chat threads
|
||||
* Improve onboarding
|
||||
* Add URL to default footer
|
||||
* Test a different approach for battery saving in this release
|
||||
* Update French, Italian, German, Polish, Portuguese, Russian and Ukrainian translations
|
||||
|
||||
## v0.9.4
|
||||
2017-08-23
|
||||
|
||||
* Introduce an editable "Status" field that is shown eg. in email footers
|
||||
* Editable and synchronized group images
|
||||
* Show the subject of messages that cannot be decrypted
|
||||
* Do not send "Read receipts" when decryption fails
|
||||
* Do not request "Read receipts" from normal MUAs as there are too many MUAs responding with weird, non-standard formats
|
||||
* Deleting a chat always deletes all messages from the device permanently
|
||||
* Ignore messages from mailing lists
|
||||
* Do not spread the original authors name nor address on forwarding
|
||||
* Encrypt mails send to SMTP and to IMAP the same way
|
||||
* Improve showing HTML-mails
|
||||
* Cleanup Android code
|
||||
* Remove badge counter on app restart
|
||||
* Add Ukrainian translation
|
||||
* Add Telugu translation
|
||||
* Add Catalan translation
|
||||
* Update German, Spanish, French, Hungarian, Italian, Polish, Portuguese and Russian translations
|
||||
|
||||
## v0.9.3
|
||||
2017-07-13
|
||||
|
||||
* Introduce "Read receipts" and avoid social pressure to leave it activated
|
||||
* Improve encryption dialog in profile
|
||||
* Fix marking messages as "seen" when opening the contact requests
|
||||
* Ignore signature.asc files of signed-only messages
|
||||
* Update Polish, Portuguese and Russian translations
|
||||
|
||||
## v0.9.2
|
||||
2017-06-28
|
||||
|
||||
* Encrypt group chats
|
||||
* Cryptographically sign messages
|
||||
* Validate signatures of incoming messages ("Info" shows the state)
|
||||
* Show a little lock beside end-to-end-encrypted messages with a validated signature
|
||||
* If end-to-end-encryption is available on sending time, guarantee the message not to be sent without end-to-end-encryption later
|
||||
* Show special characters in HTML-mails
|
||||
* Help MUAs on showing chat threads
|
||||
* Show attachments from multipart/alternative structures
|
||||
* Upgrade from Autocrypt Level 0 to Level 1; as the levels are not compatible, encryption on mixed setups does not happen
|
||||
* Update Polish, Portuguese, Spanish and French translations
|
||||
|
||||
## v0.9.1
|
||||
2017-06-04
|
||||
|
||||
* Profile: Improve encryption state dialog
|
||||
* Improved video quality of short clips
|
||||
* Make encryption-dialog localizable
|
||||
* Update Russian translation
|
||||
|
||||
## v0.9.0
|
||||
2017-06-01
|
||||
|
||||
* Add end-to-end-encrypting following the OpenPGP and Autocrypt standards
|
||||
* Add a function to compare keys
|
||||
* Profile: Add option to copy the email address to the clipboard
|
||||
* Pimp GUI
|
||||
|
||||
## v0.1.36
|
||||
2017-05-04
|
||||
|
||||
* Support camera on Android Nougat
|
||||
|
||||
## v0.1.34
|
||||
2017-05-03
|
||||
|
||||
* Link to new homepage https://delta.chat
|
||||
* Localizable Help-URLs
|
||||
|
||||
## v0.1.33
|
||||
2017-04-29
|
||||
|
||||
* Better support for right-to-left (RTL) languages, taking advantage of
|
||||
Android 4.2 (Jelly Bean MR1, API level 17).
|
||||
* Send PNG files without resizing and converting to JPEG
|
||||
* If JPEG files are send without compression, they still appear as image, not as attached files
|
||||
* Raise-to-speak defaults to false
|
||||
* Unify long click behaviour
|
||||
* Support Android's system function "Delete data"
|
||||
* Replies to messages pop up automatically even if send from other email addresses (typical scenario for alias addresses)
|
||||
* Fix group-replies from normal email-clients.
|
||||
|
||||
## v0.1.32
|
||||
2017-04-22
|
||||
|
||||
* Update Spanish and Portuguese translations
|
||||
* Update internal sqlite library to version 3.18.0, released on 2017-03-28
|
||||
* Remove more of the custom language handling, use Android's routines instead
|
||||
* General code cleanup
|
||||
* Play GIF files
|
||||
* Option to disable autoplaying GIF files
|
||||
* When sending contacts, only use the names the receivers have set themselves
|
||||
* Show some hints when long-pressing icons in the action bar
|
||||
|
||||
## v0.1.29
|
||||
2017-04-19
|
||||
|
||||
* Add Russian translation
|
||||
* For outgoing (group-)messages, only use the names the receivers have set themselves
|
||||
|
||||
## v0.1.28
|
||||
2017-04-14
|
||||
|
||||
* Pimp notifications
|
||||
* Bug fixes
|
||||
|
||||
## v0.1.27
|
||||
2017-04-12
|
||||
|
||||
* Use a permanent foreground service for reliable notifications
|
||||
* Monitor the IMAP-IDLE thread and reconnect if IMAP-IDLE seems to hang
|
||||
* Various battery and background optimizations
|
||||
|
||||
## v0.1.25
|
||||
2017-04-04
|
||||
|
||||
* Use system or user selected video player.
|
||||
* Do not connect if not configured (avoids a warning on the first time startup)
|
||||
* Add vertical scrollbar, eg. to settings activities.
|
||||
* Pimp GUI and logo.
|
||||
* Update Korean.
|
||||
|
||||
## v0.1.24
|
||||
2017-03-31
|
||||
|
||||
* Share images and documents from other apps to Delta Chat
|
||||
* Offer to mailto:-link-support to other apps
|
||||
* Ignore implausible sending time of incoming messages; use the receive time in these rare cases
|
||||
* Show errors only when Delta Chat is in foreground
|
||||
* Dynamically adapt video bitrate for longer videos to an attachment-size of max. 25 MB
|
||||
|
||||
## v0.1.23
|
||||
2017-03-28
|
||||
|
||||
* Retry connecting to IMAP if there is not network available on the first try
|
||||
* Notify about new messages if the app is not active for hours, optimize battery consumption
|
||||
|
||||
## v0.1.22
|
||||
2017-03-22
|
||||
|
||||
* Show HTML-only messages
|
||||
* Show connection errors
|
||||
* Add options for SSL/TLS and STARTTLS
|
||||
* Automatic account configuration, if possible
|
||||
* Recode large videos
|
||||
* Add Hungarian translation
|
||||
* Add Korean translation
|
||||
|
||||
## v0.1.21
|
||||
2017-03-10
|
||||
|
||||
* Record and send voice messages
|
||||
* Record and send videos
|
||||
* Send and play music
|
||||
* Send contacts and email addresses
|
||||
* Sending and opening attachments of any type
|
||||
* Share and open commands for all attachments
|
||||
* Accept VCards send to us by other apps
|
||||
* Clickable email addresses
|
||||
* Update Polish translation
|
||||
* Fix tablet startup bug
|
||||
* Close the app when using the lock-app-via-pincode function
|
||||
* Protect data by using a content provider for sharing
|
||||
* Try to clear the task switcher's screenshots when locking the app via pincode
|
||||
* Pimp GUI
|
||||
|
||||
## v0.1.20
|
||||
2017-02-16
|
||||
|
||||
* Avoid unwanted downloads of lots of old messages
|
||||
* Make the "Chats" folder visible if the server hides new folders by default
|
||||
* Fix a crash when the server returns empty folders
|
||||
* Update Polish and Portuguese translations
|
||||
* Use API level 25 (Nougat 7.1) as target
|
||||
|
||||
## v0.1.18
|
||||
2017-02-11
|
||||
|
||||
* Add Polish translation
|
||||
* Use a new default background for chats
|
||||
* Improve typography by using the system font instead of a custom resource font
|
||||
* Remove custom plural handling, use Android's routines instead
|
||||
* Remove unused source code and strings
|
||||
* More fixes of lint errors and warnings
|
||||
|
||||
## v0.1.17
|
||||
2017-02-07
|
||||
|
||||
* Drop two unnecessary permissions: ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION
|
||||
* Really add French translation
|
||||
* Update Portuguese translation
|
||||
* Start fixing translation handling of the program
|
||||
* Remove special "foss" build, because the whole program is free now.
|
||||
|
||||
## v0.1.16
|
||||
2017-02-06
|
||||
|
||||
* Add French translation
|
||||
* Fix some lint errors and warnings
|
||||
|
||||
## v0.1.15
|
||||
2017-01-31
|
||||
|
||||
* Prepare for release on [F-Droid](https://f-droid.org/)
|
||||
-150
@@ -1,150 +0,0 @@
|
||||
# Contributing Guidelines
|
||||
|
||||
Thank you for looking for ways to help on Delta Chat Android!
|
||||
|
||||
This document tries to outline some conventions that may not be obvious
|
||||
and aims to give a good starting point to new contributors.
|
||||
|
||||
|
||||
## Reporting Bugs
|
||||
|
||||
If you found a bug, [report it on Github](https://github.com/deltachat/deltachat-android/issues).
|
||||
|
||||
Project maintainers may transfer bugs that are not UI specific
|
||||
(eg. network, database or encryption related)
|
||||
to [Delta Chat Core](https://github.com/deltachat/deltachat-core-rust/issues).
|
||||
If you assume beforehand, that the bug you've found belongs to Core,
|
||||
you can report there directly.
|
||||
|
||||
Please search both open and closed issues to make sure your bug report is not a duplicate.
|
||||
|
||||
For community interactions around Delta Chat
|
||||
please read our [Community Standards](https://delta.chat/community-standards).
|
||||
|
||||
|
||||
## Proposing Features
|
||||
|
||||
If you have a feature request,
|
||||
create a new topic on the [Forum](https://support.delta.chat/c/features/6).
|
||||
|
||||
|
||||
## Rough UX Philosophy
|
||||
|
||||
Some rough ideas, that may be helpful when thinking about how to enhance things:
|
||||
|
||||
- Work hard to avoid options and up-front choices.
|
||||
Thinking about concrete user stories may help on that.
|
||||
- Avoid to speak about keys and other hard to understand things in the primary UI.
|
||||
- The app shall work offline as well as with bad network.
|
||||
- Users do not read (much).
|
||||
- Consistency matters.
|
||||
- Offer only things that are highly useful to many people in primary UI.
|
||||
If really needed, bury other things eg. in some menus.
|
||||
- The app should be for the many, not for the few.
|
||||
|
||||
|
||||
## Contributing Code
|
||||
|
||||
The [BUILDING.md](./BUILDING.md) file explains in detail how to set up the build environment.
|
||||
Please follow all steps precisely.
|
||||
If you run into troubles,
|
||||
ask on one of the [communication channels](https://delta.chat/contribute) for help.
|
||||
|
||||
To contribute code,
|
||||
[open a Pull Request](https://github.com/deltachat/deltachat-android/pulls).
|
||||
|
||||
If you have write access to the repository,
|
||||
push a branch named `<username>/<feature>`
|
||||
so it is clear who is responsible for the branch,
|
||||
and open a PR proposing to merge the change.
|
||||
Otherwise fork the repository and create a branch in your fork.
|
||||
|
||||
Please add a meaningful description to your PR
|
||||
so that reviewers get an idea about what the modifications are supposed to do.
|
||||
|
||||
A meaningful PR title is helpful for [updating `CHANGELOG.md` on releases](./RELEASE.md)
|
||||
(CHANGELOG.md is updated manually
|
||||
to only add things that are at least roughly understandable by the end user)
|
||||
|
||||
If the changes affect the user interface,
|
||||
screenshots are very helpful,
|
||||
esp. before/after screenshots.
|
||||
|
||||
|
||||
### Coding Conventions
|
||||
|
||||
Project language is Java.
|
||||
|
||||
Code formatting is enforced via [Spotless](https://github.com/diffplug/spotless) Gradle plugin.
|
||||
Auto-format all files by running `./gradlew spotlessApply` before opening a PR.
|
||||
CI will fail if files are not formatted correctly so make sure to run the formatter before pushing.
|
||||
|
||||
If you do a PR fixing a bug or adding a feature, do not refactor or rename things in the same PR
|
||||
to make the diff small and the PR easy to review.
|
||||
|
||||
By using [Delta Chat Core](https://github.com/deltachat/deltachat-core-rust)
|
||||
there is already a strong separation between "UI" and "Model".
|
||||
Further separations and abstraction layers are often not helpful
|
||||
and only add more complexity.
|
||||
|
||||
Try to avoid premature optimisation
|
||||
and complexity because it "may be needed in some future".
|
||||
Usually, it is not.
|
||||
|
||||
Readable code is better than having some Java paradigms fulfilled.
|
||||
Classic Java has a strong drive to add lots of classes, factories, one-liner-functions.
|
||||
Try to not follow these patterns and keep things really on point and simple.
|
||||
If this gets in conflict with embracing existing style, however,
|
||||
consistency with existing code is more important.
|
||||
|
||||
The "Delta Chat Core" is a high-level interface to what the UI actually needs,
|
||||
data should be served in a form that the UI do not need much additional work.
|
||||
If this is not the case, consider a feature proposal to "Delta Chat Core".
|
||||
|
||||
|
||||
### Merging Conventions
|
||||
|
||||
PR are merged usually to the branch `main` from which [releases](./RELEASE.md) are done.
|
||||
|
||||
As a default, do a `git rebase main` in case feature branches and `main` differ too much.
|
||||
|
||||
Once a PR has an approval, unless stated otherwise, it can be merged by the author.
|
||||
A PR may be approved but postponed to be merged eg. because of an ongoing release.
|
||||
|
||||
To ensure the correct merge merge strategy, merging left up to the PR author:
|
||||
|
||||
- Usually, PR are squash-merged
|
||||
as UI development often results in tiny tweak commits that are not that meaningful on their own.
|
||||
- If all commits are meaningful and have a well-written description,
|
||||
they can be rebased-merged.
|
||||
|
||||
If you do not have write access to the repository,
|
||||
you may leave a note in the PR about the desired merge strategy.
|
||||
|
||||
|
||||
## Translations
|
||||
|
||||
Translations are done via [Transifex](https://explore.transifex.com/delta-chat/),
|
||||
you can log in there with your E-Mail Address or with a Github or Google handle.
|
||||
You find two projects there:
|
||||
- "Delta Chat App" contains the strings used in the app's UI
|
||||
- "Delta Chat Website" contains the offline help from "Settings / Help"
|
||||
as well as the pages used on <https://delta.chat>
|
||||
|
||||
Most strings and the whole help are used for all systems
|
||||
(Android, iOS, Linux, Windows, macOS)
|
||||
and should be formulated accordingly.
|
||||
|
||||
If you want to change the english sources,
|
||||
do a PR to [`strings.xml`](https://github.com/deltachat/deltachat-android/blob/main/res/values/strings.xml)
|
||||
or to [`help.md`](https://github.com/deltachat/deltachat-pages/blob/master/en/help.md).
|
||||
Again, please do not mix adding things and refactorings, esp. for `help.md`,
|
||||
this would require retranslations and should be considered carefully.
|
||||
|
||||
|
||||
## Other Ways To Contribute
|
||||
|
||||
For other ways to contribute, refer to the [website](https://delta.chat/contribute).
|
||||
|
||||
If you think, something important is missed in this overview,
|
||||
please do a PR to this document :)
|
||||
-44
@@ -1,44 +0,0 @@
|
||||
FROM docker.io/debian:12.4
|
||||
|
||||
# Install Android Studio requirements
|
||||
# See https://developer.android.com/studio/install#linux
|
||||
RUN apt-get update -y \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
wget \
|
||||
curl \
|
||||
unzip \
|
||||
openjdk-17-jre \
|
||||
file \
|
||||
build-essential \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ARG USER=deltachat
|
||||
ARG UID=1000
|
||||
ARG GID=1000
|
||||
|
||||
RUN groupadd -g $GID -o $USER
|
||||
RUN useradd -m -u $UID -g $GID -o $USER
|
||||
USER $USER
|
||||
|
||||
ENV ANDROID_SDK_ROOT /home/${USER}/android-sdk
|
||||
RUN mkdir ${ANDROID_SDK_ROOT}
|
||||
WORKDIR $ANDROID_SDK_ROOT
|
||||
RUN wget -q https://dl.google.com/android/repository/commandlinetools-linux-8512546_latest.zip && \
|
||||
unzip commandlinetools-linux-8512546_latest.zip && \
|
||||
rm commandlinetools-linux-8512546_latest.zip
|
||||
|
||||
RUN yes | ${ANDROID_SDK_ROOT}/cmdline-tools/bin/sdkmanager --sdk_root=${ANDROID_SDK_ROOT} --licenses
|
||||
|
||||
ENV PATH ${PATH}:${ANDROID_SDK_ROOT}/cmdline-tools/bin
|
||||
|
||||
# Install NDK manually. Other SDK parts are installed automatically by gradle.
|
||||
#
|
||||
# If you change the NDK version here, also change it in `flake.nix`.
|
||||
# NDK version r27 LTS aka 27.0.11902837
|
||||
RUN sdkmanager --sdk_root=${ANDROID_SDK_ROOT} 'ndk;27.0.11902837'
|
||||
|
||||
ENV ANDROID_NDK_ROOT ${ANDROID_SDK_ROOT}/ndk/27.0.11902837
|
||||
ENV PATH ${PATH}:${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/
|
||||
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain none
|
||||
ENV PATH ${PATH}:/home/${USER}/.cargo/bin
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
@@ -619,3 +620,5 @@ Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
task nativeLibsToJar(
|
||||
type: Zip,
|
||||
description: 'create a jar archive of the native libs') {
|
||||
destinationDir file("$buildDir/native-libs")
|
||||
baseName 'native-libs'
|
||||
extension 'jar'
|
||||
from fileTree(dir: 'libs', include: '**/*.so')
|
||||
into 'lib/'
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
compileTask -> compileTask.dependsOn(nativeLibsToJar)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'com.android.support:appcompat-v7:25.3.1'
|
||||
compile 'com.googlecode.mp4parser:isoparser:1.0.6'
|
||||
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
||||
compile fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion '25.0.2'
|
||||
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
defaultConfig.applicationId = "com.b44t.messenger"
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
debug {
|
||||
def debugKeystore = file("config/debug.keystore")
|
||||
if (debugKeystore.exists()) {
|
||||
storeFile debugKeystore
|
||||
}
|
||||
}
|
||||
|
||||
release {
|
||||
storeFile file("config/release.keystore")
|
||||
storePassword RELEASE_STORE_PASSWORD
|
||||
keyAlias RELEASE_KEY_ALIAS
|
||||
keyPassword RELEASE_KEY_PASSWORD
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
debuggable true
|
||||
jniDebuggable true
|
||||
signingConfig signingConfigs.debug
|
||||
applicationIdSuffix ".beta"
|
||||
}
|
||||
|
||||
release {
|
||||
debuggable false
|
||||
jniDebuggable false
|
||||
signingConfig signingConfigs.release
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig.versionCode = 45
|
||||
|
||||
sourceSets.main {
|
||||
jniLibs.srcDir 'libs'
|
||||
jni.srcDirs = [] //disable automatic ndk-build call
|
||||
}
|
||||
|
||||
productFlavors {
|
||||
/*
|
||||
x86 {
|
||||
ndk {
|
||||
abiFilter "x86"
|
||||
}
|
||||
versionCode = 2
|
||||
}
|
||||
arm {
|
||||
ndk {
|
||||
abiFilter "armeabi"
|
||||
}
|
||||
versionCode = 0
|
||||
}
|
||||
armv7 {
|
||||
ndk {
|
||||
abiFilter "armeabi-v7a"
|
||||
}
|
||||
versionCode = 1
|
||||
}
|
||||
*/
|
||||
fat {
|
||||
versionCode = 3
|
||||
}
|
||||
}
|
||||
|
||||
applicationVariants.all { variant ->
|
||||
def abiVersion = variant.productFlavors.get(0).versionCode
|
||||
variant.mergedFlavor.versionCode = defaultConfig.versionCode * 10 + abiVersion;
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 14 // 14: Android 4.0 Ice Cream Sandwich 2011 (Telegram default), 21: Android 5.0 Lollipop 2014 (recommended for InstantRun)
|
||||
targetSdkVersion 25 // 25: Nougat. CAVE: Do NOT target "Andoid O" without checking the background tasks carefully, see https://developer.android.com/preview/behavior-changes.html#back-all . As long as we target "Nougat", everything works as expected even for "Andoid O" or later
|
||||
// in general, we should not change the target without reason; eg. after the switch to Nougat, the camera stops working (see https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en )
|
||||
versionName "0.9.6" // do NOT forget to increase defaultConfig.versionCode!
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
APP_PLATFORM := android-14
|
||||
APP_ABI := armeabi armeabi-v7a x86
|
||||
NDK_TOOLCHAIN_VERSION := 4.9
|
||||
APP_STL := gnustl_static
|
||||
@@ -0,0 +1,845 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Delta Chat Android
|
||||
* (C) 2013-2016 Nikolai Kudashov
|
||||
* (C) 2017 Björn Petersen
|
||||
* Contact: r10s@b44t.com, http://b44t.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see http://www.gnu.org/licenses/ .
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#include <jni.h>
|
||||
#include <ogg/ogg.h>
|
||||
#include <stdio.h>
|
||||
#include <opus.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <opusfile.h>
|
||||
#include <math.h>
|
||||
#include "mrjnimain.h"
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int channels; /* Number of channels: 1..255 */
|
||||
int preskip;
|
||||
ogg_uint32_t input_sample_rate;
|
||||
int gain; /* in dB S7.8 should be zero whenever possible */
|
||||
int channel_mapping;
|
||||
/* The rest is only used if channel_mapping != 0 */
|
||||
int nb_streams;
|
||||
int nb_coupled;
|
||||
unsigned char stream_map[255];
|
||||
} OpusHeader;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *data;
|
||||
int maxlen;
|
||||
int pos;
|
||||
} Packet;
|
||||
|
||||
typedef struct {
|
||||
const unsigned char *data;
|
||||
int maxlen;
|
||||
int pos;
|
||||
} ROPacket;
|
||||
|
||||
typedef struct {
|
||||
void *readdata;
|
||||
opus_int64 total_samples_per_channel;
|
||||
int rawmode;
|
||||
int channels;
|
||||
long rate;
|
||||
int gain;
|
||||
int samplesize;
|
||||
int endianness;
|
||||
char *infilename;
|
||||
int ignorelength;
|
||||
int skip;
|
||||
int extraout;
|
||||
char *comments;
|
||||
int comments_length;
|
||||
int copy_comments;
|
||||
} oe_enc_opt;
|
||||
|
||||
static int write_uint32(Packet *p, ogg_uint32_t val) {
|
||||
if (p->pos > p->maxlen - 4) {
|
||||
return 0;
|
||||
}
|
||||
p->data[p->pos ] = (val ) & 0xFF;
|
||||
p->data[p->pos+1] = (val>> 8) & 0xFF;
|
||||
p->data[p->pos+2] = (val>>16) & 0xFF;
|
||||
p->data[p->pos+3] = (val>>24) & 0xFF;
|
||||
p->pos += 4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int write_uint16(Packet *p, ogg_uint16_t val) {
|
||||
if (p->pos > p->maxlen-2) {
|
||||
return 0;
|
||||
}
|
||||
p->data[p->pos ] = (val ) & 0xFF;
|
||||
p->data[p->pos+1] = (val>> 8) & 0xFF;
|
||||
p->pos += 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int write_chars(Packet *p, const unsigned char *str, int nb_chars)
|
||||
{
|
||||
int i;
|
||||
if (p->pos>p->maxlen-nb_chars)
|
||||
return 0;
|
||||
for (i=0;i<nb_chars;i++)
|
||||
p->data[p->pos++] = str[i];
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_uint32(ROPacket *p, ogg_uint32_t *val)
|
||||
{
|
||||
if (p->pos>p->maxlen-4)
|
||||
return 0;
|
||||
*val = (ogg_uint32_t)p->data[p->pos ];
|
||||
*val |= (ogg_uint32_t)p->data[p->pos+1]<< 8;
|
||||
*val |= (ogg_uint32_t)p->data[p->pos+2]<<16;
|
||||
*val |= (ogg_uint32_t)p->data[p->pos+3]<<24;
|
||||
p->pos += 4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_uint16(ROPacket *p, ogg_uint16_t *val)
|
||||
{
|
||||
if (p->pos>p->maxlen-2)
|
||||
return 0;
|
||||
*val = (ogg_uint16_t)p->data[p->pos ];
|
||||
*val |= (ogg_uint16_t)p->data[p->pos+1]<<8;
|
||||
p->pos += 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int read_chars(ROPacket *p, unsigned char *str, int nb_chars)
|
||||
{
|
||||
int i;
|
||||
if (p->pos>p->maxlen-nb_chars)
|
||||
return 0;
|
||||
for (i=0;i<nb_chars;i++)
|
||||
str[i] = p->data[p->pos++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int opus_header_to_packet(const OpusHeader *h, unsigned char *packet, int len) {
|
||||
int i;
|
||||
Packet p;
|
||||
unsigned char ch;
|
||||
|
||||
p.data = packet;
|
||||
p.maxlen = len;
|
||||
p.pos = 0;
|
||||
if (len < 19) {
|
||||
return 0;
|
||||
}
|
||||
if (!write_chars(&p, (const unsigned char *)"OpusHead", 8)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ch = 1;
|
||||
if (!write_chars(&p, &ch, 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ch = h->channels;
|
||||
if (!write_chars(&p, &ch, 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!write_uint16(&p, h->preskip)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!write_uint32(&p, h->input_sample_rate)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!write_uint16(&p, h->gain)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ch = h->channel_mapping;
|
||||
if (!write_chars(&p, &ch, 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (h->channel_mapping != 0) {
|
||||
ch = h->nb_streams;
|
||||
if (!write_chars(&p, &ch, 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ch = h->nb_coupled;
|
||||
if (!write_chars(&p, &ch, 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Multi-stream support */
|
||||
for (i = 0; i < h->channels; i++) {
|
||||
if (!write_chars(&p, &h->stream_map[i], 1)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p.pos;
|
||||
}
|
||||
|
||||
#define writeint(buf, base, val) do { buf[base + 3] = ((val) >> 24) & 0xff; \
|
||||
buf[base + 2]=((val) >> 16) & 0xff; \
|
||||
buf[base + 1]=((val) >> 8) & 0xff; \
|
||||
buf[base] = (val) & 0xff; \
|
||||
} while(0)
|
||||
|
||||
static void comment_init(char **comments, int *length, const char *vendor_string) {
|
||||
// The 'vendor' field should be the actual encoding library used
|
||||
int vendor_length = strlen(vendor_string);
|
||||
int user_comment_list_length = 0;
|
||||
int len = 8 + 4 + vendor_length + 4;
|
||||
char *p = (char *)malloc(len);
|
||||
memcpy(p, "OpusTags", 8);
|
||||
writeint(p, 8, vendor_length);
|
||||
memcpy(p + 12, vendor_string, vendor_length);
|
||||
writeint(p, 12 + vendor_length, user_comment_list_length);
|
||||
*length = len;
|
||||
*comments = p;
|
||||
}
|
||||
|
||||
static void comment_pad(char **comments, int* length, int amount) {
|
||||
if (amount > 0) {
|
||||
char *p = *comments;
|
||||
// Make sure there is at least amount worth of padding free, and round up to the maximum that fits in the current ogg segments
|
||||
int newlen = (*length + amount + 255) / 255 * 255 - 1;
|
||||
p = realloc(p, newlen);
|
||||
for (int i = *length; i < newlen; i++) {
|
||||
p[i] = 0;
|
||||
}
|
||||
*comments = p;
|
||||
*length = newlen;
|
||||
}
|
||||
}
|
||||
|
||||
static int writeOggPage(ogg_page *page, FILE *os) {
|
||||
int written = fwrite(page->header, sizeof(unsigned char), page->header_len, os);
|
||||
written += fwrite(page->body, sizeof(unsigned char), page->body_len, os);
|
||||
return written;
|
||||
}
|
||||
|
||||
static const opus_int32 bitrate = 16000;
|
||||
static const opus_int32 rate = 16000;
|
||||
static const opus_int32 frame_size = 960;
|
||||
static const int with_cvbr = 1;
|
||||
static const int max_ogg_delay = 0;
|
||||
static const int comment_padding = 512;
|
||||
|
||||
static opus_int32 coding_rate = 16000;
|
||||
static ogg_int32_t _packetId;
|
||||
static OpusEncoder *_encoder = 0;
|
||||
static uint8_t *_packet = 0;
|
||||
static ogg_stream_state os;
|
||||
static FILE *_fileOs = 0;
|
||||
static oe_enc_opt inopt;
|
||||
static OpusHeader header;
|
||||
static opus_int32 min_bytes;
|
||||
static int max_frame_bytes;
|
||||
static ogg_packet op;
|
||||
static ogg_page og;
|
||||
static opus_int64 bytes_written;
|
||||
static opus_int64 pages_out;
|
||||
static opus_int64 total_samples;
|
||||
static ogg_int64_t enc_granulepos;
|
||||
static ogg_int64_t last_granulepos;
|
||||
static int size_segments;
|
||||
static int last_segments;
|
||||
|
||||
static void cleanupRecorder() {
|
||||
|
||||
ogg_stream_flush(&os, &og);
|
||||
|
||||
if (_encoder) {
|
||||
opus_encoder_destroy(_encoder);
|
||||
_encoder = 0;
|
||||
}
|
||||
|
||||
ogg_stream_clear(&os);
|
||||
|
||||
if (_packet) {
|
||||
free(_packet);
|
||||
_packet = 0;
|
||||
}
|
||||
|
||||
if (_fileOs) {
|
||||
fclose(_fileOs);
|
||||
_fileOs = 0;
|
||||
}
|
||||
|
||||
_packetId = -1;
|
||||
bytes_written = 0;
|
||||
pages_out = 0;
|
||||
total_samples = 0;
|
||||
enc_granulepos = 0;
|
||||
size_segments = 0;
|
||||
last_segments = 0;
|
||||
last_granulepos = 0;
|
||||
memset(&os, 0, sizeof(ogg_stream_state));
|
||||
memset(&inopt, 0, sizeof(oe_enc_opt));
|
||||
memset(&header, 0, sizeof(OpusHeader));
|
||||
memset(&op, 0, sizeof(ogg_packet));
|
||||
memset(&og, 0, sizeof(ogg_page));
|
||||
}
|
||||
|
||||
static int initRecorder(const char *path) {
|
||||
cleanupRecorder();
|
||||
|
||||
if (!path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_fileOs = fopen(path, "wb");
|
||||
if (!_fileOs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
inopt.rate = rate;
|
||||
inopt.gain = 0;
|
||||
inopt.endianness = 0;
|
||||
inopt.copy_comments = 0;
|
||||
inopt.rawmode = 1;
|
||||
inopt.ignorelength = 1;
|
||||
inopt.samplesize = 16;
|
||||
inopt.channels = 1;
|
||||
inopt.skip = 0;
|
||||
|
||||
comment_init(&inopt.comments, &inopt.comments_length, opus_get_version_string());
|
||||
|
||||
if (rate > 24000) {
|
||||
coding_rate = 48000;
|
||||
} else if (rate > 16000) {
|
||||
coding_rate = 24000;
|
||||
} else if (rate > 12000) {
|
||||
coding_rate = 16000;
|
||||
} else if (rate > 8000) {
|
||||
coding_rate = 12000;
|
||||
} else {
|
||||
coding_rate = 8000;
|
||||
}
|
||||
|
||||
if (rate != coding_rate) {
|
||||
LOGE("Invalid rate");
|
||||
return 0;
|
||||
}
|
||||
|
||||
header.channels = 1;
|
||||
header.channel_mapping = 0;
|
||||
header.input_sample_rate = rate;
|
||||
header.gain = inopt.gain;
|
||||
header.nb_streams = 1;
|
||||
|
||||
int result = OPUS_OK;
|
||||
_encoder = opus_encoder_create(coding_rate, 1, OPUS_APPLICATION_AUDIO, &result);
|
||||
if (result != OPUS_OK) {
|
||||
LOGE("Error cannot create encoder: %s", opus_strerror(result));
|
||||
return 0;
|
||||
}
|
||||
|
||||
min_bytes = max_frame_bytes = (1275 * 3 + 7) * header.nb_streams;
|
||||
_packet = malloc(max_frame_bytes);
|
||||
|
||||
result = opus_encoder_ctl(_encoder, OPUS_SET_BITRATE(bitrate));
|
||||
if (result != OPUS_OK) {
|
||||
LOGE("Error OPUS_SET_BITRATE returned: %s", opus_strerror(result));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef OPUS_SET_LSB_DEPTH
|
||||
result = opus_encoder_ctl(_encoder, OPUS_SET_LSB_DEPTH(max(8, min(24, inopt.samplesize))));
|
||||
if (result != OPUS_OK) {
|
||||
LOGE("Warning OPUS_SET_LSB_DEPTH returned: %s", opus_strerror(result));
|
||||
}
|
||||
#endif
|
||||
|
||||
opus_int32 lookahead;
|
||||
result = opus_encoder_ctl(_encoder, OPUS_GET_LOOKAHEAD(&lookahead));
|
||||
if (result != OPUS_OK) {
|
||||
LOGE("Error OPUS_GET_LOOKAHEAD returned: %s", opus_strerror(result));
|
||||
return 0;
|
||||
}
|
||||
|
||||
inopt.skip += lookahead;
|
||||
header.preskip = (int)(inopt.skip * (48000.0 / coding_rate));
|
||||
inopt.extraout = (int)(header.preskip * (rate / 48000.0));
|
||||
|
||||
if (ogg_stream_init(&os, rand()) == -1) {
|
||||
LOGE("Error: stream init failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char header_data[100];
|
||||
int packet_size = opus_header_to_packet(&header, header_data, 100);
|
||||
op.packet = header_data;
|
||||
op.bytes = packet_size;
|
||||
op.b_o_s = 1;
|
||||
op.e_o_s = 0;
|
||||
op.granulepos = 0;
|
||||
op.packetno = 0;
|
||||
ogg_stream_packetin(&os, &op);
|
||||
|
||||
while ((result = ogg_stream_flush(&os, &og))) {
|
||||
if (!result) {
|
||||
break;
|
||||
}
|
||||
|
||||
int pageBytesWritten = writeOggPage(&og, _fileOs);
|
||||
if (pageBytesWritten != og.header_len + og.body_len) {
|
||||
LOGE("Error: failed writing header to output stream");
|
||||
return 0;
|
||||
}
|
||||
bytes_written += pageBytesWritten;
|
||||
pages_out++;
|
||||
}
|
||||
|
||||
comment_pad(&inopt.comments, &inopt.comments_length, comment_padding);
|
||||
op.packet = (unsigned char *)inopt.comments;
|
||||
op.bytes = inopt.comments_length;
|
||||
op.b_o_s = 0;
|
||||
op.e_o_s = 0;
|
||||
op.granulepos = 0;
|
||||
op.packetno = 1;
|
||||
ogg_stream_packetin(&os, &op);
|
||||
|
||||
while ((result = ogg_stream_flush(&os, &og))) {
|
||||
if (result == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
int writtenPageBytes = writeOggPage(&og, _fileOs);
|
||||
if (writtenPageBytes != og.header_len + og.body_len) {
|
||||
LOGE("Error: failed writing header to output stream");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bytes_written += writtenPageBytes;
|
||||
pages_out++;
|
||||
}
|
||||
|
||||
free(inopt.comments);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int writeFrame(uint8_t *framePcmBytes, unsigned int frameByteCount) {
|
||||
int cur_frame_size = frame_size;
|
||||
_packetId++;
|
||||
|
||||
opus_int32 nb_samples = frameByteCount / 2;
|
||||
total_samples += nb_samples;
|
||||
if (nb_samples < frame_size) {
|
||||
op.e_o_s = 1;
|
||||
} else {
|
||||
op.e_o_s = 0;
|
||||
}
|
||||
|
||||
int nbBytes = 0;
|
||||
|
||||
if (nb_samples != 0) {
|
||||
uint8_t *paddedFrameBytes = framePcmBytes;
|
||||
int freePaddedFrameBytes = 0;
|
||||
|
||||
if (nb_samples < cur_frame_size) {
|
||||
paddedFrameBytes = malloc(cur_frame_size * 2);
|
||||
freePaddedFrameBytes = 1;
|
||||
memcpy(paddedFrameBytes, framePcmBytes, frameByteCount);
|
||||
memset(paddedFrameBytes + nb_samples * 2, 0, cur_frame_size * 2 - nb_samples * 2);
|
||||
}
|
||||
|
||||
nbBytes = opus_encode(_encoder, (opus_int16 *)paddedFrameBytes, cur_frame_size, _packet, max_frame_bytes / 10);
|
||||
if (freePaddedFrameBytes) {
|
||||
free(paddedFrameBytes);
|
||||
paddedFrameBytes = NULL;
|
||||
}
|
||||
|
||||
if (nbBytes < 0) {
|
||||
LOGE("Encoding failed: %s. Aborting.", opus_strerror(nbBytes));
|
||||
return 0;
|
||||
}
|
||||
|
||||
enc_granulepos += cur_frame_size * 48000 / coding_rate;
|
||||
size_segments = (nbBytes + 255) / 255;
|
||||
min_bytes = min(nbBytes, min_bytes);
|
||||
}
|
||||
|
||||
while ((((size_segments <= 255) && (last_segments + size_segments > 255)) || (enc_granulepos - last_granulepos > max_ogg_delay)) && ogg_stream_flush_fill(&os, &og, 255 * 255)) {
|
||||
if (ogg_page_packets(&og) != 0) {
|
||||
last_granulepos = ogg_page_granulepos(&og);
|
||||
}
|
||||
|
||||
last_segments -= og.header[26];
|
||||
int writtenPageBytes = writeOggPage(&og, _fileOs);
|
||||
if (writtenPageBytes != og.header_len + og.body_len) {
|
||||
LOGE("Error: failed writing data to output stream");
|
||||
return 0;
|
||||
}
|
||||
bytes_written += writtenPageBytes;
|
||||
pages_out++;
|
||||
}
|
||||
|
||||
op.packet = (unsigned char *)_packet;
|
||||
op.bytes = nbBytes;
|
||||
op.b_o_s = 0;
|
||||
op.granulepos = enc_granulepos;
|
||||
if (op.e_o_s) {
|
||||
op.granulepos = ((total_samples * 48000 + rate - 1) / rate) + header.preskip;
|
||||
}
|
||||
op.packetno = 2 + _packetId;
|
||||
ogg_stream_packetin(&os, &op);
|
||||
last_segments += size_segments;
|
||||
|
||||
while ((op.e_o_s || (enc_granulepos + (frame_size * 48000 / coding_rate) - last_granulepos > max_ogg_delay) || (last_segments >= 255)) ? ogg_stream_flush_fill(&os, &og, 255 * 255) : ogg_stream_pageout_fill(&os, &og, 255 * 255)) {
|
||||
if (ogg_page_packets(&og) != 0) {
|
||||
last_granulepos = ogg_page_granulepos(&og);
|
||||
}
|
||||
last_segments -= og.header[26];
|
||||
int writtenPageBytes = writeOggPage(&og, _fileOs);
|
||||
if (writtenPageBytes != og.header_len + og.body_len) {
|
||||
LOGE("Error: failed writing data to output stream");
|
||||
return 0;
|
||||
}
|
||||
bytes_written += writtenPageBytes;
|
||||
pages_out++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
JNIEXPORT int Java_com_b44t_messenger_MediaController_startRecord(JNIEnv *env, jclass class, jstring path) {
|
||||
const char *pathStr = (*env)->GetStringUTFChars(env, path, 0);
|
||||
|
||||
int result = initRecorder(pathStr);
|
||||
|
||||
if (pathStr != 0) {
|
||||
(*env)->ReleaseStringUTFChars(env, path, pathStr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT int Java_com_b44t_messenger_MediaController_writeFrame(JNIEnv *env, jclass class, jobject frame, jint len) {
|
||||
jbyte *frameBytes = (*env)->GetDirectBufferAddress(env, frame);
|
||||
return writeFrame(frameBytes, len);
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_com_b44t_messenger_MediaController_stopRecord(JNIEnv *env, jclass class) {
|
||||
cleanupRecorder();
|
||||
}
|
||||
|
||||
//player
|
||||
static OggOpusFile *_opusFile;
|
||||
static int _isSeekable = 0;
|
||||
static int64_t _totalPcmDuration = 0;
|
||||
static int64_t _currentPcmOffset = 0;
|
||||
static int _finished = 0;
|
||||
static const int playerBuffersCount = 3;
|
||||
static const int playerSampleRate = 48000;
|
||||
|
||||
static void cleanupPlayer() {
|
||||
if (_opusFile) {
|
||||
op_free(_opusFile);
|
||||
_opusFile = 0;
|
||||
}
|
||||
_isSeekable = 0;
|
||||
_totalPcmDuration = 0;
|
||||
_currentPcmOffset = 0;
|
||||
_finished = 0;
|
||||
}
|
||||
|
||||
static int seekPlayer(float position) {
|
||||
if (!_opusFile || !_isSeekable || position < 0) {
|
||||
return 0;
|
||||
}
|
||||
int result = op_pcm_seek(_opusFile, (ogg_int64_t)(position * _totalPcmDuration));
|
||||
if (result != OPUS_OK) {
|
||||
LOGE("op_pcm_seek failed: %d", result);
|
||||
}
|
||||
ogg_int64_t pcmPosition = op_pcm_tell(_opusFile);
|
||||
_currentPcmOffset = pcmPosition;
|
||||
return result == OPUS_OK;
|
||||
}
|
||||
|
||||
static int initPlayer(const char *path) {
|
||||
cleanupPlayer();
|
||||
|
||||
int openError = OPUS_OK;
|
||||
_opusFile = op_open_file(path, &openError);
|
||||
if (!_opusFile || openError != OPUS_OK) {
|
||||
LOGE("op_open_file failed: %d", openError);
|
||||
cleanupPlayer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
_isSeekable = op_seekable(_opusFile);
|
||||
_totalPcmDuration = op_pcm_total(_opusFile, -1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void fillBuffer(uint8_t *buffer, int capacity, int *args) {
|
||||
if (_opusFile) {
|
||||
args[1] = max(0, op_pcm_tell(_opusFile));
|
||||
|
||||
if (_finished) {
|
||||
args[0] = 0;
|
||||
args[1] = 0;
|
||||
args[2] = 1;
|
||||
return;
|
||||
} else {
|
||||
int writtenOutputBytes = 0;
|
||||
int endOfFileReached = 0;
|
||||
|
||||
while (writtenOutputBytes < capacity) {
|
||||
int readSamples = op_read(_opusFile, (opus_int16 *)(buffer + writtenOutputBytes), (capacity - writtenOutputBytes) / 2, NULL);
|
||||
|
||||
if (readSamples > 0) {
|
||||
writtenOutputBytes += readSamples * 2;
|
||||
} else {
|
||||
if (readSamples < 0) {
|
||||
LOGE("op_read failed: %d", readSamples);
|
||||
}
|
||||
endOfFileReached = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
args[0] = writtenOutputBytes;
|
||||
|
||||
if (endOfFileReached || args[1] + args[0] == _totalPcmDuration) {
|
||||
_finished = 1;
|
||||
args[2] = 1;
|
||||
} else {
|
||||
args[2] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
memset(buffer, 0, capacity);
|
||||
args[0] = capacity;
|
||||
args[1] = _totalPcmDuration;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jlong Java_com_b44t_messenger_MediaController_getTotalPcmDuration(JNIEnv *env, jclass class) {
|
||||
return _totalPcmDuration;
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_com_b44t_messenger_MediaController_readOpusFile(JNIEnv *env, jclass class, jobject buffer, jint capacity, jintArray args) {
|
||||
jint *argsArr = (*env)->GetIntArrayElements(env, args, 0);
|
||||
jbyte *bufferBytes = (*env)->GetDirectBufferAddress(env, buffer);
|
||||
fillBuffer(bufferBytes, capacity, argsArr);
|
||||
(*env)->ReleaseIntArrayElements(env, args, argsArr, 0);
|
||||
}
|
||||
|
||||
JNIEXPORT int Java_com_b44t_messenger_MediaController_seekOpusFile(JNIEnv *env, jclass class, jfloat position) {
|
||||
return seekPlayer(position);
|
||||
}
|
||||
|
||||
JNIEXPORT int Java_com_b44t_messenger_MediaController_openOpusFile(JNIEnv *env, jclass class, jstring path) {
|
||||
const char *pathStr = (*env)->GetStringUTFChars(env, path, 0);
|
||||
|
||||
int result = initPlayer(pathStr);
|
||||
|
||||
if (pathStr != 0) {
|
||||
(*env)->ReleaseStringUTFChars(env, path, pathStr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_com_b44t_messenger_MediaController_closeOpusFile(JNIEnv *env, jclass class) {
|
||||
cleanupPlayer();
|
||||
}
|
||||
|
||||
JNIEXPORT int Java_com_b44t_messenger_MediaController_isOpusFile(JNIEnv *env, jclass class, jstring path) {
|
||||
const char *pathStr = (*env)->GetStringUTFChars(env, path, 0);
|
||||
|
||||
int result = 0;
|
||||
|
||||
int error = OPUS_OK;
|
||||
OggOpusFile *file = op_test_file(pathStr, &error);
|
||||
if (file != NULL) {
|
||||
int error = op_test_open(file);
|
||||
op_free(file);
|
||||
|
||||
result = error == OPUS_OK;
|
||||
}
|
||||
|
||||
if (pathStr != 0) {
|
||||
(*env)->ReleaseStringUTFChars(env, path, pathStr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline void set_bits(uint8_t *bytes, int32_t bitOffset, int32_t value) {
|
||||
bytes += bitOffset / 8;
|
||||
bitOffset %= 8;
|
||||
*((int32_t *) bytes) |= (value << bitOffset);
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray Java_com_b44t_messenger_MediaController_getWaveform2(JNIEnv *env, jclass class, jshortArray array, jint length) {
|
||||
|
||||
jshort *sampleBuffer = (*env)->GetShortArrayElements(env, array, 0);
|
||||
|
||||
jbyteArray result = 0;
|
||||
int32_t resultSamples = 100;
|
||||
uint16_t *samples = malloc(100 * 2);
|
||||
uint64_t sampleIndex = 0;
|
||||
uint16_t peakSample = 0;
|
||||
int32_t sampleRate = (int32_t) max(1, length / resultSamples);
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
uint16_t sample = (uint16_t) abs(sampleBuffer[i]);
|
||||
if (sample > peakSample) {
|
||||
peakSample = sample;
|
||||
}
|
||||
if (sampleIndex++ % sampleRate == 0) {
|
||||
if (index < resultSamples) {
|
||||
samples[index++] = peakSample;
|
||||
}
|
||||
peakSample = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t sumSamples = 0;
|
||||
for (int i = 0; i < resultSamples; i++) {
|
||||
sumSamples += samples[i];
|
||||
}
|
||||
uint16_t peak = (uint16_t) (sumSamples * 1.8f / resultSamples);
|
||||
if (peak < 2500) {
|
||||
peak = 2500;
|
||||
}
|
||||
|
||||
for (int i = 0; i < resultSamples; i++) {
|
||||
uint16_t sample = (uint16_t) ((int64_t) samples[i]);
|
||||
if (sample > peak) {
|
||||
samples[i] = peak;
|
||||
}
|
||||
}
|
||||
|
||||
(*env)->ReleaseShortArrayElements(env, array, sampleBuffer, 0);
|
||||
|
||||
int bitstreamLength = (resultSamples * 5) / 8 + (((resultSamples * 5) % 8) == 0 ? 0 : 1);
|
||||
result = (*env)->NewByteArray(env, bitstreamLength);
|
||||
jbyte *bytes = (*env)->GetByteArrayElements(env, result, NULL);
|
||||
|
||||
for (int i = 0; i < resultSamples; i++) {
|
||||
int32_t value = min(31, abs((int32_t) samples[i]) * 31 / peak);
|
||||
set_bits(bytes, i * 5, value & 31);
|
||||
}
|
||||
|
||||
(*env)->ReleaseByteArrayElements(env, result, bytes, JNI_COMMIT);
|
||||
free(samples);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int16_t *sampleBuffer = NULL;
|
||||
|
||||
|
||||
JNIEXPORT jbyteArray Java_com_b44t_messenger_MediaController_getWaveform(JNIEnv *env, jclass class, jstring path) {
|
||||
const char *pathStr = (*env)->GetStringUTFChars(env, path, 0);
|
||||
jbyteArray result = 0;
|
||||
|
||||
int error = OPUS_OK;
|
||||
OggOpusFile *opusFile = op_open_file(pathStr, &error);
|
||||
if (opusFile != NULL && error == OPUS_OK) {
|
||||
int64_t totalSamples = op_pcm_total(opusFile, -1);
|
||||
int32_t resultSamples = 100;
|
||||
int32_t sampleRate = (int32_t) max(1, totalSamples / resultSamples);
|
||||
|
||||
uint16_t *samples = malloc(100 * 2);
|
||||
|
||||
int bufferSize = 1024 * 128;
|
||||
if (sampleBuffer == NULL) {
|
||||
sampleBuffer = malloc(bufferSize);
|
||||
}
|
||||
uint64_t sampleIndex = 0;
|
||||
uint16_t peakSample = 0;
|
||||
|
||||
int index = 0;
|
||||
|
||||
while (1) {
|
||||
int readSamples = op_read(opusFile, sampleBuffer, bufferSize / 2, NULL);
|
||||
for (int i = 0; i < readSamples; i++) {
|
||||
uint16_t sample = (uint16_t) abs(sampleBuffer[i]);
|
||||
if (sample > peakSample) {
|
||||
peakSample = sample;
|
||||
}
|
||||
if (sampleIndex++ % sampleRate == 0) {
|
||||
if (index < resultSamples) {
|
||||
samples[index++] = peakSample;
|
||||
}
|
||||
peakSample = 0;
|
||||
}
|
||||
}
|
||||
if (readSamples == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t sumSamples = 0;
|
||||
for (int i = 0; i < resultSamples; i++) {
|
||||
sumSamples += samples[i];
|
||||
}
|
||||
uint16_t peak = (uint16_t) (sumSamples * 1.8f / resultSamples);
|
||||
if (peak < 2500) {
|
||||
peak = 2500;
|
||||
}
|
||||
|
||||
for (int i = 0; i < resultSamples; i++) {
|
||||
uint16_t sample = (uint16_t) ((int64_t) samples[i]);
|
||||
if (sample > peak) {
|
||||
samples[i] = peak;
|
||||
}
|
||||
}
|
||||
|
||||
//free(sampleBuffer);
|
||||
op_free(opusFile);
|
||||
|
||||
int bitstreamLength = (resultSamples * 5) / 8 + (((resultSamples * 5) % 8) == 0 ? 0 : 1);
|
||||
result = (*env)->NewByteArray(env, bitstreamLength);
|
||||
jbyte *bytes = (*env)->GetByteArrayElements(env, result, NULL);
|
||||
|
||||
for (int i = 0; i < resultSamples; i++) {
|
||||
int32_t value = min(31, abs((int32_t) samples[i]) * 31 / peak);
|
||||
set_bits(bytes, i * 5, value & 31);
|
||||
}
|
||||
|
||||
(*env)->ReleaseByteArrayElements(env, result, bytes, JNI_COMMIT);
|
||||
free(samples);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (pathStr != 0) {
|
||||
(*env)->ReleaseStringUTFChars(env, path, pathStr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
Rob Siemborski <rjs3+@andrew.cmu.edu> wrote and tested the conversion
|
||||
to the SASLv2 API.
|
||||
|
||||
Ken Murchison <murch@andrew.cmu.edu> worked on the OTP, NTLM, SRP and SQL
|
||||
plugins, as well as helping to track down bugs as they appear. He also
|
||||
added support for HTTP authentication.
|
||||
|
||||
Rob Earhart <earhart@cmu.edu> wrote the build/installation procedure,
|
||||
wrote and tested some of the code, and provided general guidance and
|
||||
coding advice.
|
||||
|
||||
Leif Johansson <leifj@matematik.su.se> wrote the GSSAPI plugin, with
|
||||
contributions from Sam Hartman <hartmans@fundsxpress.com>.
|
||||
|
||||
Leandro Santi <lesanti@sinectis.com.ar> added Courier authdaemon support.
|
||||
|
||||
Alexey Melnikov <alexey.melnikov@isode.com> wrote the first pass of the
|
||||
DIGEST-MD5 plugin and continues to work on it. He also wrote
|
||||
a good deal of the current Windows support.
|
||||
|
||||
Rainer Schoepf <schoepf@uni-mainz.de> contributed the LOGIN plugin,
|
||||
based on Tim Martin's PLAIN plugin.
|
||||
|
||||
Simon Loader <simon@surf.org.uk> wrote the MySQL auxprop module.
|
||||
|
||||
Rolf Braun <rbraun@andrew.cmu.edu> wrote the MacOS ports.
|
||||
|
||||
Howard Chu <hyc@highlandsun.com> put a good deal of work into OS/390
|
||||
portability, correct building of static libraries, and a slew
|
||||
of misc. bugfixes.
|
||||
|
||||
Tim Martin <tmartin@andrew.cmu.edu> wrote, debugged, and tested
|
||||
most of the SASLv1 code.
|
||||
|
||||
Larry Greenfield <leg+sasl@andrew.cmu.edu> complained. a lot.
|
||||
|
||||
Chris Newman <chris.newman@oracle.com> wrote the initial version of the
|
||||
SASL API, as well as the version 2 SASL API (documented in sasl.h,
|
||||
saslutil.h, saslplug.h, and prop.h).
|
||||
|
||||
Ryan Troll <ryan@andrew.cmu.edu> started the Windows port,
|
||||
and both Larry Greenfield and Alexey Melnikov have done more work on it.
|
||||
|
||||
getaddrinfo.c was written by Hajimu UMEMOTO <ume@mahoroba.org>
|
||||
which is based on the IPv6 code written by KIKUCHI Takahiro
|
||||
<kick@kyoto.wide.ad.jp>
|
||||
|
||||
$Id: AUTHORS,v 1.18 2006/12/01 17:34:58 mel Exp $
|
||||
@@ -0,0 +1,44 @@
|
||||
/* CMU libsasl
|
||||
* Tim Martin
|
||||
* Rob Earhart
|
||||
* Rob Siemborski
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,302 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Briefly, the shell commands `./configure; make; make install' should
|
||||
configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
instructions specific to this package.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system.
|
||||
|
||||
Running `configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
6. Often, you can also type `make uninstall' to remove the installed
|
||||
files again.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
On MacOS X 10.5 and later systems, you can create libraries and
|
||||
executables that work on multiple system types--known as "fat" or
|
||||
"universal" binaries--by specifying multiple `-arch' options to the
|
||||
compiler but only a single `-arch' option to the preprocessor. Like
|
||||
this:
|
||||
|
||||
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
CPP="gcc -E" CXXCPP="g++ -E"
|
||||
|
||||
This is not guaranteed to produce working output in all cases, you
|
||||
may have to build one architecture at a time and combine the results
|
||||
using the `lipo' tool if you have problems.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Particular systems
|
||||
==================
|
||||
|
||||
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
|
||||
CC is not installed, it is recommended to use the following options in
|
||||
order to use an ANSI C compiler:
|
||||
|
||||
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
|
||||
|
||||
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||
|
||||
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
|
||||
a workaround. If GNU CC is not installed, it is therefore recommended
|
||||
to try
|
||||
|
||||
./configure CC="cc"
|
||||
|
||||
and if that doesn't work, try
|
||||
|
||||
./configure CC="cc -nodtk"
|
||||
|
||||
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
|
||||
directory contains several dysfunctional programs; working variants of
|
||||
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
|
||||
in your `PATH', put it _after_ `/usr/bin'.
|
||||
|
||||
On Haiku, software installed for all users goes in `/boot/common',
|
||||
not `/usr/local'. It is recommended to use the following options:
|
||||
|
||||
./configure --prefix=/boot/common
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS
|
||||
KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||
|
||||
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of all of the options to `configure', and exit.
|
||||
|
||||
`--help=short'
|
||||
`--help=recursive'
|
||||
Print a summary of the options unique to this package's
|
||||
`configure', and exit. The `short' variant lists options used
|
||||
only in the top level, while the `recursive' variant lists options
|
||||
also present in any nested packages.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--prefix=DIR'
|
||||
Use DIR as the installation prefix. *Note Installation Names::
|
||||
for more details, including other options available for fine-tuning
|
||||
the installation locations.
|
||||
|
||||
`--no-create'
|
||||
`-n'
|
||||
Run the configure checks, but stop before creating any output
|
||||
files.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
For installation instructions, see doc/install.html.
|
||||
@@ -0,0 +1,503 @@
|
||||
New in 2.1.26
|
||||
-------------
|
||||
|
||||
* Modernize SASL malloc/realloc callback prototypes
|
||||
* Added sasl_config_done() to plug a memory leak when using an application
|
||||
specific config file
|
||||
* Fixed PLAIN/LOGIN authentication failure when using saslauthd
|
||||
with no auxprop plugins (bug # 3590).
|
||||
* unlock the mutex in sasl_dispose if the context was freed by another thread
|
||||
* MINGW32 compatibility patches
|
||||
* Fixed broken logic in get_fqhostname() when abort_if_no_fqdn is 0
|
||||
* Fixed some memory leaks in libsasl
|
||||
* GSSAPI plugin:
|
||||
- Fixed a segfault in gssapi.c introduced in 2.1.25.
|
||||
- Code refactoring
|
||||
- Added support for GSS-SPNEGO SASL mechanism (Unix only), which is also
|
||||
HTTP capable
|
||||
* GS2 plugin:
|
||||
- Updated GS2 plugin not to lose minor GSS-API status codes on errors
|
||||
* DIGEST-MD5 plugin:
|
||||
- Correctly send "stale" directive to prevent clients from (re)promtping
|
||||
for password
|
||||
- Better handling of HTTP reauthentication cases
|
||||
- fixed some memory leaks
|
||||
* SASLDB plugin:
|
||||
- Added support for BerkleyDB 5.X or later
|
||||
* OTP plugin:
|
||||
- Removed calling of EVP_cleanup() on plugin shutdown in order to prevent
|
||||
TLS from failing in calling applications
|
||||
* SRP plugin:
|
||||
- Removed calling of EVP_cleanup() on plugin shutdown in order to prevent
|
||||
TLS from failing in calling applications
|
||||
* saslauthd:
|
||||
- auth_rimap.c: qstring incorrectly appending the closing double quote,
|
||||
which might be causing crashes
|
||||
- auth_rimap.c: read the whole IMAP greeting
|
||||
- better error reporting from some drivers
|
||||
- fixed some memory leaks
|
||||
|
||||
New in 2.1.25
|
||||
-------------
|
||||
|
||||
* Make sure that a failed authorization doesn't preclude
|
||||
further server-side SASL authentication attempts from working.
|
||||
* Fixed a crash caused by aborted SASL authentication
|
||||
and initiation of another one using the same SASL context.
|
||||
* (Windows) Fixed the random number generator to actually produce random
|
||||
output on each run.
|
||||
* Be protective against calling sasl_server_step once authentication
|
||||
has failed (multiple SASL plugins)
|
||||
* Fixed several bugs in the mech_avail callback handling
|
||||
in the server side code.
|
||||
* Added support for channel bindings
|
||||
* Added support for ordering SASL mechanisms by strength (on the client side),
|
||||
or using the "client_mech_list" option.
|
||||
* server_idle needs to obey server's SASL mechanism list from the server
|
||||
context.
|
||||
* Better server plugin API mismatch reporting
|
||||
* Build:
|
||||
- Updated config to the latest GNU snapshot
|
||||
- Fixed SASL's libtool MacOS/X 64-bit file magic
|
||||
* New SASL plugin: SCRAM
|
||||
* New SASL plugin: GS2
|
||||
* DIGEST-MD5 plugin:
|
||||
- Allow DIGEST-MD5 plugin to be used for client-side and
|
||||
server-side HTTP Digest, including running over non-persistent
|
||||
connections (RFC 2617)
|
||||
- Use the same username for reauthentication cache lookup and update
|
||||
- Minimize the number of auxprop lookups in the server side DIGEST-MD5
|
||||
plugin for the most common case when authentication and authorization
|
||||
identities are the same.
|
||||
- Updated digestmd5_server_mech_step2() to be more defensive against
|
||||
empty client input.
|
||||
- Fixed some memory leaks on failed plugin initialization.
|
||||
Prevent potential race condition when freeding plugin state.
|
||||
Set the freed reauthentication cache mutex to NULL, to make errors
|
||||
due to mutex access after free more obvious.
|
||||
- Test against broken UTF-8 based hashes if calculation using special
|
||||
ISO-8859-1 code fails.
|
||||
- Fixed an interop problem with some LDAP clients ignoring server
|
||||
advertised realm and providing their own.
|
||||
* GSSAPI plugin:
|
||||
- Fix to build GSSAPI with Heimdal
|
||||
- Properly set serveroutlen to 0 in one place.
|
||||
Don't send empty challenge once server context establishment is done,
|
||||
as this is in violation of the RFC 2222 and its successor.
|
||||
- Don't send maxbuf, if no security layer can be established.
|
||||
Added additional checks for buffer lengths.
|
||||
* LDAPDB plugin:
|
||||
- build fixes
|
||||
|
||||
New in 2.1.24
|
||||
-------------
|
||||
|
||||
* Order advertised server-side SASL mechanisms per the specified 'mech_list'
|
||||
option or by relative "strength"
|
||||
* Make sure that sasl_set_alloc() has no effect once sasl_client_init()
|
||||
or sasl_server_init() is called
|
||||
* Fixed sasl_set_mutex() to disallow changing mutex management functions
|
||||
once sasl_server_init()/sasl_client_init() is called (bug # 3083)
|
||||
* Removed unused mutexes in lib/client.c and lib/server.c (bug # 3141)
|
||||
* Added direct support for hashed password to auxprop API
|
||||
* Don't treat a constraint violation as an error to store an auxprop property
|
||||
* Extended libsasl (auxprop) to support user deletion
|
||||
* Extended SASL auxprop_lookup to return error code
|
||||
* Updated sasl_user_exists() so that it can handle passwordless accounts (e.g. disabled)
|
||||
* (Windows) Free handles of shared libraries on Windows that were loaded
|
||||
but are not SASL plugins (bug # 2089)
|
||||
* Prevent freeing of common state on a subsequent call to _sasl_common_init.
|
||||
Make sure that the last global callback always wins.
|
||||
* Implemented sasl_client_done()/sasl_server_done()
|
||||
* Added automatic hostname canonicalization inside libsasl
|
||||
* Made sasl_config_init() public
|
||||
* Strip trailing spaces from server config file option values (bug # 3139, bug # 3041)
|
||||
* Fixed potential buffer overflow in saslautd_verify_password().
|
||||
* Fixed segfault in dlclose() on HPUX
|
||||
* Various bugfixes for 64bit platforms
|
||||
* Fixed bug # 2895 (passing LF to sasl_decode64) in sample/sample-client.c,
|
||||
sample/sample-server.c, utils/smtptest.c
|
||||
* pluginviewer: Code cleanup, improved human readable messages
|
||||
* Build:
|
||||
- (Windows) Updated makefiles to build with VC 8.0 (VC++ 2005)
|
||||
- (Windows) Added Windows64 build
|
||||
- Updated to use .plugin extension on MacOS
|
||||
- Changed 64bit HP-UX build to use .so for shared libraries
|
||||
* saslauthd:
|
||||
- Fixed bug counting double-quotes in username/password in
|
||||
auth_rimap.c. Also fixed bug zeroing password.
|
||||
- auth_krb.c: improved diagnostic in the k5support_verify_tgt() function.
|
||||
- auth_sasldb.c: pid_file_lock is created with a mask of 644 instead of 0644
|
||||
- auth_shadow.c: Define _XOPEN_SOURCE before including unistd.h,
|
||||
so that crypt is correctly defined
|
||||
- auth_getpwent.c: Fixed Solaris build
|
||||
* SASLDB plugin:
|
||||
- Fixed spurious 'user not found' errors caused by an attempt
|
||||
to delete a non-existent property
|
||||
- Added direct support for hashed password to auxprop API
|
||||
- Sleepycat driver: Return SASL_NOUSER instead of SASL_FAIL when the database
|
||||
file doesn't exist
|
||||
- Ignore properties starting with '*' in the auxprop store function
|
||||
* SQL plugin:
|
||||
- Added support for SQLITE3
|
||||
- Uninitialized variables can cause crash when the searched user is not found
|
||||
- Added direct support for hashed password
|
||||
- Ignore properties starting with '*' in the auxprop store function
|
||||
* LDAPDB plugin:
|
||||
- Added code to extend LDAPDB into a canon_user plugin in addition
|
||||
to its existing auxprop plugin functionality
|
||||
* PLAIN plugin:
|
||||
- Advertise SASL_SEC_PASS_CREDENTIALS feature
|
||||
* LOGIN plugin:
|
||||
- Advertise SASL_SEC_PASS_CREDENTIALS feature
|
||||
* DIGEST-MD5 plugin:
|
||||
- Fixed a memory leak in the DIGEST-MD5 security layer
|
||||
- Fixed memory leaks in client-side reauth and other places
|
||||
- More detailed error reporting.
|
||||
- Fixed parsing of challenges/responses with extra commas.
|
||||
- Allow for multiple qop options from the server and require
|
||||
a single qop option from the client.
|
||||
* GSSAPI plugin:
|
||||
- Check that params->serverFQDN is not NULL before using strlen on it
|
||||
- Make auxprop lookup calls optional
|
||||
* EXTERNAL plugin:
|
||||
- Make auxprop lookup calls optional
|
||||
* NTLM plugin:
|
||||
- allow a comma separated list of servernames in 'ntlm_server' option
|
||||
- Fixed crash in calculating NTv2 reponse
|
||||
* OTP plugin:
|
||||
- Don't use a stack variable for an OTP prompt (bug # 2822)
|
||||
- Downgrade the failure to store OTP secret to debug level
|
||||
* KERBEROS_V4 plugin:
|
||||
- Make auxprop lookup calls optional
|
||||
|
||||
New in 2.1.23
|
||||
-------------
|
||||
|
||||
* Fixed CERT VU#238019 (make sure sasl_encode64() always NUL
|
||||
terminates output or returns SASL_BUFOVER)
|
||||
|
||||
New in 2.1.22
|
||||
-------------
|
||||
|
||||
* Added support for spliting big data blocks (bigger than maxbuf)
|
||||
into multiple SASL packets in sasl_encodev
|
||||
* Various sasl_decode64() fixes
|
||||
* Increase canonicalization buffer size to 1024 bytes
|
||||
* Call do_authorization() after successful APOP authentication
|
||||
* Allow for configuration file location to be configurable independently
|
||||
of plugin location (bug # 2795)
|
||||
* Added sasl_set_path function, which provides a more convenient way
|
||||
of setting plugin and config paths. Changed the default
|
||||
sasl_getpath_t/sasl_getconfpath_t callbacks to calculate
|
||||
the value only once and cache it for later use.
|
||||
* Fixed load_config to search for the config file in all directories
|
||||
(bug # 2796). Changed the default search path to be
|
||||
/usr/lib/sasl2:/etc/sasl2
|
||||
* Don't ignore log_level configuration option in default UNIX syslog
|
||||
logging callback
|
||||
* (Windows) Minor IPv6 related changes in Makefiles for Visual Studio 6
|
||||
* (Windows) Fixed bug of not setting the CODEGEN (code generation option)
|
||||
nmake option if STATIC nmake option is set.
|
||||
* Several fixed to DIGEST-MD5 plugin:
|
||||
- Enable RC4 cipher in Windows build of DIGEST-MD5
|
||||
- Server side: handle missing realm option as if realm="" was sent
|
||||
- Fix DIGEST-MD5 to properly advertise maxssf when both DES and RC4
|
||||
are disabled
|
||||
- Check that DIGEST-MD5 SASL packet are no shorter than 16 bytes
|
||||
* Several changes/fixed to SASLDB plugin:
|
||||
- Prevent spurious SASL_NOUSER errors
|
||||
- Added ability to keep BerkleyDB handle open between operations
|
||||
(for performance reason). New behavior can be enabled
|
||||
with --enable-keep-db-open.
|
||||
* Better error checking in SQL (MySQL) auxprop plugin code
|
||||
* Added support for HTTP POST password validation in saslauthd
|
||||
* Added new application ("pluginviewer") that helps report information
|
||||
about installed plugins
|
||||
* Allow for building with OpenSSL 0.9.8
|
||||
* Allow for building with OpenLDAP 2.3+
|
||||
* Several quoting fixes to configure script
|
||||
* A large number of other minor bugfixes and cleanups
|
||||
|
||||
New in 2.1.21
|
||||
-------------
|
||||
* Fixes DIGEST-MD5 server side segfault caused by the client not sending
|
||||
any realms
|
||||
* Minor Other bugfixes
|
||||
|
||||
New in 2.1.20
|
||||
-------------
|
||||
* Fixes to cram plugin to avoid attempting to canonify uninitialized data.
|
||||
* NTLM portability fixes.
|
||||
* Avoid potential attack using SASL_PATH when sasl is used in a setuid
|
||||
environment.
|
||||
* A trivial number of small bugfixes.
|
||||
|
||||
New in 2.1.19
|
||||
-------------
|
||||
* Fixes to saslauthd to allow better integration with realms (-r flag to
|
||||
saslauthd, %R token in LDAP module)
|
||||
* Support for forwarding of GSSAPI credentials
|
||||
* SQLite support for the SQL plugin
|
||||
* A nontrivial number of small bugfixes.
|
||||
|
||||
New in 2.1.18
|
||||
-------------
|
||||
* saslauthd/LDAP no longer tagged "experimental"
|
||||
* Add group membership check to saslauthd/LDAP
|
||||
* Fix Solaris 9 "NI_WITHSCOPEID" issue
|
||||
* Fix missing "getaddrinfo.c" and other distribution problems
|
||||
* Significant Windows enhancements
|
||||
* A large number of other minor bugfixes and cleanups
|
||||
|
||||
New in 2.1.17
|
||||
-------------
|
||||
* Allow selection of GSSAPI implementation explicitly (--with-gss_impl)
|
||||
* Other GSSAPI detection improvements
|
||||
* Now correctly do authorizaton callback in sasl_checkpass()
|
||||
* Disable KERBEROS_V4 by default
|
||||
* Continued Win32/Win64 Improvements
|
||||
* Minor Other bugfixes
|
||||
|
||||
New in 2.1.16-BETA
|
||||
------------------
|
||||
* Significantly improved Win32 support
|
||||
* Writable auxprop support
|
||||
* Expanded SQL support (including postgres)
|
||||
* Significantly improved documentation
|
||||
* Improved realm/username handling with saslauthd
|
||||
* Support for modern automake and autoconf
|
||||
|
||||
New in 2.1.15
|
||||
-------------
|
||||
* Fix a number of build issues
|
||||
* Add a doc/components.html that hopefully describes how things
|
||||
interact better.
|
||||
|
||||
New in 2.1.14
|
||||
-------------
|
||||
* OS X 10.2 support
|
||||
* Support for the Sun SEAM GSSAPI implementation
|
||||
* Support for MySQL 4
|
||||
* A number of build fixes
|
||||
* Other minor bugfixes
|
||||
|
||||
New in 2.1.13
|
||||
-------------
|
||||
* Add a configure option to allow specification of what /dev/random to use.
|
||||
* Addition of a saslauthd credential cache feature (-c option).
|
||||
* Unification of the saslauthd ipc method code.
|
||||
* Fix a number of autoconf issues.
|
||||
* A significant number of fixes throughout the library from Sun Microsystems.
|
||||
* Other minor bugfixes.
|
||||
|
||||
New in 2.1.12
|
||||
-------------
|
||||
* Distribute in Solaris tar (not GNU tar format)
|
||||
* Fix a number of build/configure related issues.
|
||||
|
||||
New in 2.1.11
|
||||
-------------
|
||||
* Add the fastbind auth method to the saslauthd LDAP module.
|
||||
* Fix a potential memory leak in the doors version of saslauthd.
|
||||
* NTLM now only requires one of LM or NT, not both.
|
||||
* Fix a variety of Berkeley DB, LDAP, OpenSSL, and other build issues.
|
||||
* Win32 support compiles, but no documentation as of yet.
|
||||
|
||||
New in 2.1.10
|
||||
-------------
|
||||
* Further DIGEST-MD5 DES interoperability fixes. Now works against Active
|
||||
Directory.
|
||||
* Fix some potential buffer overflows.
|
||||
* Misc. cleanups in the saslauthd LDAP module
|
||||
* Fix security properties of NTLM and EXTERNAL
|
||||
|
||||
New in 2.1.9
|
||||
------------
|
||||
* Include missing lib/staticopen.h file.
|
||||
|
||||
New in 2.1.8
|
||||
------------
|
||||
* Support for the NTLM mechanism (Ken Murchison <ken@oceana.com>)
|
||||
* Support libtool --enable-shared and --enable-static
|
||||
(Howard Chu <hyc@highlandsun.com>)
|
||||
* OS/390 Support (Howard Chu <hyc@highlandsun.com>)
|
||||
* Berkeley DB 4.1 Support (Mika Iisakkila <mika.iisakkila@pingrid.fi>)
|
||||
* Documentation fixes
|
||||
* The usual round of assorted other minor bugfixes.
|
||||
|
||||
New in 2.1.7
|
||||
------------
|
||||
* Add SASL_AUTHUSER as a parameter to sasl_getprop
|
||||
* Allow applications to require proxy-capable mechanisms (SASL_NEED_PROXY)
|
||||
* Performance improvements in our treatment of /dev/random
|
||||
* Removal of buggy DIGEST-MD5 reauth support.
|
||||
* Documentation fixes
|
||||
* Assorted other minor bugfixes.
|
||||
|
||||
New in 2.1.6
|
||||
------------
|
||||
* Security fix for the CRAM-MD5 plugin to check the full length of the
|
||||
digest string.
|
||||
* Return of the Experimental LDAP saslauthd module.
|
||||
* Addition of Experimental MySQL auxprop plugin.
|
||||
* Can now select multiple auxprop plugins (and a priority ordering)
|
||||
* Mechanism selection now includes number of security flags
|
||||
* Mac OS X 10.1 Fixes
|
||||
* Misc other minor bugfixes.
|
||||
|
||||
New in 2.1.5
|
||||
------------
|
||||
* Remove LDAP support due to copyright concerns.
|
||||
* Minor bugfixes.
|
||||
|
||||
New in 2.1.4
|
||||
------------
|
||||
* Enhancements and cleanup to the experimental LDAP saslauthd module
|
||||
(Igor Brezac <igor@ipass.net>)
|
||||
* Addition of a new sasl_version() API
|
||||
* Misc. Bugfixes
|
||||
|
||||
New in 2.1.3-BETA
|
||||
-----------------
|
||||
* Significant amount of plugin cleanup / standardization. A good deal of code
|
||||
is now shared between them. (mostly due to Ken Murchison <ken@oceana.com>)
|
||||
* DIGEST-MD5 now supports reauthentication. Also has a fix for DES
|
||||
interoperability.
|
||||
* saslauthd now supports the Solaris "doors" IPC method
|
||||
(--with-ipctype=doors)
|
||||
* Significant GSSAPI fixes (mostly due to Howard Chu <hyc@highlandsun.com>)
|
||||
* Auxprop interface now correctly deals with the * prefix indicating
|
||||
authid vs. authzid. (May break some incompatible auxprop plugins).
|
||||
* We now allow multiple pwcheck_method(s). Also you can restrict auxprop
|
||||
plugins to the use of a single plugin.
|
||||
* Added an experimental saslauthd LDAP module (Igor Brezac <igor@ipass.net>)
|
||||
* Removed check for db3/db.h
|
||||
* Misc. documentation updates. (Marshall Rose, and others)
|
||||
* Other misc. bugfixes.
|
||||
|
||||
New in 2.1.2
|
||||
------------
|
||||
* Mostly a minor-bugfix release
|
||||
* Improved documentation / cleanup of old references to obsolete
|
||||
pwcheck_methods
|
||||
* Better error reporting for auxprop password verifiers
|
||||
|
||||
New in 2.1.1
|
||||
------------
|
||||
* Many minor bugfixes throughout.
|
||||
* Improvements to OTP and SRP mechanisms (now compliant with
|
||||
draft-burdis-cat-srp-sasl-06.txt)
|
||||
* API additions including sasl_global_listmech, and a cleaner handling of
|
||||
client-first and server-last semantics (no application level changes)
|
||||
* Minor documentation improvements
|
||||
|
||||
New in 2.1.0
|
||||
------------
|
||||
* The Cyrus SASL library is now considered stable. It is still not backwards
|
||||
compatible with applications that require SASLv1.
|
||||
* Minor API changes occured, namely the canon_user callback interface.
|
||||
* saslauthd now preforks a number of processes to handle connections
|
||||
* Many bugfixes through the entire library.
|
||||
|
||||
New in 2.0.5-BETA
|
||||
-----------------
|
||||
* THIS IS A BETA-QUALITY RELEASE THAT IS NOT INTENDED FOR PRODUCTION USE.
|
||||
IT *WILL BREAK* ANY APPLICATION EXPECTING THE SASLv1 API.
|
||||
* Improved performance of security layers in KERBEROS_V4, GSSAPI, and DIGEST.
|
||||
* This release includes an OTP plugin that requires libopie.
|
||||
* SRP plugin now in alpha stage.
|
||||
* Includes many significant bugfixes throughout the library.
|
||||
|
||||
New in 2.0.4-BETA
|
||||
-----------------
|
||||
* THIS IS A BETA-QUALITY RELEASE THAT IS ONLY INTENDED FOR USE BY
|
||||
DEVELOPERS WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY.
|
||||
IT *WILL BREAK* ANY APPLICATION EXPECTING THE SASLv1 API.
|
||||
* This release now includes Mac OS 9 and Mac OS X support.
|
||||
* Significant new features include
|
||||
* DES and 3DES Encryption should now be working for DIGEST-MD5
|
||||
* Improved configuration system
|
||||
* Improved documentation (now includes plugin writers guide)
|
||||
* Many other bugfixes (see ChangeLog)
|
||||
|
||||
New in 2.0.3-BETA
|
||||
-----------------
|
||||
* THIS IS A BETA-QUALITY RELEASE THAT IS ONLY INTENDED FOR USE BY
|
||||
DEVELOPERS WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY.
|
||||
IT *WILL BREAK* ANY APPLICATION EXPECTING THE SASLv1 API.
|
||||
* This library should be fairly close to the core features that will be
|
||||
released in a final version of Cyrus SASLv2. It very likely has bugs.
|
||||
* Major new features included in this release:
|
||||
- The glue code now correctly handles client-send-first and server-send-last
|
||||
situations based on what the protocol and mechanism each support.
|
||||
- The sasldb code has been extracted from the main library and now resides
|
||||
in a separate libsasldb.la that is available at build time.
|
||||
- SASLdb now supports multiple auxiliary properties, though as distributed
|
||||
only userPassword is implemented and used.
|
||||
- Much improved configure checking for various items, including
|
||||
Berkeley DB, Kerberos, and GSSAPI.
|
||||
- Better (more standard) handling of realms in DIGEST-MD5.
|
||||
- A new Plugin Programmer's guide.
|
||||
- IPv6 support.
|
||||
- Error reporting now works in the GSSAPI plugin.
|
||||
* See the ChangeLog for a more detailed list of changes.
|
||||
|
||||
New in 2.0.2-ALPHA
|
||||
------------------
|
||||
* THIS IS AN ALPHA-QUALITY RELEASE THAT IS ONLY INTENDED FOR DEVELOPERS
|
||||
WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY.
|
||||
* This release is intended to show developers that use Cyrus SASL what
|
||||
direction we are planning on taking the library so that they can make
|
||||
plans to migrate their applications accordingly
|
||||
* Major new features included in this release:
|
||||
- Ability to compile a static library including all mechanisms. This
|
||||
means lower memory usage and faster mechanism loading time, but
|
||||
is not for everyone (or even many people). See doc/advanced.html,
|
||||
as well as the '--with-staticsasl' configure flag.
|
||||
- Man pages should now all be present and are close to being correct.
|
||||
- Can now build libsfsasl and the smtptest program (using the --with-sfio
|
||||
configure flag)
|
||||
- Reverted to the v1 entry points for mechanisms, to allow v1 mechanisms
|
||||
to fail loading cleanly.
|
||||
- Auxprop and canon_user plugins can now load from DSOs
|
||||
- Java code now compiles (but is not well tested, or up to date with the
|
||||
current Java API draft)
|
||||
- Error handling and use of sasl_errdetail has been fleshed out and
|
||||
should now work in most cases.
|
||||
* Still Coming:
|
||||
- Cleanup of the client-send-first and server-send-last situation
|
||||
- Error reporting in GSSAPI plugin
|
||||
- Move the sasldb code out of the main library and into plugins and
|
||||
utilities only.
|
||||
|
||||
New in 2.0.0-ALPHA
|
||||
------------------
|
||||
* THIS IS AN ALPHA-QUALITY RELEASE THAT IS ONLY INTENDED FOR DEVELOPERS
|
||||
WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY.
|
||||
* This release is intended to show developers that use Cyrus SASL what
|
||||
direction we are planning on taking the library so that they can make
|
||||
plans to migrate their applications accordingly
|
||||
* This release implements the SASLv2 API.
|
||||
Some of the major improvements in the API include:
|
||||
- Memory management is now sane (whoever allocates the memory is responsible
|
||||
for freeing it)
|
||||
- Auxiliary Property plugin support (ability to interface with directory
|
||||
services as part of authentication)
|
||||
- Username canonification plugin support
|
||||
- Improved error reporting (not fully implemented in this release)
|
||||
- Database support has been simplified. We now maintain only a single
|
||||
store of plaintext passwords that is shared by all supplied plugins
|
||||
(using the auxiliary property interface).
|
||||
The new API is more fully documented in the header files sasl.h, saslplug.h
|
||||
saslutil.h, and prop.h. The man pages, programmers guide, and system
|
||||
administrators guide have also been rewritten to deal with the new API.
|
||||
* There is still a good amount of work to be done, and as this code is alpha
|
||||
quality, it has bugs, known and unknown. Please either use our bugzilla at
|
||||
http://bugzilla.andrew.cmu.edu, or email cyrus-bugs@andrew.cmu.edu with
|
||||
questions, comments, or bug reports.
|
||||
- Most notably, the Java bindings have not been converted to work with
|
||||
the new API, and thus will not compile successfully.
|
||||
- The current development branch with this source is in our
|
||||
cvs repository as the "sasl-v2-rjs3" branch of the "sasl" collection.
|
||||
(see http://asg.web.cmu.edu/cyrus/download/anoncvs.html for more info)
|
||||
@@ -0,0 +1,21 @@
|
||||
This is the Cyrus SASL API implentation. It can be used on the client
|
||||
or server side to provide authentication and authorization services.
|
||||
See RFC 4422 for more information.
|
||||
|
||||
The latest version is available at:
|
||||
ftp://ftp.andrew.cmu.edu/pub/cyrus-mail
|
||||
|
||||
There's a mailing list for Cyrus SASL. Subscribe by sending a message
|
||||
to majordomo@lists.andrew.cmu.edu with the body "subscribe
|
||||
cyrus-sasl". The mailing list is available via anonymous IMAP at
|
||||
imap://cyrus.andrew.cmu.edu/archive.cyrus-sasl or via the web at
|
||||
http://asg.web.cmu.edu/archive/mailbox.php3?mailbox=archive.cyrus-sasl.
|
||||
|
||||
If you are looking to port SASLv1 applications to SASLv2, please see
|
||||
doc/appconvert.html
|
||||
|
||||
Bugs can be searched/reported at: http://bugzilla.cyrussasl.org
|
||||
|
||||
DOCUMENTATION
|
||||
--------------
|
||||
Please see doc/index.html for the remainder of the documentation.
|
||||
@@ -0,0 +1,65 @@
|
||||
# Makefile.am for SASL includes
|
||||
# Rob Earhart
|
||||
#
|
||||
################################################################
|
||||
# Copyright (c) 2000 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# prior written permission. For permission or any other legal
|
||||
# details, please contact
|
||||
# Office of Technology Transfer
|
||||
# Carnegie Mellon University
|
||||
# 5000 Forbes Avenue
|
||||
# Pittsburgh, PA 15213-3890
|
||||
# (412) 268-4387, fax: (412) 268-7395
|
||||
# tech-transfer@andrew.cmu.edu
|
||||
#
|
||||
# 4. Redistributions of any form whatsoever must retain the following
|
||||
# acknowledgment:
|
||||
# "This product includes software developed by Computing Services
|
||||
# at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
#
|
||||
# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
################################################################
|
||||
|
||||
noinst_HEADERS = gai.h exits.h
|
||||
|
||||
saslincludedir = $(includedir)/sasl
|
||||
saslinclude_HEADERS = hmac-md5.h md5.h md5global.h sasl.h saslplug.h saslutil.h prop.h
|
||||
|
||||
noinst_PROGRAMS = makemd5
|
||||
|
||||
makemd5_SOURCES = makemd5.c
|
||||
|
||||
md5global.h: makemd5
|
||||
-rm -f md5global.h
|
||||
./makemd5 md5global.h
|
||||
|
||||
EXTRA_DIST = NTMakefile
|
||||
DISTCLEANFILES = md5global.h
|
||||
|
||||
if MACOSX
|
||||
framedir = /Library/Frameworks/SASL2.framework
|
||||
frameheaderdir = $(framedir)/Versions/A/Headers
|
||||
frameheader_DATA = $(saslinclude_HEADERS)
|
||||
endif
|
||||
@@ -0,0 +1,653 @@
|
||||
# Makefile.in generated by automake 1.11 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# Makefile.am for SASL includes
|
||||
# Rob Earhart
|
||||
#
|
||||
################################################################
|
||||
# Copyright (c) 2000 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# prior written permission. For permission or any other legal
|
||||
# details, please contact
|
||||
# Office of Technology Transfer
|
||||
# Carnegie Mellon University
|
||||
# 5000 Forbes Avenue
|
||||
# Pittsburgh, PA 15213-3890
|
||||
# (412) 268-4387, fax: (412) 268-7395
|
||||
# tech-transfer@andrew.cmu.edu
|
||||
#
|
||||
# 4. Redistributions of any form whatsoever must retain the following
|
||||
# acknowledgment:
|
||||
# "This product includes software developed by Computing Services
|
||||
# at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
#
|
||||
# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
################################################################
|
||||
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
noinst_PROGRAMS = makemd5$(EXEEXT)
|
||||
subdir = include
|
||||
DIST_COMMON = $(noinst_HEADERS) $(saslinclude_HEADERS) \
|
||||
$(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/config/kerberos_v4.m4 \
|
||||
$(top_srcdir)/config/libtool.m4 $(top_srcdir)/config/plain.m4 \
|
||||
$(top_srcdir)/config/sasldb.m4 \
|
||||
$(top_srcdir)/cmulocal/berkdb.m4 \
|
||||
$(top_srcdir)/cmulocal/bsd_sockets.m4 \
|
||||
$(top_srcdir)/cmulocal/c-attribute.m4 \
|
||||
$(top_srcdir)/cmulocal/common.m4 \
|
||||
$(top_srcdir)/cmulocal/cyrus.m4 \
|
||||
$(top_srcdir)/cmulocal/init_automake.m4 \
|
||||
$(top_srcdir)/cmulocal/ipv6.m4 \
|
||||
$(top_srcdir)/cmulocal/openldap.m4 \
|
||||
$(top_srcdir)/cmulocal/openssl.m4 \
|
||||
$(top_srcdir)/cmulocal/sasl2.m4 $(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
PROGRAMS = $(noinst_PROGRAMS)
|
||||
am_makemd5_OBJECTS = makemd5.$(OBJEXT)
|
||||
makemd5_OBJECTS = $(am_makemd5_OBJECTS)
|
||||
makemd5_LDADD = $(LDADD)
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
|
||||
$(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(makemd5_SOURCES)
|
||||
DIST_SOURCES = $(makemd5_SOURCES)
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__installdirs = "$(DESTDIR)$(frameheaderdir)" \
|
||||
"$(DESTDIR)$(saslincludedir)"
|
||||
DATA = $(frameheader_DATA)
|
||||
HEADERS = $(noinst_HEADERS) $(saslinclude_HEADERS)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DIRS = @DIRS@
|
||||
DMALLOC_LIBS = @DMALLOC_LIBS@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
GETADDRINFOOBJS = @GETADDRINFOOBJS@
|
||||
GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
|
||||
GETSUBOPT = @GETSUBOPT@
|
||||
GREP = @GREP@
|
||||
GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
|
||||
GSSAPI_LIBS = @GSSAPI_LIBS@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
IPCTYPE = @IPCTYPE@
|
||||
JAVAC = @JAVAC@
|
||||
JAVADOC = @JAVADOC@
|
||||
JAVAH = @JAVAH@
|
||||
JAVAROOT = @JAVAROOT@
|
||||
JAVA_INCLUDES = @JAVA_INCLUDES@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIB_CRYPT = @LIB_CRYPT@
|
||||
LIB_DES = @LIB_DES@
|
||||
LIB_DOOR = @LIB_DOOR@
|
||||
LIB_LDAP = @LIB_LDAP@
|
||||
LIB_MYSQL = @LIB_MYSQL@
|
||||
LIB_PGSQL = @LIB_PGSQL@
|
||||
LIB_SOCKET = @LIB_SOCKET@
|
||||
LIB_SQLITE = @LIB_SQLITE@
|
||||
LIB_SQLITE3 = @LIB_SQLITE3@
|
||||
LN_S = @LN_S@
|
||||
LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
|
||||
LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NTLM_LIBS = @NTLM_LIBS@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTP_LIBS = @OTP_LIBS@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PASSDSS_LIBS = @PASSDSS_LIBS@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PLAIN_LIBS = @PLAIN_LIBS@
|
||||
PURECOV = @PURECOV@
|
||||
PURIFY = @PURIFY@
|
||||
PWCHECKMETH = @PWCHECKMETH@
|
||||
RANLIB = @RANLIB@
|
||||
SASL_DB_BACKEND = @SASL_DB_BACKEND@
|
||||
SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
|
||||
SASL_DB_INC = @SASL_DB_INC@
|
||||
SASL_DB_LIB = @SASL_DB_LIB@
|
||||
SASL_DB_MANS = @SASL_DB_MANS@
|
||||
SASL_DB_UTILS = @SASL_DB_UTILS@
|
||||
SASL_DL_LIB = @SASL_DL_LIB@
|
||||
SASL_KRB_LIB = @SASL_KRB_LIB@
|
||||
SASL_MECHS = @SASL_MECHS@
|
||||
SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
|
||||
SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
|
||||
SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
|
||||
SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
|
||||
SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
|
||||
SCRAM_LIBS = @SCRAM_LIBS@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
|
||||
SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
|
||||
SHELL = @SHELL@
|
||||
SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
|
||||
SNPRINTFOBJS = @SNPRINTFOBJS@
|
||||
SRP_LIBS = @SRP_LIBS@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
configdir = @configdir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
plugindir = @plugindir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
subdirs = @subdirs@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
noinst_HEADERS = gai.h exits.h
|
||||
saslincludedir = $(includedir)/sasl
|
||||
saslinclude_HEADERS = hmac-md5.h md5.h md5global.h sasl.h saslplug.h saslutil.h prop.h
|
||||
makemd5_SOURCES = makemd5.c
|
||||
EXTRA_DIST = NTMakefile
|
||||
DISTCLEANFILES = md5global.h
|
||||
@MACOSX_TRUE@framedir = /Library/Frameworks/SASL2.framework
|
||||
@MACOSX_TRUE@frameheaderdir = $(framedir)/Versions/A/Headers
|
||||
@MACOSX_TRUE@frameheader_DATA = $(saslinclude_HEADERS)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu include/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
clean-noinstPROGRAMS:
|
||||
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list || exit $$?; \
|
||||
test -n "$(EXEEXT)" || exit 0; \
|
||||
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
makemd5$(EXEEXT): $(makemd5_OBJECTS) $(makemd5_DEPENDENCIES)
|
||||
@rm -f makemd5$(EXEEXT)
|
||||
$(LINK) $(makemd5_OBJECTS) $(makemd5_LDADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/makemd5.Po@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
install-frameheaderDATA: $(frameheader_DATA)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(frameheaderdir)" || $(MKDIR_P) "$(DESTDIR)$(frameheaderdir)"
|
||||
@list='$(frameheader_DATA)'; test -n "$(frameheaderdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(frameheaderdir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(frameheaderdir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-frameheaderDATA:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(frameheader_DATA)'; test -n "$(frameheaderdir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
test -n "$$files" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(frameheaderdir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(frameheaderdir)" && rm -f $$files
|
||||
install-saslincludeHEADERS: $(saslinclude_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(saslincludedir)" || $(MKDIR_P) "$(DESTDIR)$(saslincludedir)"
|
||||
@list='$(saslinclude_HEADERS)'; test -n "$(saslincludedir)" || list=; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(saslincludedir)'"; \
|
||||
$(INSTALL_HEADER) $$files "$(DESTDIR)$(saslincludedir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-saslincludeHEADERS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(saslinclude_HEADERS)'; test -n "$(saslincludedir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
test -n "$$files" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(saslincludedir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(saslincludedir)" && rm -f $$files
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(PROGRAMS) $(DATA) $(HEADERS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(frameheaderdir)" "$(DESTDIR)$(saslincludedir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-frameheaderDATA install-saslincludeHEADERS
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-frameheaderDATA uninstall-saslincludeHEADERS
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-libtool clean-noinstPROGRAMS ctags distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am \
|
||||
install-frameheaderDATA install-html install-html-am \
|
||||
install-info install-info-am install-man install-pdf \
|
||||
install-pdf-am install-ps install-ps-am \
|
||||
install-saslincludeHEADERS install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags uninstall uninstall-am uninstall-frameheaderDATA \
|
||||
uninstall-saslincludeHEADERS
|
||||
|
||||
|
||||
md5global.h: makemd5
|
||||
-rm -f md5global.h
|
||||
./makemd5 md5global.h
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
@@ -0,0 +1,65 @@
|
||||
# NTMakefile for SASL, include directory
|
||||
# Alexey Melnikov
|
||||
#
|
||||
################################################################
|
||||
# Copyright (c) 2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# prior written permission. For permission or any other legal
|
||||
# details, please contact
|
||||
# Office of Technology Transfer
|
||||
# Carnegie Mellon University
|
||||
# 5000 Forbes Avenue
|
||||
# Pittsburgh, PA 15213-3890
|
||||
# (412) 268-4387, fax: (412) 268-7395
|
||||
# tech-transfer@andrew.cmu.edu
|
||||
#
|
||||
# 4. Redistributions of any form whatsoever must retain the following
|
||||
# acknowledgment:
|
||||
# "This product includes software developed by Computing Services
|
||||
# at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
#
|
||||
# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
################################################################
|
||||
|
||||
#Suppress verbose output from defaulting values
|
||||
VERBOSE=0
|
||||
|
||||
!INCLUDE ..\win32\common.mak
|
||||
|
||||
includedir = $(prefix)\include
|
||||
|
||||
saslincludedir = $(includedir)\sasl\
|
||||
|
||||
saslinclude_HEADERS = hmac-md5.h md5.h sasl.h saslplug.h saslutil.h prop.h
|
||||
|
||||
# The first target get executed by default. We don't want this to be "install"
|
||||
all:
|
||||
@echo Nothing to be done for $@
|
||||
|
||||
#
|
||||
# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels
|
||||
#
|
||||
install: $(saslinclude_HEADERS)
|
||||
!xcopy sasl*.h $(saslincludedir) /I /F /Y
|
||||
!xcopy $? $(saslincludedir) /I /F /Y
|
||||
@@ -0,0 +1,607 @@
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
|
||||
/* acconfig.h - autoheader configuration input */
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
|
||||
/* Runtime config file location */
|
||||
#define CONFIGDIR "/usr/lib/sasl2:/etc/sasl2"
|
||||
|
||||
/* Do we need a leading _ for dlsym? */
|
||||
/* #undef DLSYM_NEEDS_UNDERSCORE */
|
||||
|
||||
/* Should we build a shared plugin (via dlopen) library? */
|
||||
/* #undef DO_DLOPEN */
|
||||
|
||||
/* should we support sasl_checkapop? */
|
||||
#define DO_SASL_CHECKAPOP /**/
|
||||
|
||||
/* should we support setpass() for SRP? */
|
||||
/* #undef DO_SRP_SETPASS */
|
||||
|
||||
/* should we mutex-wrap calls into the GSS library? */
|
||||
#define GSS_USE_MUTEXES /**/
|
||||
|
||||
/* Enable 'alwaystrue' password verifier? */
|
||||
/* #undef HAVE_ALWAYSTRUE */
|
||||
|
||||
/* Include support for Courier's authdaemond? */
|
||||
#define HAVE_AUTHDAEMON /**/
|
||||
|
||||
/* Define to 1 if you have the <des.h> header file. */
|
||||
/* #undef HAVE_DES_H */
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#define HAVE_DIRENT_H 1
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the `dns_lookup' function. */
|
||||
/* #undef HAVE_DNS_LOOKUP */
|
||||
|
||||
/* Define to 1 if you have the `dn_expand' function. */
|
||||
#define HAVE_DN_EXPAND 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Do we have a getaddrinfo? */
|
||||
#define HAVE_GETADDRINFO /**/
|
||||
|
||||
/* Define to 1 if you have the `getdomainname' function. */
|
||||
#define HAVE_GETDOMAINNAME 1
|
||||
|
||||
/* Define to 1 if you have the `gethostname' function. */
|
||||
#define HAVE_GETHOSTNAME 1
|
||||
|
||||
/* Do we have a getnameinfo() function? */
|
||||
#define HAVE_GETNAMEINFO /**/
|
||||
|
||||
/* Define to 1 if you have the `getpassphrase' function. */
|
||||
/* #undef HAVE_GETPASSPHRASE */
|
||||
|
||||
/* Define to 1 if you have the `getpwnam' function. */
|
||||
#define HAVE_GETPWNAM 1
|
||||
|
||||
/* Define to 1 if you have the `getspnam' function. */
|
||||
/* #undef HAVE_GETSPNAM */
|
||||
|
||||
/* do we have getsubopt()? */
|
||||
#define HAVE_GETSUBOPT /**/
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define to 1 if you have the <gssapi/gssapi_ext.h> header file. */
|
||||
/* #undef HAVE_GSSAPI_GSSAPI_EXT_H */
|
||||
|
||||
/* Define if you have the gssapi.h header file */
|
||||
#define HAVE_GSSAPI_H /**/
|
||||
|
||||
/* Define to 1 if you have the `gsskrb5_register_acceptor_identity' function.
|
||||
*/
|
||||
/* #undef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY */
|
||||
|
||||
/* Define if your GSSAPI implementation defines GSS_C_NT_HOSTBASED_SERVICE */
|
||||
#define HAVE_GSS_C_NT_HOSTBASED_SERVICE /**/
|
||||
|
||||
/* Define if your GSSAPI implementation defines GSS_C_NT_USER_NAME */
|
||||
#define HAVE_GSS_C_NT_USER_NAME /**/
|
||||
|
||||
/* Define to 1 if you have the `gss_decapsulate_token' function. */
|
||||
/* #undef HAVE_GSS_DECAPSULATE_TOKEN */
|
||||
|
||||
/* Define to 1 if you have the `gss_encapsulate_token' function. */
|
||||
/* #undef HAVE_GSS_ENCAPSULATE_TOKEN */
|
||||
|
||||
/* Define to 1 if you have the `gss_get_name_attribute' function. */
|
||||
/* #undef HAVE_GSS_GET_NAME_ATTRIBUTE */
|
||||
|
||||
/* Define to 1 if you have the `gss_oid_equal' function. */
|
||||
/* #undef HAVE_GSS_OID_EQUAL */
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
#define HAVE_INET_ATON 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the `jrand48' function. */
|
||||
#define HAVE_JRAND48 1
|
||||
|
||||
/* Do we have Kerberos 4 Support? */
|
||||
/* #undef HAVE_KRB */
|
||||
|
||||
/* Define to 1 if you have the `krb_get_err_text' function. */
|
||||
/* #undef HAVE_KRB_GET_ERR_TEXT */
|
||||
|
||||
/* Define to 1 if you have the <lber.h> header file. */
|
||||
/* #undef HAVE_LBER_H */
|
||||
|
||||
/* Define to 1 if you have the <ldap.h> header file. */
|
||||
/* #undef HAVE_LDAP_H */
|
||||
|
||||
/* Define to 1 if you have the `resolv' library (-lresolv). */
|
||||
#define HAVE_LIBRESOLV 1
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define to 1 if you have the <malloc.h> header file. */
|
||||
/* #undef HAVE_MALLOC_H */
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `mkdir' function. */
|
||||
#define HAVE_MKDIR 1
|
||||
|
||||
/* Do we have mysql support? */
|
||||
/* #undef HAVE_MYSQL */
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
|
||||
/* Do we have OpenSSL? */
|
||||
#define HAVE_OPENSSL /**/
|
||||
|
||||
/* Use OPIE for server-side OTP? */
|
||||
/* #undef HAVE_OPIE */
|
||||
|
||||
/* Define to 1 if you have the <pam/pam_appl.h> header file. */
|
||||
/* #undef HAVE_PAM_PAM_APPL_H */
|
||||
|
||||
/* Define to 1 if you have the <paths.h> header file. */
|
||||
#define HAVE_PATHS_H 1
|
||||
|
||||
/* Do we have Postgres support? */
|
||||
/* #undef HAVE_PGSQL */
|
||||
|
||||
/* Include Support for pwcheck daemon? */
|
||||
/* #undef HAVE_PWCHECK */
|
||||
|
||||
/* Include support for saslauthd? */
|
||||
#define HAVE_SASLAUTHD /**/
|
||||
|
||||
/* Define to 1 if you have the <security/pam_appl.h> header file. */
|
||||
#define HAVE_SECURITY_PAM_APPL_H 1
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#define HAVE_SELECT 1
|
||||
|
||||
/* Does the system have snprintf()? */
|
||||
#define HAVE_SNPRINTF /**/
|
||||
|
||||
/* Does sockaddr have an sa_len? */
|
||||
/* #undef HAVE_SOCKADDR_SA_LEN */
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Do we have a socklen_t? */
|
||||
#define HAVE_SOCKLEN_T /**/
|
||||
|
||||
/* Do we have SQLite support? */
|
||||
/* #undef HAVE_SQLITE */
|
||||
|
||||
/* Do we have SQLite3 support? */
|
||||
/* #undef HAVE_SQLITE3 */
|
||||
|
||||
/* Is there an ss_family in sockaddr_storage? */
|
||||
#define HAVE_SS_FAMILY /**/
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#define HAVE_STDARG_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strchr' function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define to 1 if you have the `strdup' function. */
|
||||
#define HAVE_STRDUP 1
|
||||
|
||||
/* Define to 1 if you have the `strerror' function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strspn' function. */
|
||||
#define HAVE_STRSPN 1
|
||||
|
||||
/* Define to 1 if you have the `strstr' function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#define HAVE_STRTOL 1
|
||||
|
||||
/* Do we have struct sockaddr_stroage? */
|
||||
#define HAVE_STRUCT_SOCKADDR_STORAGE /**/
|
||||
|
||||
/* Define to 1 if you have the <sysexits.h> header file. */
|
||||
#define HAVE_SYSEXITS_H 1
|
||||
|
||||
/* Define to 1 if you have the `syslog' function. */
|
||||
#define HAVE_SYSLOG 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#define HAVE_SYSLOG_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/file.h> header file. */
|
||||
#define HAVE_SYS_FILE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
#define HAVE_SYS_UIO_H 1
|
||||
|
||||
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the <varargs.h> header file. */
|
||||
/* #undef HAVE_VARARGS_H */
|
||||
|
||||
/* Does the system have vsnprintf()? */
|
||||
#define HAVE_VSNPRINTF /**/
|
||||
|
||||
/* define if your compiler has __attribute__ */
|
||||
#define HAVE___ATTRIBUTE__ 1
|
||||
|
||||
/* Should we keep handle to Berkeley DB open in SASLDB plugin? */
|
||||
/* #undef KEEP_DB_OPEN */
|
||||
|
||||
/* Ignore IP Address in Kerberos 4 tickets? */
|
||||
/* #undef KRB4_IGNORE_IP_ADDRESS */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "cyrus-sasl"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME ""
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING ""
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION ""
|
||||
|
||||
/* Where do we look for Courier authdaemond's socket? */
|
||||
#define PATH_AUTHDAEMON_SOCKET "/dev/null"
|
||||
|
||||
/* Where do we look for saslauthd's socket? */
|
||||
#define PATH_SASLAUTHD_RUNDIR "/var/state/saslauthd"
|
||||
|
||||
/* Runtime plugin location */
|
||||
#define PLUGINDIR "/usr/lib/sasl2"
|
||||
|
||||
/* Force a preferred mechanism */
|
||||
/* #undef PREFER_MECH */
|
||||
|
||||
/* Location of pwcheck socket */
|
||||
/* #undef PWCHECKDIR */
|
||||
|
||||
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||
#define RETSIGTYPE void
|
||||
|
||||
/* Use BerkeleyDB for SASLdb */
|
||||
/* #undef SASL_BERKELEYDB */
|
||||
|
||||
/* Path to default SASLdb database */
|
||||
#define SASL_DB_PATH "/etc/sasldb2"
|
||||
|
||||
/* File to use for source of randomness */
|
||||
#define SASL_DEV_RANDOM "/dev/random"
|
||||
|
||||
/* Use GDBM for SASLdb */
|
||||
/* #undef SASL_GDBM */
|
||||
|
||||
/* Use NDBM for SASLdb */
|
||||
#define SASL_NDBM /**/
|
||||
|
||||
/* The size of `long', as computed by sizeof. */
|
||||
#define SIZEOF_LONG 8
|
||||
|
||||
/* Link ANONYMOUS Staticly */
|
||||
#define STATIC_ANONYMOUS /**/
|
||||
|
||||
/* Link CRAM-MD5 Staticly */
|
||||
#define STATIC_CRAMMD5 /**/
|
||||
|
||||
/* Link DIGEST-MD5 Staticly */
|
||||
#define STATIC_DIGESTMD5 /**/
|
||||
|
||||
/* Link GSSAPI Staticly */
|
||||
/* #undef STATIC_GSSAPIV2 */
|
||||
|
||||
/* User KERBEROS_V4 Staticly */
|
||||
/* #undef STATIC_KERBEROS4 */
|
||||
|
||||
/* Link ldapdb plugin Staticly */
|
||||
/* #undef STATIC_LDAPDB */
|
||||
|
||||
/* Link LOGIN Staticly */
|
||||
/* #undef STATIC_LOGIN */
|
||||
|
||||
/* Link NTLM Staticly */
|
||||
/* #undef STATIC_NTLM */
|
||||
|
||||
/* Link OTP Staticly */
|
||||
#define STATIC_OTP /**/
|
||||
|
||||
/* Link PASSDSS Staticly */
|
||||
/* #undef STATIC_PASSDSS */
|
||||
|
||||
/* Link PLAIN Staticly */
|
||||
#define STATIC_PLAIN /**/
|
||||
|
||||
/* Link SASLdb Staticly */
|
||||
/* #undef STATIC_SASLDB */
|
||||
|
||||
/* Link SCRAM Staticly */
|
||||
#define STATIC_SCRAM /**/
|
||||
|
||||
/* Link SQL plugin staticly */
|
||||
/* #undef STATIC_SQL */
|
||||
|
||||
/* Link SRP Staticly */
|
||||
/* #undef STATIC_SRP */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Should we try to dlopen() plugins while staticly compiled? */
|
||||
/* #undef TRY_DLOPEN_WHEN_STATIC */
|
||||
|
||||
/* use the doors IPC API for saslauthd? */
|
||||
/* #undef USE_DOORS */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "2.1.25"
|
||||
|
||||
/* Use DES */
|
||||
#define WITH_DES /**/
|
||||
|
||||
/* Linking against dmalloc? */
|
||||
/* #undef WITH_DMALLOC */
|
||||
|
||||
/* Use internal RC4 implementation? */
|
||||
#define WITH_RC4 /**/
|
||||
|
||||
/* Use OpenSSL DES Implementation */
|
||||
#define WITH_SSL_DES /**/
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
/* #undef inline */
|
||||
#endif
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef mode_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef pid_t */
|
||||
|
||||
|
||||
|
||||
|
||||
/* Create a struct iovec if we need one */
|
||||
#if !defined(_WIN32) && !defined(HAVE_SYS_UIO_H)
|
||||
/* (win32 is handled in sasl.h) */
|
||||
struct iovec {
|
||||
char *iov_base;
|
||||
long iov_len;
|
||||
};
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
|
||||
/* location of the random number generator */
|
||||
#ifdef DEV_RANDOM
|
||||
/* #undef DEV_RANDOM */
|
||||
#endif
|
||||
#define DEV_RANDOM SASL_DEV_RANDOM
|
||||
|
||||
/* if we've got krb_get_err_txt, we might as well use it;
|
||||
especially since krb_err_txt isn't in some newer distributions
|
||||
(MIT Kerb for Mac 4 being a notable example). If we don't have
|
||||
it, we fall back to the krb_err_txt array */
|
||||
#ifdef HAVE_KRB_GET_ERR_TEXT
|
||||
#define get_krb_err_txt krb_get_err_text
|
||||
#else
|
||||
#define get_krb_err_txt(X) (krb_err_txt[(X)])
|
||||
#endif
|
||||
|
||||
/* Make Solaris happy... */
|
||||
#ifndef __EXTENSIONS__
|
||||
#define __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
/* Make Linux happy... */
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#ifndef HAVE___ATTRIBUTE__
|
||||
/* Can't use attributes... */
|
||||
#define __attribute__(foo)
|
||||
#endif
|
||||
|
||||
#define SASL_PATH_ENV_VAR "SASL_PATH"
|
||||
#define SASL_CONF_PATH_ENV_VAR "SASL_CONF_PATH"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#ifndef WIN32
|
||||
# include <netdb.h>
|
||||
# ifdef HAVE_SYS_PARAM_H
|
||||
# include <sys/param.h>
|
||||
# endif
|
||||
#else /* WIN32 */
|
||||
# include <winsock2.h>
|
||||
#endif /* WIN32 */
|
||||
#include <string.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifndef HAVE_SOCKLEN_T
|
||||
typedef unsigned int socklen_t;
|
||||
#endif /* HAVE_SOCKLEN_T */
|
||||
|
||||
#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
|
||||
#define _SS_MAXSIZE 128 /* Implementation specific max size */
|
||||
#define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr))
|
||||
|
||||
struct sockaddr_storage {
|
||||
struct sockaddr ss_sa;
|
||||
char __ss_pad2[_SS_PADSIZE];
|
||||
};
|
||||
# define ss_family ss_sa.sa_family
|
||||
#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
|
||||
|
||||
#ifndef AF_INET6
|
||||
/* Define it to something that should never appear */
|
||||
#define AF_INET6 AF_MAX
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
#define getaddrinfo sasl_getaddrinfo
|
||||
#define freeaddrinfo sasl_freeaddrinfo
|
||||
#define gai_strerror sasl_gai_strerror
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
#define getnameinfo sasl_getnameinfo
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_GETNAMEINFO) || !defined(HAVE_GETADDRINFO)
|
||||
#include "gai.h"
|
||||
#endif
|
||||
|
||||
#ifndef AI_NUMERICHOST /* support glibc 2.0.x */
|
||||
#define AI_NUMERICHOST 4
|
||||
#define NI_NUMERICHOST 2
|
||||
#define NI_NAMEREQD 4
|
||||
#define NI_NUMERICSERV 8
|
||||
#endif
|
||||
|
||||
/* Defined in RFC 1035. max strlen is only 253 due to length bytes. */
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 255
|
||||
#endif
|
||||
|
||||
// #ifndef HAVE_SYSEXITS_H
|
||||
// #include "exits.h"
|
||||
// #else
|
||||
// #include "sysexits.h"
|
||||
// #endif
|
||||
|
||||
/* Get the correct time.h */
|
||||
#if TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# if HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HIER_DELIMITER
|
||||
#define HIER_DELIMITER '/'
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_H */
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 1987, 1993
|
||||
* The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS 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 THE REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* @(#)sysexits.h 8.1 (Berkeley) 6/2/93
|
||||
*/
|
||||
|
||||
#ifndef _SYSEXITS_H_
|
||||
#define _SYSEXITS_H_
|
||||
|
||||
/*
|
||||
* SYSEXITS.H -- Exit status codes for system programs.
|
||||
*
|
||||
* This include file attempts to categorize possible error
|
||||
* exit statuses for system programs, notably delivermail
|
||||
* and the Berkeley network.
|
||||
*
|
||||
* Error numbers begin at EX__BASE to reduce the possibility of
|
||||
* clashing with other exit statuses that random programs may
|
||||
* already return. The meaning of the codes is approximately
|
||||
* as follows:
|
||||
*
|
||||
* EX_USAGE -- The command was used incorrectly, e.g., with
|
||||
* the wrong number of arguments, a bad flag, a bad
|
||||
* syntax in a parameter, or whatever.
|
||||
* EX_DATAERR -- The input data was incorrect in some way.
|
||||
* This should only be used for user's data & not
|
||||
* system files.
|
||||
* EX_NOINPUT -- An input file (not a system file) did not
|
||||
* exist or was not readable. This could also include
|
||||
* errors like "No message" to a mailer (if it cared
|
||||
* to catch it).
|
||||
* EX_NOUSER -- The user specified did not exist. This might
|
||||
* be used for mail addresses or remote logins.
|
||||
* EX_NOHOST -- The host specified did not exist. This is used
|
||||
* in mail addresses or network requests.
|
||||
* EX_UNAVAILABLE -- A service is unavailable. This can occur
|
||||
* if a support program or file does not exist. This
|
||||
* can also be used as a catchall message when something
|
||||
* you wanted to do doesn't work, but you don't know
|
||||
* why.
|
||||
* EX_SOFTWARE -- An internal software error has been detected.
|
||||
* This should be limited to non-operating system related
|
||||
* errors as possible.
|
||||
* EX_OSERR -- An operating system error has been detected.
|
||||
* This is intended to be used for such things as "cannot
|
||||
* fork", "cannot create pipe", or the like. It includes
|
||||
* things like getuid returning a user that does not
|
||||
* exist in the passwd file.
|
||||
* EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp,
|
||||
* etc.) does not exist, cannot be opened, or has some
|
||||
* sort of error (e.g., syntax error).
|
||||
* EX_CANTCREAT -- A (user specified) output file cannot be
|
||||
* created.
|
||||
* EX_IOERR -- An error occurred while doing I/O on some file.
|
||||
* EX_TEMPFAIL -- temporary failure, indicating something that
|
||||
* is not really an error. In sendmail, this means
|
||||
* that a mailer (e.g.) could not create a connection,
|
||||
* and the request should be reattempted later.
|
||||
* EX_PROTOCOL -- the remote system returned something that
|
||||
* was "not possible" during a protocol exchange.
|
||||
* EX_NOPERM -- You did not have sufficient permission to
|
||||
* perform the operation. This is not intended for
|
||||
* file system problems, which should use NOINPUT or
|
||||
* CANTCREAT, but rather for higher level permissions.
|
||||
*/
|
||||
|
||||
#define EX_OK 0 /* successful termination */
|
||||
|
||||
#define EX__BASE 64 /* base value for error messages */
|
||||
|
||||
#define EX_USAGE 64 /* command line usage error */
|
||||
#define EX_DATAERR 65 /* data format error */
|
||||
#define EX_NOINPUT 66 /* cannot open input */
|
||||
#define EX_NOUSER 67 /* addressee unknown */
|
||||
#define EX_NOHOST 68 /* host name unknown */
|
||||
#define EX_UNAVAILABLE 69 /* service unavailable */
|
||||
#define EX_SOFTWARE 70 /* internal software error */
|
||||
#define EX_OSERR 71 /* system error (e.g., can't fork) */
|
||||
#define EX_OSFILE 72 /* critical OS file missing */
|
||||
#define EX_CANTCREAT 73 /* can't create (user) output file */
|
||||
#define EX_IOERR 74 /* input/output error */
|
||||
#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */
|
||||
#define EX_PROTOCOL 76 /* remote error in protocol */
|
||||
#define EX_NOPERM 77 /* permission denied */
|
||||
#define EX_CONFIG 78 /* configuration error */
|
||||
|
||||
#define EX__MAX 78 /* maximum listed value */
|
||||
|
||||
#endif /* !_SYSEXITS_H_ */
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Mar 8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org>
|
||||
* $Id: gai.h,v 1.8 2006/04/10 13:36:20 mel Exp $
|
||||
*
|
||||
* This module is besed on ssh-1.2.27-IPv6-1.5 written by
|
||||
* KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file is included in getaddrinfo.c and getnameinfo.c.
|
||||
* See getaddrinfo.c and getnameinfo.c.
|
||||
*/
|
||||
|
||||
#ifndef _GAI_H_
|
||||
#define _GAI_H_
|
||||
|
||||
#ifndef NI_MAXHOST
|
||||
#define NI_MAXHOST 1025
|
||||
#endif
|
||||
#ifndef NI_MAXSERV
|
||||
#define NI_MAXSERV 32
|
||||
#endif
|
||||
|
||||
/* for old netdb.h */
|
||||
#ifndef EAI_NODATA
|
||||
#define EAI_NODATA 1
|
||||
#define EAI_MEMORY 2
|
||||
#define EAI_FAMILY 5 /* ai_family not supported */
|
||||
#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
|
||||
#endif
|
||||
|
||||
/* dummy value for old netdb.h */
|
||||
#ifndef AI_PASSIVE
|
||||
#define AI_PASSIVE 1
|
||||
#define AI_CANONNAME 2
|
||||
struct addrinfo {
|
||||
int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
|
||||
int ai_family; /* PF_xxx */
|
||||
int ai_socktype; /* SOCK_xxx */
|
||||
int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
|
||||
size_t ai_addrlen; /* length of ai_addr */
|
||||
char *ai_canonname; /* canonical name for hostname */
|
||||
struct sockaddr *ai_addr; /* binary address */
|
||||
struct addrinfo *ai_next; /* next structure in linked list */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETNAMEINFO
|
||||
int getnameinfo(const struct sockaddr *, socklen_t, char *,
|
||||
size_t, char *, size_t, int);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETADDRINFO
|
||||
int getaddrinfo(const char *, const char *,
|
||||
const struct addrinfo *, struct addrinfo **);
|
||||
void freeaddrinfo(struct addrinfo *);
|
||||
char *gai_strerror(int);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/* hmac-md5.h -- HMAC_MD5 functions
|
||||
*/
|
||||
|
||||
#ifndef HMAC_MD5_H
|
||||
#define HMAC_MD5_H 1
|
||||
|
||||
#define HMAC_MD5_SIZE 16
|
||||
|
||||
/* intermediate MD5 context */
|
||||
typedef struct HMAC_MD5_CTX_s {
|
||||
MD5_CTX ictx, octx;
|
||||
} HMAC_MD5_CTX;
|
||||
|
||||
/* intermediate HMAC state
|
||||
* values stored in network byte order (Big Endian)
|
||||
*/
|
||||
typedef struct HMAC_MD5_STATE_s {
|
||||
UINT4 istate[4];
|
||||
UINT4 ostate[4];
|
||||
} HMAC_MD5_STATE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* One step hmac computation
|
||||
*
|
||||
* digest may be same as text or key
|
||||
*/
|
||||
void _sasl_hmac_md5(const unsigned char *text, int text_len,
|
||||
const unsigned char *key, int key_len,
|
||||
unsigned char digest[HMAC_MD5_SIZE]);
|
||||
|
||||
/* create context from key
|
||||
*/
|
||||
void _sasl_hmac_md5_init(HMAC_MD5_CTX *hmac,
|
||||
const unsigned char *key, int key_len);
|
||||
|
||||
/* precalculate intermediate state from key
|
||||
*/
|
||||
void _sasl_hmac_md5_precalc(HMAC_MD5_STATE *hmac,
|
||||
const unsigned char *key, int key_len);
|
||||
|
||||
/* initialize context from intermediate state
|
||||
*/
|
||||
void _sasl_hmac_md5_import(HMAC_MD5_CTX *hmac, HMAC_MD5_STATE *state);
|
||||
|
||||
#define _sasl_hmac_md5_update(hmac, text, text_len) _sasl_MD5Update(&(hmac)->ictx, (text), (text_len))
|
||||
|
||||
/* finish hmac from intermediate result. Intermediate result is zeroed.
|
||||
*/
|
||||
void _sasl_hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
|
||||
HMAC_MD5_CTX *hmac);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HMAC_MD5_H */
|
||||
@@ -0,0 +1,246 @@
|
||||
/* creates the md5global.h file.
|
||||
* Derived from KTH kerberos library bits.c program
|
||||
* Tim Martin
|
||||
* $Id: makemd5.c,v 1.4 2003/02/13 19:55:52 rjs3 Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
|
||||
* (Royal Institute of Technology, Stockholm, Sweden).
|
||||
* 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Kungliga Tekniska
|
||||
* Högskolan and its contributors.
|
||||
*
|
||||
* 4. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS 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 THE INSTITUTE OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
static void
|
||||
my_strupr(char *s)
|
||||
{
|
||||
char *p = s;
|
||||
while(*p){
|
||||
if(islower((int) *p))
|
||||
*p = toupper((int) *p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define BITSIZE(TYPE) \
|
||||
{ \
|
||||
int b = 0; TYPE x = 1, zero = 0; char *pre = "U"; \
|
||||
char tmp[128], tmp2[128]; \
|
||||
while(x){ x <<= 1; b++; if(x < zero) pre=""; } \
|
||||
if(b >= len){ \
|
||||
int tabs; \
|
||||
sprintf(tmp, "%sINT%d" , pre, len/8); \
|
||||
sprintf(tmp2, "typedef %s %s;", #TYPE, tmp); \
|
||||
my_strupr(tmp); \
|
||||
tabs = 5 - strlen(tmp2) / 8; \
|
||||
fprintf(f, "%s", tmp2); \
|
||||
while(tabs-- > 0) fprintf(f, "\t"); \
|
||||
fprintf(f, "/* %2d bits */\n", b); \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
static void
|
||||
try_signed(FILE *f, int len)
|
||||
{
|
||||
BITSIZE(signed char);
|
||||
BITSIZE(short);
|
||||
BITSIZE(int);
|
||||
BITSIZE(long);
|
||||
#ifdef HAVE_LONG_LONG
|
||||
BITSIZE(long long);
|
||||
#endif
|
||||
fprintf(f, "/* There is no %d bit type */\n", len);
|
||||
}
|
||||
|
||||
static void
|
||||
try_unsigned(FILE *f, int len)
|
||||
{
|
||||
BITSIZE(unsigned char);
|
||||
BITSIZE(unsigned short);
|
||||
BITSIZE(unsigned int);
|
||||
BITSIZE(unsigned long);
|
||||
#ifdef HAVE_LONG_LONG
|
||||
BITSIZE(unsigned long long);
|
||||
#endif
|
||||
fprintf(f, "/* There is no %d bit type */\n", len);
|
||||
}
|
||||
|
||||
static int print_pre(FILE *f)
|
||||
{
|
||||
fprintf(f,
|
||||
"/* GLOBAL.H - RSAREF types and constants\n"
|
||||
" */\n"
|
||||
"#ifndef MD5GLOBAL_H\n"
|
||||
"#define MD5GLOBAL_H\n"
|
||||
"\n"
|
||||
"/* PROTOTYPES should be set to one if and only if the compiler supports\n"
|
||||
" function argument prototyping.\n"
|
||||
"The following makes PROTOTYPES default to 0 if it has not already\n"
|
||||
" been defined with C compiler flags.\n"
|
||||
" */\n"
|
||||
"#ifndef PROTOTYPES\n"
|
||||
"#define PROTOTYPES 0\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"/* POINTER defines a generic pointer type */\n"
|
||||
"typedef unsigned char *POINTER;\n"
|
||||
"\n"
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int print_post(FILE *f)
|
||||
{
|
||||
fprintf(f, "\n"
|
||||
"/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.\n"
|
||||
"If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it\n"
|
||||
"returns an empty list.\n"
|
||||
"*/\n"
|
||||
"#if PROTOTYPES\n"
|
||||
"#define PROTO_LIST(list) list\n"
|
||||
"#else\n"
|
||||
"#define PROTO_LIST(list) ()\n"
|
||||
"#endif\n"
|
||||
"\n"
|
||||
"#endif /* MD5GLOBAL_H */\n\n"
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *f;
|
||||
char *fn, *hb;
|
||||
|
||||
if(argc < 2){
|
||||
fn = "bits.h";
|
||||
hb = "__BITS_H__";
|
||||
f = stdout;
|
||||
} else {
|
||||
char *p;
|
||||
fn = argv[1];
|
||||
hb = malloc(strlen(fn) + 5);
|
||||
sprintf(hb, "__%s__", fn);
|
||||
for(p = hb; *p; p++){
|
||||
if(!isalnum((int) *p))
|
||||
*p = '_';
|
||||
}
|
||||
f = fopen(argv[1], "w");
|
||||
}
|
||||
|
||||
print_pre(f);
|
||||
|
||||
#ifndef HAVE_INT8_T
|
||||
try_signed (f, 8);
|
||||
#endif /* HAVE_INT8_T */
|
||||
#ifndef HAVE_INT16_T
|
||||
try_signed (f, 16);
|
||||
#endif /* HAVE_INT16_T */
|
||||
#ifndef HAVE_INT32_T
|
||||
try_signed (f, 32);
|
||||
#endif /* HAVE_INT32_T */
|
||||
#ifndef HAVE_INT64_T
|
||||
try_signed (f, 64);
|
||||
#endif /* HAVE_INT64_T */
|
||||
|
||||
#ifndef HAVE_U_INT8_T
|
||||
try_unsigned (f, 8);
|
||||
#endif /* HAVE_INT8_T */
|
||||
#ifndef HAVE_U_INT16_T
|
||||
try_unsigned (f, 16);
|
||||
#endif /* HAVE_U_INT16_T */
|
||||
#ifndef HAVE_U_INT32_T
|
||||
try_unsigned (f, 32);
|
||||
#endif /* HAVE_U_INT32_T */
|
||||
#ifndef HAVE_U_INT64_T
|
||||
try_unsigned (f, 64);
|
||||
#endif /* HAVE_U_INT64_T */
|
||||
|
||||
print_post(f);
|
||||
|
||||
fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/* MD5.H - header file for MD5C.C
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
*/
|
||||
|
||||
/* MD5 context. */
|
||||
typedef struct {
|
||||
UINT4 state[4]; /* state (ABCD) */
|
||||
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
unsigned char buffer[64]; /* input buffer */
|
||||
} MD5_CTX;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void _sasl_MD5Init (MD5_CTX *);
|
||||
void _sasl_MD5Update (MD5_CTX *, const unsigned char *, unsigned int);
|
||||
void _sasl_MD5Final (unsigned char [16], MD5_CTX *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,38 @@
|
||||
/* GLOBAL.H - RSAREF types and constants
|
||||
*/
|
||||
#ifndef MD5GLOBAL_H
|
||||
#define MD5GLOBAL_H
|
||||
|
||||
/* PROTOTYPES should be set to one if and only if the compiler supports
|
||||
function argument prototyping.
|
||||
The following makes PROTOTYPES default to 0 if it has not already
|
||||
been defined with C compiler flags.
|
||||
*/
|
||||
#ifndef PROTOTYPES
|
||||
#define PROTOTYPES 0
|
||||
#endif
|
||||
|
||||
/* POINTER defines a generic pointer type */
|
||||
typedef unsigned char *POINTER;
|
||||
|
||||
typedef signed char INT1; /* 8 bits */
|
||||
typedef short INT2; /* 16 bits */
|
||||
typedef int INT4; /* 32 bits */
|
||||
/* There is no 64 bit type */
|
||||
typedef unsigned char UINT1; /* 8 bits */
|
||||
typedef unsigned short UINT2; /* 16 bits */
|
||||
typedef unsigned int UINT4; /* 32 bits */
|
||||
/* There is no 64 bit type */
|
||||
|
||||
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
|
||||
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
|
||||
returns an empty list.
|
||||
*/
|
||||
#if PROTOTYPES
|
||||
#define PROTO_LIST(list) list
|
||||
#else
|
||||
#define PROTO_LIST(list) ()
|
||||
#endif
|
||||
|
||||
#endif /* MD5GLOBAL_H */
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/* prop.h -- property request/response management routines
|
||||
*
|
||||
* Author: Chris Newman
|
||||
* Removal of implementation-specific details by: Rob Siemborski
|
||||
*
|
||||
* This is intended to be used to create a list of properties to request,
|
||||
* and _then_ request values for all properties. Any change to the request
|
||||
* list will discard any existing values. This assumption allows a very
|
||||
* efficient and simple memory model. This was designed for SASL API auxiliary
|
||||
* property support, but would be fine for other contexts where this property
|
||||
* model is appropriate.
|
||||
*
|
||||
* The "struct propctx" is allocated by prop_new and is a fixed size structure.
|
||||
* If a prop_init() call were added, it would be reasonable to embed a "struct
|
||||
* propctx" in another structure. prop_new also allocates a pool of memory
|
||||
* (in the vbase field) which will be used for an array of "struct propval"
|
||||
* to list all the requested properties.
|
||||
*
|
||||
* Properties may be multi-valued.
|
||||
*/
|
||||
|
||||
#ifndef PROP_H
|
||||
#define PROP_H 1
|
||||
|
||||
/* The following ifdef block is the standard way of creating macros
|
||||
* which make exporting from a DLL simpler. All files within this DLL
|
||||
* are compiled with the LIBSASL_EXPORTS symbol defined on the command
|
||||
* line. this symbol should not be defined on any project that uses
|
||||
* this DLL. This way any other project whose source files include
|
||||
* this file see LIBSASL_API functions as being imported from a DLL,
|
||||
* wheras this DLL sees symbols defined with this macro as being
|
||||
* exported. */
|
||||
/* Under Unix, life is simpler: we just need to mark library functions
|
||||
* as extern. (Technically, we don't even have to do that.) */
|
||||
#ifdef WIN32
|
||||
# ifdef LIBSASL_EXPORTS
|
||||
# define LIBSASL_API extern __declspec(dllexport)
|
||||
# else /* LIBSASL_EXPORTS */
|
||||
# define LIBSASL_API extern __declspec(dllimport)
|
||||
# endif /* LIBSASL_EXPORTS */
|
||||
#else /* WIN32 */
|
||||
# define LIBSASL_API extern
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* Same as above, but used during a variable declaration. */
|
||||
#ifdef WIN32
|
||||
# ifdef LIBSASL_EXPORTS
|
||||
# define LIBSASL_VAR extern __declspec(dllexport)
|
||||
# else /* LIBSASL_EXPORTS */
|
||||
# define LIBSASL_VAR extern __declspec(dllimport)
|
||||
# endif /* LIBSASL_EXPORTS */
|
||||
#else /* WIN32 */
|
||||
# define LIBSASL_VAR extern
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* the resulting structure for property values
|
||||
*/
|
||||
struct propval {
|
||||
const char *name; /* name of property; NULL = end of list */
|
||||
/* same pointer used in request will be used here */
|
||||
const char **values; /* list of strings, values == NULL if property not
|
||||
* found, *values == NULL if property found with
|
||||
* no values */
|
||||
unsigned nvalues; /* total number of value strings */
|
||||
unsigned valsize; /* total size in characters of all value strings */
|
||||
};
|
||||
|
||||
/*
|
||||
* private internal structure
|
||||
*/
|
||||
#define PROP_DEFAULT 4 /* default number of propvals to assume */
|
||||
struct propctx;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* create a property context
|
||||
* estimate -- an estimate of the storage needed for requests & responses
|
||||
* 0 will use module default
|
||||
* returns a new property context on success and NULL on any error
|
||||
*/
|
||||
LIBSASL_API struct propctx *prop_new(unsigned estimate);
|
||||
|
||||
/* create new propctx which duplicates the contents of an existing propctx
|
||||
* returns SASL_OK on success
|
||||
* possible other return values include: SASL_NOMEM, SASL_BADPARAM
|
||||
*/
|
||||
LIBSASL_API int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx);
|
||||
|
||||
/* Add property names to request
|
||||
* ctx -- context from prop_new()
|
||||
* names -- list of property names; must persist until context freed
|
||||
* or requests cleared (This extends to other contexts that
|
||||
* are dup'ed from this one, and their children, etc)
|
||||
*
|
||||
* NOTE: may clear values from context as side-effect
|
||||
* returns SASL_OK on success
|
||||
* possible other return values include: SASL_NOMEM, SASL_BADPARAM
|
||||
*/
|
||||
LIBSASL_API int prop_request(struct propctx *ctx, const char **names);
|
||||
|
||||
/* return array of struct propval from the context
|
||||
* return value persists until next call to
|
||||
* prop_request, prop_clear or prop_dispose on context
|
||||
*
|
||||
* returns NULL on error
|
||||
*/
|
||||
LIBSASL_API const struct propval *prop_get(struct propctx *ctx);
|
||||
|
||||
/* Fill in an array of struct propval based on a list of property names
|
||||
* return value persists until next call to
|
||||
* prop_request, prop_clear or prop_dispose on context
|
||||
* returns number of matching properties which were found (values != NULL)
|
||||
* if a name requested here was never requested by a prop_request, then
|
||||
* the name field of the associated vals entry will be set to NULL
|
||||
*
|
||||
* The vals array MUST be atleast as long as the names array.
|
||||
*
|
||||
* returns # of matching properties on success
|
||||
* possible other return values include: SASL_BADPARAM
|
||||
*/
|
||||
LIBSASL_API int prop_getnames(struct propctx *ctx, const char **names,
|
||||
struct propval *vals);
|
||||
|
||||
/* clear values and optionally requests from property context
|
||||
* ctx -- property context
|
||||
* requests -- 0 = don't clear requests, 1 = clear requests
|
||||
*/
|
||||
LIBSASL_API void prop_clear(struct propctx *ctx, int requests);
|
||||
|
||||
/* erase the value of a property
|
||||
*/
|
||||
LIBSASL_API void prop_erase(struct propctx *ctx, const char *name);
|
||||
|
||||
/* dispose of property context
|
||||
* ctx -- is disposed and set to NULL; noop if ctx or *ctx is NULL
|
||||
*/
|
||||
LIBSASL_API void prop_dispose(struct propctx **ctx);
|
||||
|
||||
|
||||
/****fetcher interfaces****/
|
||||
|
||||
/* format the requested property names into a string
|
||||
* ctx -- context from prop_new()/prop_request()
|
||||
* sep -- separator between property names (unused if none requested)
|
||||
* seplen -- length of separator, if < 0 then strlen(sep) will be used
|
||||
* outbuf -- output buffer
|
||||
* outmax -- maximum length of output buffer including NUL terminator
|
||||
* outlen -- set to length of output string excluding NUL terminator
|
||||
* returns SASL_OK on success
|
||||
* returns SASL_BADPARAM or amount of additional space needed on failure
|
||||
*/
|
||||
LIBSASL_API int prop_format(struct propctx *ctx, const char *sep, int seplen,
|
||||
char *outbuf, unsigned outmax, unsigned *outlen);
|
||||
|
||||
/* add a property value to the context
|
||||
* ctx -- context from prop_new()/prop_request()
|
||||
* name -- name of property to which value will be added
|
||||
* if NULL, add to the same name as previous prop_set/setvals call
|
||||
* value -- a value for the property; will be copied into context
|
||||
* if NULL, remove existing values
|
||||
* vallen -- length of value, if <= 0 then strlen(value) will be used
|
||||
* returns SASL_OK on success
|
||||
* possible error return values include: SASL_BADPARAM, SASL_NOMEM
|
||||
*/
|
||||
LIBSASL_API int prop_set(struct propctx *ctx, const char *name,
|
||||
const char *value, int vallen);
|
||||
|
||||
/* set the values for a property
|
||||
* ctx -- context from prop_new()/prop_request()
|
||||
* name -- name of property to which value will be added
|
||||
* if NULL, add to the same name as previous prop_set/setvals call
|
||||
* values -- array of values, ending in NULL. Each value is a NUL terminated
|
||||
* string
|
||||
* returns SASL_OK on success
|
||||
* possible error return values include: SASL_BADPARAM, SASL_NOMEM
|
||||
*/
|
||||
LIBSASL_API int prop_setvals(struct propctx *ctx, const char *name,
|
||||
const char **values);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PROP_H */
|
||||
+1321
File diff suppressed because it is too large
Load Diff
+986
@@ -0,0 +1,986 @@
|
||||
/* saslplug.h -- API for SASL plug-ins
|
||||
*/
|
||||
|
||||
#ifndef SASLPLUG_H
|
||||
#define SASLPLUG_H 1
|
||||
|
||||
#ifndef MD5GLOBAL_H
|
||||
#include "md5global.h"
|
||||
#endif
|
||||
#ifndef MD5_H
|
||||
#include "md5.h"
|
||||
#endif
|
||||
#ifndef HMAC_MD5_H
|
||||
#include "hmac-md5.h"
|
||||
#endif
|
||||
#ifndef PROP_H
|
||||
#include "prop.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* callback to lookup a sasl_callback_t for a connection
|
||||
* input:
|
||||
* conn -- the connection to lookup a callback for
|
||||
* callbacknum -- the number of the callback
|
||||
* output:
|
||||
* pproc -- pointer to the callback function (set to NULL on failure)
|
||||
* pcontext -- pointer to the callback context (set to NULL on failure)
|
||||
* returns:
|
||||
* SASL_OK -- no error
|
||||
* SASL_FAIL -- unable to find a callback of the requested type
|
||||
* SASL_INTERACT -- caller must use interaction to get data
|
||||
*/
|
||||
typedef int (*sasl_callback_ft)(void);
|
||||
typedef int sasl_getcallback_t(sasl_conn_t *conn,
|
||||
unsigned long callbackid,
|
||||
sasl_callback_ft * pproc,
|
||||
void **pcontext);
|
||||
|
||||
/* The sasl_utils structure will remain backwards compatible unless
|
||||
* the SASL_*_PLUG_VERSION is changed incompatibly
|
||||
* higher SASL_UTILS_VERSION numbers indicate more functions are available
|
||||
*/
|
||||
#define SASL_UTILS_VERSION 4
|
||||
|
||||
/* utility function set for plug-ins
|
||||
*/
|
||||
typedef struct sasl_utils {
|
||||
int version;
|
||||
|
||||
/* contexts */
|
||||
sasl_conn_t *conn;
|
||||
sasl_rand_t *rpool;
|
||||
void *getopt_context;
|
||||
|
||||
/* option function */
|
||||
sasl_getopt_t *getopt;
|
||||
|
||||
/* allocation functions: */
|
||||
sasl_malloc_t *malloc;
|
||||
sasl_calloc_t *calloc;
|
||||
sasl_realloc_t *realloc;
|
||||
sasl_free_t *free;
|
||||
|
||||
/* mutex functions: */
|
||||
sasl_mutex_alloc_t *mutex_alloc;
|
||||
sasl_mutex_lock_t *mutex_lock;
|
||||
sasl_mutex_unlock_t *mutex_unlock;
|
||||
sasl_mutex_free_t *mutex_free;
|
||||
|
||||
/* MD5 hash and HMAC functions */
|
||||
void (*MD5Init)(MD5_CTX *);
|
||||
void (*MD5Update)(MD5_CTX *, const unsigned char *text, unsigned int len);
|
||||
void (*MD5Final)(unsigned char [16], MD5_CTX *);
|
||||
void (*hmac_md5)(const unsigned char *text, int text_len,
|
||||
const unsigned char *key, int key_len,
|
||||
unsigned char [16]);
|
||||
void (*hmac_md5_init)(HMAC_MD5_CTX *, const unsigned char *key, int len);
|
||||
/* hmac_md5_update() is just a call to MD5Update on inner context */
|
||||
void (*hmac_md5_final)(unsigned char [16], HMAC_MD5_CTX *);
|
||||
void (*hmac_md5_precalc)(HMAC_MD5_STATE *,
|
||||
const unsigned char *key, int len);
|
||||
void (*hmac_md5_import)(HMAC_MD5_CTX *, HMAC_MD5_STATE *);
|
||||
|
||||
/* mechanism utility functions (same as above): */
|
||||
int (*mkchal)(sasl_conn_t *conn, char *buf, unsigned maxlen,
|
||||
unsigned hostflag);
|
||||
int (*utf8verify)(const char *str, unsigned len);
|
||||
void (*rand)(sasl_rand_t *rpool, char *buf, unsigned len);
|
||||
void (*churn)(sasl_rand_t *rpool, const char *data, unsigned len);
|
||||
|
||||
/* This allows recursive calls to the sasl_checkpass() routine from
|
||||
* within a SASL plug-in. This MUST NOT be used in the PLAIN mechanism
|
||||
* as sasl_checkpass MAY be a front-end for the PLAIN mechanism.
|
||||
* This is intended for use by the non-standard LOGIN mechanism and
|
||||
* potentially by a future mechanism which uses public-key technology to
|
||||
* set up a lightweight encryption layer just for sending a password.
|
||||
*/
|
||||
int (*checkpass)(sasl_conn_t *conn,
|
||||
const char *user, unsigned userlen,
|
||||
const char *pass, unsigned passlen);
|
||||
|
||||
/* Access to base64 encode/decode routines */
|
||||
int (*decode64)(const char *in, unsigned inlen,
|
||||
char *out, unsigned outmax, unsigned *outlen);
|
||||
int (*encode64)(const char *in, unsigned inlen,
|
||||
char *out, unsigned outmax, unsigned *outlen);
|
||||
|
||||
/* erase a buffer */
|
||||
void (*erasebuffer)(char *buf, unsigned len);
|
||||
|
||||
/* callback to sasl_getprop() and sasl_setprop() */
|
||||
int (*getprop)(sasl_conn_t *conn, int propnum, const void **pvalue);
|
||||
int (*setprop)(sasl_conn_t *conn, int propnum, const void *value);
|
||||
|
||||
/* callback function */
|
||||
sasl_getcallback_t *getcallback;
|
||||
|
||||
/* format a message and then pass it to the SASL_CB_LOG callback
|
||||
*
|
||||
* use syslog()-style formatting (printf with %m as a human readable text
|
||||
* (strerror()) for the error specified as the parameter).
|
||||
* The implementation may use a fixed size buffer not smaller
|
||||
* than 512 octets if it securely truncates the message.
|
||||
*
|
||||
* level is a SASL_LOG_* level (see sasl.h)
|
||||
*/
|
||||
void (*log)(sasl_conn_t *conn, int level, const char *fmt, ...);
|
||||
|
||||
/* callback to sasl_seterror() */
|
||||
void (*seterror)(sasl_conn_t *conn, unsigned flags, const char *fmt, ...);
|
||||
|
||||
/* spare function pointer */
|
||||
int *(*spare_fptr)(void);
|
||||
|
||||
/* auxiliary property utilities */
|
||||
struct propctx *(*prop_new)(unsigned estimate);
|
||||
int (*prop_dup)(struct propctx *src_ctx, struct propctx **dst_ctx);
|
||||
int (*prop_request)(struct propctx *ctx, const char **names);
|
||||
const struct propval *(*prop_get)(struct propctx *ctx);
|
||||
int (*prop_getnames)(struct propctx *ctx, const char **names,
|
||||
struct propval *vals);
|
||||
void (*prop_clear)(struct propctx *ctx, int requests);
|
||||
void (*prop_dispose)(struct propctx **ctx);
|
||||
int (*prop_format)(struct propctx *ctx, const char *sep, int seplen,
|
||||
char *outbuf, unsigned outmax, unsigned *outlen);
|
||||
int (*prop_set)(struct propctx *ctx, const char *name,
|
||||
const char *value, int vallen);
|
||||
int (*prop_setvals)(struct propctx *ctx, const char *name,
|
||||
const char **values);
|
||||
void (*prop_erase)(struct propctx *ctx, const char *name);
|
||||
int (*auxprop_store)(sasl_conn_t *conn,
|
||||
struct propctx *ctx, const char *user);
|
||||
|
||||
/* for additions which don't require a version upgrade; set to 0 */
|
||||
int (*spare_fptr1)(void);
|
||||
int (*spare_fptr2)(void);
|
||||
} sasl_utils_t;
|
||||
|
||||
/*
|
||||
* output parameters from SASL API
|
||||
*
|
||||
* created / destroyed by the glue code, though probably filled in
|
||||
* by a combination of the plugin, the glue code, and the canon_user callback.
|
||||
*
|
||||
*/
|
||||
typedef struct sasl_out_params {
|
||||
unsigned doneflag; /* exchange complete */
|
||||
|
||||
const char *user; /* canonicalized user name */
|
||||
const char *authid; /* canonicalized authentication id */
|
||||
|
||||
unsigned ulen; /* length of canonicalized user name */
|
||||
unsigned alen; /* length of canonicalized authid */
|
||||
|
||||
/* security layer information */
|
||||
unsigned maxoutbuf; /* Maximum buffer size, which will
|
||||
produce buffer no bigger than the
|
||||
negotiated SASL maximum buffer size */
|
||||
sasl_ssf_t mech_ssf; /* Should be set non-zero if negotiation of a
|
||||
* security layer was *attempted*, even if
|
||||
* the negotiation failed */
|
||||
void *encode_context;
|
||||
int (*encode)(void *context, const struct iovec *invec, unsigned numiov,
|
||||
const char **output, unsigned *outputlen);
|
||||
void *decode_context;
|
||||
int (*decode)(void *context, const char *input, unsigned inputlen,
|
||||
const char **output, unsigned *outputlen);
|
||||
|
||||
/* Pointer to delegated (client's) credentials, if supported by
|
||||
the SASL mechanism */
|
||||
void *client_creds;
|
||||
|
||||
/* for additions which don't require a version upgrade; set to 0 */
|
||||
const void *gss_peer_name;
|
||||
const void *gss_local_name;
|
||||
const char *cbindingname; /* channel binding name from packet */
|
||||
int (*spare_fptr1)(void);
|
||||
int (*spare_fptr2)(void);
|
||||
unsigned int cbindingdisp; /* channel binding disposition from client */
|
||||
int spare_int2;
|
||||
int spare_int3;
|
||||
int spare_int4;
|
||||
|
||||
/* set to 0 initially, this allows a plugin with extended parameters
|
||||
* to work with an older framework by updating version as parameters
|
||||
* are added.
|
||||
*/
|
||||
int param_version;
|
||||
} sasl_out_params_t;
|
||||
|
||||
|
||||
|
||||
/* Used by both client and server side plugins */
|
||||
typedef enum {
|
||||
SASL_INFO_LIST_START = 0,
|
||||
SASL_INFO_LIST_MECH,
|
||||
SASL_INFO_LIST_END
|
||||
} sasl_info_callback_stage_t;
|
||||
|
||||
/******************************
|
||||
* Channel binding macros **
|
||||
******************************/
|
||||
|
||||
typedef enum {
|
||||
SASL_CB_DISP_NONE = 0, /* client did not support CB */
|
||||
SASL_CB_DISP_WANT, /* client supports CB, thinks server does not */
|
||||
SASL_CB_DISP_USED /* client supports and used CB */
|
||||
} sasl_cbinding_disp_t;
|
||||
|
||||
/* TRUE if channel binding is non-NULL */
|
||||
#define SASL_CB_PRESENT(params) ((params)->cbinding != NULL)
|
||||
/* TRUE if channel binding is marked critical */
|
||||
#define SASL_CB_CRITICAL(params) (SASL_CB_PRESENT(params) && \
|
||||
(params)->cbinding->critical)
|
||||
|
||||
/******************************
|
||||
* Client Mechanism Functions *
|
||||
******************************/
|
||||
|
||||
/*
|
||||
* input parameters to client SASL plugin
|
||||
*
|
||||
* created / destroyed by the glue code
|
||||
*
|
||||
*/
|
||||
typedef struct sasl_client_params {
|
||||
const char *service; /* service name */
|
||||
const char *serverFQDN; /* server fully qualified domain name */
|
||||
const char *clientFQDN; /* client's fully qualified domain name */
|
||||
const sasl_utils_t *utils; /* SASL API utility routines --
|
||||
* for a particular sasl_conn_t,
|
||||
* MUST remain valid until mech_free is
|
||||
* called */
|
||||
const sasl_callback_t *prompt_supp; /* client callback list */
|
||||
const char *iplocalport; /* server IP domain literal & port */
|
||||
const char *ipremoteport; /* client IP domain literal & port */
|
||||
|
||||
unsigned servicelen; /* length of service */
|
||||
unsigned slen; /* length of serverFQDN */
|
||||
unsigned clen; /* length of clientFQDN */
|
||||
unsigned iploclen; /* length of iplocalport */
|
||||
unsigned ipremlen; /* length of ipremoteport */
|
||||
|
||||
/* application's security requirements & info */
|
||||
sasl_security_properties_t props;
|
||||
sasl_ssf_t external_ssf; /* external SSF active */
|
||||
|
||||
/* for additions which don't require a version upgrade; set to 0 */
|
||||
const void *gss_creds; /* GSS credential handle */
|
||||
const sasl_channel_binding_t *cbinding; /* client channel binding */
|
||||
const sasl_http_request_t *http_request;/* HTTP Digest request method */
|
||||
void *spare_ptr4;
|
||||
|
||||
/* Canonicalize a user name from on-wire to internal format
|
||||
* added rjs3 2001-05-23
|
||||
* Must be called once user name aquired if canon_user is non-NULL.
|
||||
* conn connection context
|
||||
* in user name from wire protocol (need not be NUL terminated)
|
||||
* len length of user name from wire protocol (0 = strlen(user))
|
||||
* flags for SASL_CU_* flags
|
||||
* oparams the user, authid, ulen, alen, fields are
|
||||
* set appropriately after canonicalization/copying and
|
||||
* authorization of arguments
|
||||
*
|
||||
* responsible for setting user, ulen, authid, and alen in the oparams
|
||||
* structure
|
||||
*
|
||||
* default behavior is to strip leading and trailing whitespace, as
|
||||
* well as allocating space for and copying the parameters.
|
||||
*
|
||||
* results:
|
||||
* SASL_OK -- success
|
||||
* SASL_NOMEM -- out of memory
|
||||
* SASL_BADPARAM -- invalid conn
|
||||
* SASL_BADPROT -- invalid user/authid
|
||||
*/
|
||||
int (*canon_user)(sasl_conn_t *conn,
|
||||
const char *in, unsigned len,
|
||||
unsigned flags,
|
||||
sasl_out_params_t *oparams);
|
||||
|
||||
int (*spare_fptr1)(void);
|
||||
|
||||
unsigned int cbindingdisp;
|
||||
int spare_int2;
|
||||
int spare_int3;
|
||||
|
||||
/* flags field as passed to sasl_client_new */
|
||||
unsigned flags;
|
||||
|
||||
/* set to 0 initially, this allows a plugin with extended parameters
|
||||
* to work with an older framework by updating version as parameters
|
||||
* are added.
|
||||
*/
|
||||
int param_version;
|
||||
} sasl_client_params_t;
|
||||
|
||||
/* features shared between client and server */
|
||||
/* These allow the glue code to handle client-first and server-last issues */
|
||||
|
||||
/* This indicates that the mechanism prefers to do client-send-first
|
||||
* if the protocol allows it. */
|
||||
#define SASL_FEAT_WANT_CLIENT_FIRST 0x0002
|
||||
|
||||
/* This feature is deprecated. Instead, plugins should set *serverout to
|
||||
* non-NULL and return SASL_OK intelligently to allow flexible use of
|
||||
* server-last semantics
|
||||
#define SASL_FEAT_WANT_SERVER_LAST 0x0004
|
||||
*/
|
||||
|
||||
/* This feature is deprecated. Instead, plugins should correctly set
|
||||
* SASL_FEAT_SERVER_FIRST as needed
|
||||
#define SASL_FEAT_INTERNAL_CLIENT_FIRST 0x0008
|
||||
*/
|
||||
|
||||
/* This indicates that the plugin is server-first only.
|
||||
* Not defining either of SASL_FEAT_SERVER_FIRST or
|
||||
* SASL_FEAT_WANT_CLIENT_FIRST indicates that the mechanism
|
||||
* will handle the client-first situation internally.
|
||||
*/
|
||||
#define SASL_FEAT_SERVER_FIRST 0x0010
|
||||
|
||||
/* This plugin allows proxying */
|
||||
#define SASL_FEAT_ALLOWS_PROXY 0x0020
|
||||
|
||||
/* server plugin don't use cleartext userPassword attribute */
|
||||
#define SASL_FEAT_DONTUSE_USERPASSWD 0x0080
|
||||
|
||||
/* Underlying mechanism uses GSS framing */
|
||||
#define SASL_FEAT_GSS_FRAMING 0x0100
|
||||
|
||||
/* Underlying mechanism supports channel binding */
|
||||
#define SASL_FEAT_CHANNEL_BINDING 0x0800
|
||||
|
||||
/* This plugin can be used for HTTP authentication */
|
||||
#define SASL_FEAT_SUPPORTS_HTTP 0x1000
|
||||
|
||||
/* client plug-in features */
|
||||
#define SASL_FEAT_NEEDSERVERFQDN 0x0001
|
||||
|
||||
/* a C object for a client mechanism
|
||||
*/
|
||||
typedef struct sasl_client_plug {
|
||||
/* mechanism name */
|
||||
const char *mech_name;
|
||||
|
||||
/* best mech additional security layer strength factor */
|
||||
sasl_ssf_t max_ssf;
|
||||
|
||||
/* best security flags, as defined in sasl_security_properties_t */
|
||||
unsigned security_flags;
|
||||
|
||||
/* features of plugin */
|
||||
unsigned features;
|
||||
|
||||
/* required prompt ids, NULL = user/pass only */
|
||||
const unsigned long *required_prompts;
|
||||
|
||||
/* global state for mechanism */
|
||||
void *glob_context;
|
||||
|
||||
/* create context for mechanism, using params supplied
|
||||
* glob_context -- from above
|
||||
* params -- params from sasl_client_new
|
||||
* conn_context -- context for one connection
|
||||
* returns:
|
||||
* SASL_OK -- success
|
||||
* SASL_NOMEM -- not enough memory
|
||||
* SASL_WRONGMECH -- mech doesn't support security params
|
||||
*/
|
||||
int (*mech_new)(void *glob_context,
|
||||
sasl_client_params_t *cparams,
|
||||
void **conn_context);
|
||||
|
||||
/* perform one step of exchange. NULL is passed for serverin on
|
||||
* first step.
|
||||
* returns:
|
||||
* SASL_OK -- success
|
||||
* SASL_INTERACT -- user interaction needed to fill in prompts
|
||||
* SASL_BADPROT -- server protocol incorrect/cancelled
|
||||
* SASL_BADSERV -- server failed mutual auth
|
||||
*/
|
||||
int (*mech_step)(void *conn_context,
|
||||
sasl_client_params_t *cparams,
|
||||
const char *serverin,
|
||||
unsigned serverinlen,
|
||||
sasl_interact_t **prompt_need,
|
||||
const char **clientout,
|
||||
unsigned *clientoutlen,
|
||||
sasl_out_params_t *oparams);
|
||||
|
||||
/* dispose of connection context from mech_new
|
||||
*/
|
||||
void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils);
|
||||
|
||||
/* free all global space used by mechanism
|
||||
* mech_dispose must be called on all mechanisms first
|
||||
*/
|
||||
void (*mech_free)(void *glob_context, const sasl_utils_t *utils);
|
||||
|
||||
/* perform precalculations during a network round-trip
|
||||
* or idle period. conn_context may be NULL
|
||||
* returns 1 if action taken, 0 if no action taken
|
||||
*/
|
||||
int (*idle)(void *glob_context,
|
||||
void *conn_context,
|
||||
sasl_client_params_t *cparams);
|
||||
|
||||
/* for additions which don't require a version upgrade; set to 0 */
|
||||
int (*spare_fptr1)(void);
|
||||
int (*spare_fptr2)(void);
|
||||
} sasl_client_plug_t;
|
||||
|
||||
#define SASL_CLIENT_PLUG_VERSION 4
|
||||
|
||||
/* plug-in entry point:
|
||||
* utils -- utility callback functions
|
||||
* max_version -- highest client plug version supported
|
||||
* returns:
|
||||
* out_version -- client plug version of result
|
||||
* pluglist -- list of mechanism plug-ins
|
||||
* plugcount -- number of mechanism plug-ins
|
||||
* results:
|
||||
* SASL_OK -- success
|
||||
* SASL_NOMEM -- failure
|
||||
* SASL_BADVERS -- max_version too small
|
||||
* SASL_BADPARAM -- bad config string
|
||||
* ...
|
||||
*/
|
||||
typedef int sasl_client_plug_init_t(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_client_plug_t **pluglist,
|
||||
int *plugcount);
|
||||
|
||||
|
||||
/* add a client plug-in
|
||||
*/
|
||||
LIBSASL_API int sasl_client_add_plugin(const char *plugname,
|
||||
sasl_client_plug_init_t *cplugfunc);
|
||||
|
||||
typedef struct client_sasl_mechanism
|
||||
{
|
||||
int version;
|
||||
|
||||
char *plugname;
|
||||
const sasl_client_plug_t *plug;
|
||||
} client_sasl_mechanism_t;
|
||||
|
||||
typedef void sasl_client_info_callback_t (client_sasl_mechanism_t *m,
|
||||
sasl_info_callback_stage_t stage,
|
||||
void *rock);
|
||||
|
||||
/* Dump information about available client plugins */
|
||||
LIBSASL_API int sasl_client_plugin_info (const char *mech_list,
|
||||
sasl_client_info_callback_t *info_cb,
|
||||
void *info_cb_rock);
|
||||
|
||||
|
||||
/********************
|
||||
* Server Functions *
|
||||
********************/
|
||||
|
||||
/* log message formatting routine */
|
||||
typedef void sasl_logmsg_p(sasl_conn_t *conn, const char *fmt, ...);
|
||||
|
||||
/*
|
||||
* input parameters to server SASL plugin
|
||||
*
|
||||
* created / destroyed by the glue code
|
||||
*
|
||||
*/
|
||||
typedef struct sasl_server_params {
|
||||
const char *service; /* NULL = default service for user_exists
|
||||
and setpass */
|
||||
const char *appname; /* name of calling application */
|
||||
const char *serverFQDN; /* server default fully qualified domain name
|
||||
* (e.g., gethostname) */
|
||||
const char *user_realm; /* realm for user (NULL = client supplied) */
|
||||
const char *iplocalport; /* server IP domain literal & port */
|
||||
const char *ipremoteport; /* client IP domain literal & port */
|
||||
|
||||
unsigned servicelen; /* length of service */
|
||||
unsigned applen; /* length of appname */
|
||||
unsigned slen; /* length of serverFQDN */
|
||||
unsigned urlen; /* length of user_realm */
|
||||
unsigned iploclen; /* length of iplocalport */
|
||||
unsigned ipremlen; /* length of ipremoteport */
|
||||
|
||||
/* This indicates the level of logging desired. See SASL_LOG_*
|
||||
* in sasl.h
|
||||
*
|
||||
* Plug-ins can ignore this and just pass their desired level to
|
||||
* the log callback. This is primarily used to eliminate logging which
|
||||
* might be a performance problem (e.g., full protocol trace) and
|
||||
* to select between SASL_LOG_TRACE and SASL_LOG_PASS alternatives
|
||||
*/
|
||||
int log_level;
|
||||
|
||||
const sasl_utils_t *utils; /* SASL API utility routines --
|
||||
* for a particular sasl_conn_t,
|
||||
* MUST remain valid until mech_free is
|
||||
* called */
|
||||
const sasl_callback_t *callbacks; /* Callbacks from application */
|
||||
|
||||
/* application's security requirements */
|
||||
sasl_security_properties_t props;
|
||||
sasl_ssf_t external_ssf; /* external SSF active */
|
||||
|
||||
/* Pointer to the function which takes the plaintext passphrase and
|
||||
* transitions a user to non-plaintext mechanisms via setpass calls.
|
||||
* (NULL = auto transition not enabled/supported)
|
||||
*
|
||||
* If passlen is 0, it defaults to strlen(pass).
|
||||
* returns 0 if no entry added, 1 if entry added
|
||||
*/
|
||||
int (*transition)(sasl_conn_t *conn, const char *pass, unsigned passlen);
|
||||
|
||||
/* Canonicalize a user name from on-wire to internal format
|
||||
* added cjn 1999-09-21
|
||||
* Must be called once user name acquired if canon_user is non-NULL.
|
||||
* conn connection context
|
||||
* user user name from wire protocol (need not be NUL terminated)
|
||||
* ulen length of user name from wire protocol (0 = strlen(user))
|
||||
* flags for SASL_CU_* flags
|
||||
* oparams the user, authid, ulen, alen, fields are
|
||||
* set appropriately after canonicalization/copying and
|
||||
* authorization of arguments
|
||||
*
|
||||
* responsible for setting user, ulen, authid, and alen in the oparams
|
||||
* structure
|
||||
*
|
||||
* default behavior is to strip leading and trailing whitespace, as
|
||||
* well as allocating space for and copying the parameters.
|
||||
*
|
||||
* results:
|
||||
* SASL_OK -- success
|
||||
* SASL_NOMEM -- out of memory
|
||||
* SASL_BADPARAM -- invalid conn
|
||||
* SASL_BADPROT -- invalid user/authid
|
||||
*/
|
||||
int (*canon_user)(sasl_conn_t *conn,
|
||||
const char *user, unsigned ulen,
|
||||
unsigned flags,
|
||||
sasl_out_params_t *oparams);
|
||||
|
||||
/* auxiliary property context (see definitions in prop.h)
|
||||
* added cjn 2000-01-30
|
||||
*
|
||||
* NOTE: these properties are the ones associated with the
|
||||
* canonicalized "user" (user to login as / authorization id), not
|
||||
* the "authid" (user whose credentials are used / authentication id)
|
||||
* Prefix the property name with a "*" if a property associated with
|
||||
* the "authid" is interesting.
|
||||
*/
|
||||
struct propctx *propctx;
|
||||
|
||||
/* for additions which don't require a version upgrade; set to 0 */
|
||||
const void *gss_creds; /* GSS credential handle */
|
||||
const sasl_channel_binding_t *cbinding; /* server channel binding */
|
||||
const sasl_http_request_t *http_request;/* HTTP Digest request method */
|
||||
void *spare_ptr4;
|
||||
int (*spare_fptr1)(void);
|
||||
int (*spare_fptr2)(void);
|
||||
int spare_int1;
|
||||
int spare_int2;
|
||||
int spare_int3;
|
||||
|
||||
/* flags field as passed to sasl_server_new */
|
||||
unsigned flags;
|
||||
|
||||
/* set to 0 initially, this allows a plugin with extended parameters
|
||||
* to work with an older framework by updating version as parameters
|
||||
* are added.
|
||||
*/
|
||||
int param_version;
|
||||
} sasl_server_params_t;
|
||||
|
||||
/* logging levels (more levels may be added later, if necessary):
|
||||
*/
|
||||
#define SASL_LOG_NONE 0 /* don't log anything */
|
||||
#define SASL_LOG_ERR 1 /* log unusual errors (default) */
|
||||
#define SASL_LOG_FAIL 2 /* log all authentication failures */
|
||||
#define SASL_LOG_WARN 3 /* log non-fatal warnings */
|
||||
#define SASL_LOG_NOTE 4 /* more verbose than LOG_WARN */
|
||||
#define SASL_LOG_DEBUG 5 /* more verbose than LOG_NOTE */
|
||||
#define SASL_LOG_TRACE 6 /* traces of internal protocols */
|
||||
#define SASL_LOG_PASS 7 /* traces of internal protocols, including
|
||||
* passwords */
|
||||
|
||||
/* additional flags for setpass() function below:
|
||||
*/
|
||||
/* SASL_SET_CREATE create user if pass non-NULL */
|
||||
/* SASL_SET_DISABLE disable user */
|
||||
#define SASL_SET_REMOVE SASL_SET_CREATE /* remove user if pass is NULL */
|
||||
|
||||
/* features for server plug-in
|
||||
*/
|
||||
#define SASL_FEAT_SERVICE 0x0200 /* service-specific passwords supported */
|
||||
#define SASL_FEAT_GETSECRET 0x0400 /* sasl_server_{get,put}secret_t callbacks
|
||||
* required by plug-in */
|
||||
|
||||
/* a C object for a server mechanism
|
||||
*/
|
||||
typedef struct sasl_server_plug {
|
||||
/* mechanism name */
|
||||
const char *mech_name;
|
||||
|
||||
/* best mech additional security layer strength factor */
|
||||
sasl_ssf_t max_ssf;
|
||||
|
||||
/* best security flags, as defined in sasl_security_properties_t */
|
||||
unsigned security_flags;
|
||||
|
||||
/* features of plugin */
|
||||
unsigned features;
|
||||
|
||||
/* global state for mechanism */
|
||||
void *glob_context;
|
||||
|
||||
/* create a new mechanism handler
|
||||
* glob_context -- global context
|
||||
* sparams -- server config params
|
||||
* challenge -- server challenge from previous instance or NULL
|
||||
* challen -- length of challenge from previous instance or 0
|
||||
* out:
|
||||
* conn_context -- connection context
|
||||
* errinfo -- error information
|
||||
*
|
||||
* returns:
|
||||
* SASL_OK -- successfully created mech instance
|
||||
* SASL_* -- any other server error code
|
||||
*/
|
||||
int (*mech_new)(void *glob_context,
|
||||
sasl_server_params_t *sparams,
|
||||
const char *challenge,
|
||||
unsigned challen,
|
||||
void **conn_context);
|
||||
|
||||
/* perform one step in exchange
|
||||
*
|
||||
* returns:
|
||||
* SASL_OK -- success, all done
|
||||
* SASL_CONTINUE -- success, one more round trip
|
||||
* SASL_* -- any other server error code
|
||||
*/
|
||||
int (*mech_step)(void *conn_context,
|
||||
sasl_server_params_t *sparams,
|
||||
const char *clientin,
|
||||
unsigned clientinlen,
|
||||
const char **serverout,
|
||||
unsigned *serveroutlen,
|
||||
sasl_out_params_t *oparams);
|
||||
|
||||
/* dispose of a connection state
|
||||
*/
|
||||
void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils);
|
||||
|
||||
/* free global state for mechanism
|
||||
* mech_dispose must be called on all mechanisms first
|
||||
*/
|
||||
void (*mech_free)(void *glob_context, const sasl_utils_t *utils);
|
||||
|
||||
/* set a password (optional)
|
||||
* glob_context -- global context
|
||||
* sparams -- service, middleware utilities, etc. props ignored
|
||||
* user -- user name
|
||||
* pass -- password/passphrase (NULL = disable/remove/delete)
|
||||
* passlen -- length of password/passphrase
|
||||
* oldpass -- old password/passphrase (NULL = transition)
|
||||
* oldpasslen -- length of password/passphrase
|
||||
* flags -- see above
|
||||
*
|
||||
* returns:
|
||||
* SASL_NOCHANGE -- no change was needed
|
||||
* SASL_NOUSER -- no entry for user
|
||||
* SASL_NOVERIFY -- no mechanism compatible entry for user
|
||||
* SASL_PWLOCK -- password locked
|
||||
* SASL_DIABLED -- account disabled
|
||||
* etc.
|
||||
*/
|
||||
int (*setpass)(void *glob_context,
|
||||
sasl_server_params_t *sparams,
|
||||
const char *user,
|
||||
const char *pass, unsigned passlen,
|
||||
const char *oldpass, unsigned oldpasslen,
|
||||
unsigned flags);
|
||||
|
||||
/* query which mechanisms are available for user
|
||||
* glob_context -- context
|
||||
* sparams -- service, middleware utilities, etc. props ignored
|
||||
* user -- NUL terminated user name
|
||||
* maxmech -- max number of strings in mechlist (0 = no output)
|
||||
* output:
|
||||
* mechlist -- an array of C string pointers, filled in with
|
||||
* mechanism names available to the user
|
||||
*
|
||||
* returns:
|
||||
* SASL_OK -- success
|
||||
* SASL_NOMEM -- not enough memory
|
||||
* SASL_FAIL -- lower level failure
|
||||
* SASL_DISABLED -- account disabled
|
||||
* SASL_NOUSER -- user not found
|
||||
* SASL_BUFOVER -- maxmech is too small
|
||||
* SASL_NOVERIFY -- user found, but no mechanisms available
|
||||
*/
|
||||
int (*user_query)(void *glob_context,
|
||||
sasl_server_params_t *sparams,
|
||||
const char *user,
|
||||
int maxmech,
|
||||
const char **mechlist);
|
||||
|
||||
/* perform precalculations during a network round-trip
|
||||
* or idle period. conn_context may be NULL (optional)
|
||||
* returns 1 if action taken, 0 if no action taken
|
||||
*/
|
||||
int (*idle)(void *glob_context,
|
||||
void *conn_context,
|
||||
sasl_server_params_t *sparams);
|
||||
|
||||
/* check if mechanism is available
|
||||
* optional--if NULL, mechanism is available based on ENABLE= in config
|
||||
*
|
||||
* If this routine sets conn_context to a non-NULL value, then the call
|
||||
* to mech_new will be skipped. This should not be done unless
|
||||
* there's a significant performance benefit, since it can cause
|
||||
* additional memory allocation in SASL core code to keep track of
|
||||
* contexts potentially for multiple mechanisms.
|
||||
*
|
||||
* This is called by the first call to sasl_listmech() for a
|
||||
* given connection context, thus for a given protocol it may
|
||||
* never be called. Note that if mech_avail returns SASL_NOMECH,
|
||||
* then that mechanism is considered disabled for the remainder
|
||||
* of the session. If mech_avail returns SASL_NOTDONE, then a
|
||||
* future call to mech_avail may still return either SASL_OK
|
||||
* or SASL_NOMECH.
|
||||
*
|
||||
* returns SASL_OK on success,
|
||||
* SASL_NOTDONE if mech is not available now, but may be later
|
||||
* (e.g. EXTERNAL w/o auth_id)
|
||||
* SASL_NOMECH if mech disabled
|
||||
*/
|
||||
int (*mech_avail)(void *glob_context,
|
||||
sasl_server_params_t *sparams,
|
||||
void **conn_context);
|
||||
|
||||
/* for additions which don't require a version upgrade; set to 0 */
|
||||
int (*spare_fptr2)(void);
|
||||
} sasl_server_plug_t;
|
||||
|
||||
#define SASL_SERVER_PLUG_VERSION 4
|
||||
|
||||
/* plug-in entry point:
|
||||
* utils -- utility callback functions
|
||||
* plugname -- name of plug-in (may be NULL)
|
||||
* max_version -- highest server plug version supported
|
||||
* returns:
|
||||
* out_version -- server plug-in version of result
|
||||
* pluglist -- list of mechanism plug-ins
|
||||
* plugcount -- number of mechanism plug-ins
|
||||
* results:
|
||||
* SASL_OK -- success
|
||||
* SASL_NOMEM -- failure
|
||||
* SASL_BADVERS -- max_version too small
|
||||
* SASL_BADPARAM -- bad config string
|
||||
* ...
|
||||
*/
|
||||
typedef int sasl_server_plug_init_t(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_server_plug_t **pluglist,
|
||||
int *plugcount);
|
||||
|
||||
/*
|
||||
* add a server plug-in
|
||||
*/
|
||||
LIBSASL_API int sasl_server_add_plugin(const char *plugname,
|
||||
sasl_server_plug_init_t *splugfunc);
|
||||
|
||||
|
||||
typedef struct server_sasl_mechanism
|
||||
{
|
||||
int version;
|
||||
int condition; /* set to SASL_NOUSER if no available users;
|
||||
set to SASL_CONTINUE if delayed plugin loading */
|
||||
char *plugname; /* for AUTHSOURCE tracking */
|
||||
const sasl_server_plug_t *plug;
|
||||
char *f; /* where should i load the mechanism from? */
|
||||
} server_sasl_mechanism_t;
|
||||
|
||||
typedef void sasl_server_info_callback_t (server_sasl_mechanism_t *m,
|
||||
sasl_info_callback_stage_t stage,
|
||||
void *rock);
|
||||
|
||||
|
||||
/* Dump information about available server plugins (separate functions are
|
||||
used for canon and auxprop plugins) */
|
||||
LIBSASL_API int sasl_server_plugin_info (const char *mech_list,
|
||||
sasl_server_info_callback_t *info_cb,
|
||||
void *info_cb_rock);
|
||||
|
||||
|
||||
/*********************************************************
|
||||
* user canonicalization plug-in -- added cjn 1999-09-29 *
|
||||
*********************************************************/
|
||||
|
||||
typedef struct sasl_canonuser {
|
||||
/* optional features of plugin (set to 0) */
|
||||
int features;
|
||||
|
||||
/* spare integer (set to 0) */
|
||||
int spare_int1;
|
||||
|
||||
/* global state for plugin */
|
||||
void *glob_context;
|
||||
|
||||
/* name of plugin */
|
||||
char *name;
|
||||
|
||||
/* free global state for plugin */
|
||||
void (*canon_user_free)(void *glob_context, const sasl_utils_t *utils);
|
||||
|
||||
/* canonicalize a username
|
||||
* glob_context -- global context from this structure
|
||||
* sparams -- server params, note user_realm&propctx elements
|
||||
* user -- user to login as (may not be NUL terminated)
|
||||
* len -- length of user name (0 = strlen(user))
|
||||
* flags -- for SASL_CU_* flags
|
||||
* out -- buffer to copy user name
|
||||
* out_max -- max length of user name
|
||||
* out_len -- set to length of user name
|
||||
*
|
||||
* note that the output buffers MAY be the same as the input buffers.
|
||||
*
|
||||
* returns
|
||||
* SASL_OK on success
|
||||
* SASL_BADPROT username contains invalid character
|
||||
*/
|
||||
int (*canon_user_server)(void *glob_context,
|
||||
sasl_server_params_t *sparams,
|
||||
const char *user, unsigned len,
|
||||
unsigned flags,
|
||||
char *out,
|
||||
unsigned out_umax, unsigned *out_ulen);
|
||||
|
||||
int (*canon_user_client)(void *glob_context,
|
||||
sasl_client_params_t *cparams,
|
||||
const char *user, unsigned len,
|
||||
unsigned flags,
|
||||
char *out,
|
||||
unsigned out_max, unsigned *out_len);
|
||||
|
||||
/* for additions which don't require a version upgrade; set to 0 */
|
||||
int (*spare_fptr1)(void);
|
||||
int (*spare_fptr2)(void);
|
||||
int (*spare_fptr3)(void);
|
||||
} sasl_canonuser_plug_t;
|
||||
|
||||
#define SASL_CANONUSER_PLUG_VERSION 5
|
||||
|
||||
/* default name for canonuser plug-in entry point is "sasl_canonuser_init"
|
||||
* similar to sasl_server_plug_init model, except only returns one
|
||||
* sasl_canonuser_plug_t structure;
|
||||
*/
|
||||
typedef int sasl_canonuser_init_t(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_canonuser_plug_t **plug,
|
||||
const char *plugname);
|
||||
|
||||
/* add a canonuser plugin
|
||||
*/
|
||||
LIBSASL_API int sasl_canonuser_add_plugin(const char *plugname,
|
||||
sasl_canonuser_init_t *canonuserfunc);
|
||||
|
||||
/******************************************************
|
||||
* auxiliary property plug-in -- added cjn 1999-09-29 *
|
||||
******************************************************/
|
||||
|
||||
typedef struct sasl_auxprop_plug {
|
||||
/* optional features of plugin (none defined yet, set to 0) */
|
||||
int features;
|
||||
|
||||
/* spare integer, must be set to 0 */
|
||||
int spare_int1;
|
||||
|
||||
/* global state for plugin */
|
||||
void *glob_context;
|
||||
|
||||
/* free global state for plugin (OPTIONAL) */
|
||||
void (*auxprop_free)(void *glob_context, const sasl_utils_t *utils);
|
||||
|
||||
/* fill in fields of an auxiliary property context
|
||||
* last element in array has id of SASL_AUX_END
|
||||
* elements with non-0 len should be ignored.
|
||||
*/
|
||||
int (*auxprop_lookup)(void *glob_context,
|
||||
sasl_server_params_t *sparams,
|
||||
unsigned flags,
|
||||
const char *user, unsigned ulen);
|
||||
|
||||
/* name of the auxprop plugin */
|
||||
char *name;
|
||||
|
||||
/* store the fields/values of an auxiliary property context (OPTIONAL)
|
||||
*
|
||||
* if ctx is NULL, just check if storing properties is enabled
|
||||
*
|
||||
* returns
|
||||
* SASL_OK on success
|
||||
* SASL_FAIL on failure
|
||||
*/
|
||||
int (*auxprop_store)(void *glob_context,
|
||||
sasl_server_params_t *sparams,
|
||||
struct propctx *ctx,
|
||||
const char *user, unsigned ulen);
|
||||
} sasl_auxprop_plug_t;
|
||||
|
||||
/* auxprop lookup flags */
|
||||
#define SASL_AUXPROP_OVERRIDE 0x01 /* if clear, ignore auxiliary properties
|
||||
* with non-zero len field. If set,
|
||||
* override value of those properties */
|
||||
#define SASL_AUXPROP_AUTHZID 0x02 /* if clear, we are looking up the
|
||||
* authid flags (prefixed with *), otherwise
|
||||
* we are looking up the authzid flags
|
||||
* (no prefix) */
|
||||
|
||||
/* NOTE: Keep in sync with SASL_CU_<XXX> flags */
|
||||
#define SASL_AUXPROP_VERIFY_AGAINST_HASH 0x10
|
||||
|
||||
|
||||
#define SASL_AUXPROP_PLUG_VERSION 8
|
||||
|
||||
/* default name for auxprop plug-in entry point is "sasl_auxprop_init"
|
||||
* similar to sasl_server_plug_init model, except only returns one
|
||||
* sasl_auxprop_plug_t structure;
|
||||
*/
|
||||
typedef int sasl_auxprop_init_t(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_auxprop_plug_t **plug,
|
||||
const char *plugname);
|
||||
|
||||
/* add an auxiliary property plug-in
|
||||
*/
|
||||
LIBSASL_API int sasl_auxprop_add_plugin(const char *plugname,
|
||||
sasl_auxprop_init_t *auxpropfunc);
|
||||
|
||||
typedef void auxprop_info_callback_t (sasl_auxprop_plug_t *m,
|
||||
sasl_info_callback_stage_t stage,
|
||||
void *rock);
|
||||
|
||||
/* Dump information about available auxprop plugins (separate functions are
|
||||
used for canon and server authentication plugins) */
|
||||
LIBSASL_API int auxprop_plugin_info (const char *mech_list,
|
||||
auxprop_info_callback_t *info_cb,
|
||||
void *info_cb_rock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SASLPLUG_H */
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/* saslutil.h -- various utility functions in SASL library
|
||||
*/
|
||||
|
||||
#ifndef SASLUTIL_H
|
||||
#define SASLUTIL_H 1
|
||||
|
||||
#ifndef SASL_H
|
||||
#include "sasl.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* base64 decode
|
||||
* in -- input data
|
||||
* inlen -- length of input data
|
||||
* out -- output data (may be same as in, must have enough space)
|
||||
* outmax -- max size of output buffer
|
||||
* result:
|
||||
* outlen -- actual output length
|
||||
*
|
||||
* returns SASL_BADPROT on bad base64,
|
||||
* SASL_BUFOVER if result won't fit
|
||||
* SASL_OK on success
|
||||
*/
|
||||
LIBSASL_API int sasl_decode64(const char *in, unsigned inlen,
|
||||
char *out, unsigned outmax, unsigned *outlen);
|
||||
|
||||
/* base64 encode
|
||||
* in -- input data
|
||||
* inlen -- input data length
|
||||
* out -- output buffer (will be NUL terminated)
|
||||
* outmax -- max size of output buffer
|
||||
* result:
|
||||
* outlen -- gets actual length of output buffer (optional)
|
||||
*
|
||||
* Returns SASL_OK on success, SASL_BUFOVER if result won't fit
|
||||
*/
|
||||
LIBSASL_API int sasl_encode64(const char *in, unsigned inlen,
|
||||
char *out, unsigned outmax, unsigned *outlen);
|
||||
|
||||
/* make a challenge string (NUL terminated)
|
||||
* buf -- buffer for result
|
||||
* maxlen -- max length of result
|
||||
* hostflag -- 0 = don't include hostname, 1 = include hostname
|
||||
* returns final length or 0 if not enough space
|
||||
*/
|
||||
LIBSASL_API int sasl_mkchal(sasl_conn_t *conn, char *buf,
|
||||
unsigned maxlen, unsigned hostflag);
|
||||
|
||||
/* verify a string is valid UTF-8
|
||||
* if len == 0, strlen(str) will be used.
|
||||
* returns SASL_BADPROT on error, SASL_OK on success
|
||||
*/
|
||||
LIBSASL_API int sasl_utf8verify(const char *str, unsigned len);
|
||||
|
||||
/* create random pool seeded with OS-based params */
|
||||
LIBSASL_API int sasl_randcreate(sasl_rand_t **rpool);
|
||||
|
||||
/* free random pool from randcreate */
|
||||
LIBSASL_API void sasl_randfree(sasl_rand_t **rpool);
|
||||
|
||||
/* seed random number generator */
|
||||
LIBSASL_API void sasl_randseed(sasl_rand_t *rpool, const char *seed,
|
||||
unsigned len);
|
||||
|
||||
/* generate random octets */
|
||||
LIBSASL_API void sasl_rand(sasl_rand_t *rpool, char *buf, unsigned len);
|
||||
|
||||
/* churn data into random number generator */
|
||||
LIBSASL_API void sasl_churn(sasl_rand_t *rpool, const char *data,
|
||||
unsigned len);
|
||||
|
||||
/* erase a security sensitive buffer or password.
|
||||
* Implementation may use recovery-resistant erase logic.
|
||||
*/
|
||||
LIBSASL_API void sasl_erasebuffer(char *pass, unsigned len);
|
||||
|
||||
/* Lowercase string in place */
|
||||
LIBSASL_API char *sasl_strlower (char *val);
|
||||
|
||||
LIBSASL_API int sasl_config_init(const char *filename);
|
||||
|
||||
LIBSASL_API void sasl_config_done(void);
|
||||
|
||||
#ifdef WIN32
|
||||
/* Just in case a different DLL defines this as well */
|
||||
#if defined(NEED_GETOPT)
|
||||
LIBSASL_API int getopt(int argc, char **argv, char *optstring);
|
||||
#endif
|
||||
LIBSASL_API char * getpass(const char *prompt);
|
||||
#endif /* WIN32 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SASLUTIL_H */
|
||||
@@ -0,0 +1,104 @@
|
||||
# Makefile.am for the SASL library
|
||||
# Rob Earhart
|
||||
# $Id: Makefile.am,v 1.88 2011/09/05 14:18:10 murch Exp $
|
||||
# Copyright (c) 2000 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# prior written permission. For permission or any other legal
|
||||
# details, please contact
|
||||
# Office of Technology Transfer
|
||||
# Carnegie Mellon University
|
||||
# 5000 Forbes Avenue
|
||||
# Pittsburgh, PA 15213-3890
|
||||
# (412) 268-4387, fax: (412) 268-7395
|
||||
# tech-transfer@andrew.cmu.edu
|
||||
#
|
||||
# 4. Redistributions of any form whatsoever must retain the following
|
||||
# acknowledgment:
|
||||
# "This product includes software developed by Computing Services
|
||||
# at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
#
|
||||
# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
# Library version info - here at the top, for sanity
|
||||
# See <http://www.gnu.org/software/libtool/manual/libtool.html#Versioning>
|
||||
# CURRENT:REVISION:AGE
|
||||
sasl_version = 3:0:0
|
||||
|
||||
INCLUDES=-DLIBSASL_EXPORTS=1 -I$(top_srcdir)/include -I$(top_srcdir)/plugins -I$(top_builddir)/include -I$(top_srcdir)/sasldb
|
||||
|
||||
EXTRA_DIST = windlopen.c staticopen.h NTMakefile
|
||||
EXTRA_LIBRARIES = libsasl2.a
|
||||
noinst_LIBRARIES = @SASL_STATIC_LIBS@
|
||||
libsasl2_a_SOURCES=
|
||||
|
||||
BUILT_SOURCES = $(SASL_STATIC_SRCS)
|
||||
|
||||
common_headers = saslint.h
|
||||
common_sources = auxprop.c canonusr.c checkpw.c client.c common.c config.c external.c md5.c saslutil.c server.c seterror.c dlopen.c ../plugins/plugin_common.c
|
||||
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIB_DOOR= @LIB_DOOR@
|
||||
|
||||
lib_LTLIBRARIES = libsasl2.la
|
||||
|
||||
libsasl2_la_SOURCES = $(common_sources) $(common_headers)
|
||||
libsasl2_la_LDFLAGS = -version-info $(sasl_version)
|
||||
libsasl2_la_DEPENDENCIES = $(LTLIBOBJS)
|
||||
libsasl2_la_LIBADD = $(LTLIBOBJS) $(SASL_DL_LIB) $(LIB_SOCKET) $(LIB_DOOR)
|
||||
|
||||
if MACOSX
|
||||
framedir = /Library/Frameworks/SASL2.framework
|
||||
install-exec-hook:
|
||||
$(mkinstalldirs) $(framedir)/Versions/A
|
||||
ln -fs $(libdir)/libsasl2.dylib $(framedir)/Versions/A/SASL2
|
||||
cd $(framedir) ; ln -fs Versions/A/SASL2 .
|
||||
else
|
||||
install-exec-hook:
|
||||
endif
|
||||
|
||||
libsasl2.a: libsasl2.la $(SASL_STATIC_OBJS)
|
||||
@echo adding static plugins and dependencies
|
||||
$(AR) cru .libs/$@ $(SASL_STATIC_OBJS)
|
||||
@for i in ./libsasl2.la ../sasldb/libsasldb.la ../plugins/lib*.la; do \
|
||||
if test ! -f $$i; then continue; fi; . $$i; \
|
||||
for j in $$dependency_libs foo; do \
|
||||
case $$j in foo) ;; \
|
||||
-L*) for k in $$depdirs foo; do \
|
||||
if test $$k = $$j; then break; fi; done; \
|
||||
if test $$k = foo; then depdirs="$$depdirs $$j"; fi ;; \
|
||||
-l*) for k in $$deplibs foo; do \
|
||||
if test $$k = $$j; then break; fi; done; \
|
||||
if test $$k = foo; then deplibs="$$deplibs $$j"; fi ;; \
|
||||
esac; done; dependency_libs=""; done; \
|
||||
sed -e "/^dependency_libs=/s%=.*%='$${depdirs}$${deplibs}'%" \
|
||||
libsasl2.la >TMP.$$ && mv TMP.$$ libsasl2.la
|
||||
rm -f $@
|
||||
ln -s .libs/$@ $@
|
||||
|
||||
$(SASL_STATIC_SRCS): linksrcs
|
||||
|
||||
linksrcs:
|
||||
-ln -s $(SASL_STATIC_SRCS) .
|
||||
|
||||
@@ -0,0 +1,705 @@
|
||||
# Makefile.in generated by automake 1.11 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# Makefile.am for the SASL library
|
||||
# Rob Earhart
|
||||
# $Id: Makefile.am,v 1.88 2011/09/05 14:18:10 murch Exp $
|
||||
# Copyright (c) 2000 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# prior written permission. For permission or any other legal
|
||||
# details, please contact
|
||||
# Office of Technology Transfer
|
||||
# Carnegie Mellon University
|
||||
# 5000 Forbes Avenue
|
||||
# Pittsburgh, PA 15213-3890
|
||||
# (412) 268-4387, fax: (412) 268-7395
|
||||
# tech-transfer@andrew.cmu.edu
|
||||
#
|
||||
# 4. Redistributions of any form whatsoever must retain the following
|
||||
# acknowledgment:
|
||||
# "This product includes software developed by Computing Services
|
||||
# at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
#
|
||||
# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
subdir = lib
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
|
||||
getaddrinfo.c getnameinfo.c getsubopt.c snprintf.c
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/config/kerberos_v4.m4 \
|
||||
$(top_srcdir)/config/libtool.m4 $(top_srcdir)/config/plain.m4 \
|
||||
$(top_srcdir)/config/sasldb.m4 \
|
||||
$(top_srcdir)/cmulocal/berkdb.m4 \
|
||||
$(top_srcdir)/cmulocal/bsd_sockets.m4 \
|
||||
$(top_srcdir)/cmulocal/c-attribute.m4 \
|
||||
$(top_srcdir)/cmulocal/common.m4 \
|
||||
$(top_srcdir)/cmulocal/cyrus.m4 \
|
||||
$(top_srcdir)/cmulocal/init_automake.m4 \
|
||||
$(top_srcdir)/cmulocal/ipv6.m4 \
|
||||
$(top_srcdir)/cmulocal/openldap.m4 \
|
||||
$(top_srcdir)/cmulocal/openssl.m4 \
|
||||
$(top_srcdir)/cmulocal/sasl2.m4 $(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
LIBRARIES = $(noinst_LIBRARIES)
|
||||
AR = ar
|
||||
ARFLAGS = cru
|
||||
libsasl2_a_AR = $(AR) $(ARFLAGS)
|
||||
libsasl2_a_LIBADD =
|
||||
am_libsasl2_a_OBJECTS =
|
||||
libsasl2_a_OBJECTS = $(am_libsasl2_a_OBJECTS)
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__installdirs = "$(DESTDIR)$(libdir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
am__DEPENDENCIES_1 =
|
||||
am__objects_1 = auxprop.lo canonusr.lo checkpw.lo client.lo common.lo \
|
||||
config.lo external.lo md5.lo saslutil.lo server.lo seterror.lo \
|
||||
dlopen.lo plugin_common.lo
|
||||
am__objects_2 =
|
||||
am_libsasl2_la_OBJECTS = $(am__objects_1) $(am__objects_2)
|
||||
libsasl2_la_OBJECTS = $(am_libsasl2_la_OBJECTS)
|
||||
libsasl2_la_LINK = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(libsasl2_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
|
||||
$(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(libsasl2_a_SOURCES) $(libsasl2_la_SOURCES)
|
||||
DIST_SOURCES = $(libsasl2_a_SOURCES) $(libsasl2_la_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DIRS = @DIRS@
|
||||
DMALLOC_LIBS = @DMALLOC_LIBS@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
GETADDRINFOOBJS = @GETADDRINFOOBJS@
|
||||
GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
|
||||
GETSUBOPT = @GETSUBOPT@
|
||||
GREP = @GREP@
|
||||
GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
|
||||
GSSAPI_LIBS = @GSSAPI_LIBS@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
IPCTYPE = @IPCTYPE@
|
||||
JAVAC = @JAVAC@
|
||||
JAVADOC = @JAVADOC@
|
||||
JAVAH = @JAVAH@
|
||||
JAVAROOT = @JAVAROOT@
|
||||
JAVA_INCLUDES = @JAVA_INCLUDES@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIB_CRYPT = @LIB_CRYPT@
|
||||
LIB_DES = @LIB_DES@
|
||||
LIB_DOOR = @LIB_DOOR@
|
||||
LIB_LDAP = @LIB_LDAP@
|
||||
LIB_MYSQL = @LIB_MYSQL@
|
||||
LIB_PGSQL = @LIB_PGSQL@
|
||||
LIB_SOCKET = @LIB_SOCKET@
|
||||
LIB_SQLITE = @LIB_SQLITE@
|
||||
LIB_SQLITE3 = @LIB_SQLITE3@
|
||||
LN_S = @LN_S@
|
||||
LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
|
||||
LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NTLM_LIBS = @NTLM_LIBS@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTP_LIBS = @OTP_LIBS@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PASSDSS_LIBS = @PASSDSS_LIBS@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PLAIN_LIBS = @PLAIN_LIBS@
|
||||
PURECOV = @PURECOV@
|
||||
PURIFY = @PURIFY@
|
||||
PWCHECKMETH = @PWCHECKMETH@
|
||||
RANLIB = @RANLIB@
|
||||
SASL_DB_BACKEND = @SASL_DB_BACKEND@
|
||||
SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
|
||||
SASL_DB_INC = @SASL_DB_INC@
|
||||
SASL_DB_LIB = @SASL_DB_LIB@
|
||||
SASL_DB_MANS = @SASL_DB_MANS@
|
||||
SASL_DB_UTILS = @SASL_DB_UTILS@
|
||||
SASL_DL_LIB = @SASL_DL_LIB@
|
||||
SASL_KRB_LIB = @SASL_KRB_LIB@
|
||||
SASL_MECHS = @SASL_MECHS@
|
||||
SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
|
||||
SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
|
||||
SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
|
||||
SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
|
||||
SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
|
||||
SCRAM_LIBS = @SCRAM_LIBS@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
|
||||
SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
|
||||
SHELL = @SHELL@
|
||||
SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
|
||||
SNPRINTFOBJS = @SNPRINTFOBJS@
|
||||
SRP_LIBS = @SRP_LIBS@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
configdir = @configdir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
plugindir = @plugindir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
subdirs = @subdirs@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
# Library version info - here at the top, for sanity
|
||||
# See <http://www.gnu.org/software/libtool/manual/libtool.html#Versioning>
|
||||
# CURRENT:REVISION:AGE
|
||||
sasl_version = 3:0:0
|
||||
INCLUDES = -DLIBSASL_EXPORTS=1 -I$(top_srcdir)/include -I$(top_srcdir)/plugins -I$(top_builddir)/include -I$(top_srcdir)/sasldb
|
||||
EXTRA_DIST = windlopen.c staticopen.h NTMakefile
|
||||
EXTRA_LIBRARIES = libsasl2.a
|
||||
noinst_LIBRARIES = @SASL_STATIC_LIBS@
|
||||
libsasl2_a_SOURCES =
|
||||
BUILT_SOURCES = $(SASL_STATIC_SRCS)
|
||||
common_headers = saslint.h
|
||||
common_sources = auxprop.c canonusr.c checkpw.c client.c common.c config.c external.c md5.c saslutil.c server.c seterror.c dlopen.c ../plugins/plugin_common.c
|
||||
lib_LTLIBRARIES = libsasl2.la
|
||||
libsasl2_la_SOURCES = $(common_sources) $(common_headers)
|
||||
libsasl2_la_LDFLAGS = -version-info $(sasl_version)
|
||||
libsasl2_la_DEPENDENCIES = $(LTLIBOBJS)
|
||||
libsasl2_la_LIBADD = $(LTLIBOBJS) $(SASL_DL_LIB) $(LIB_SOCKET) $(LIB_DOOR)
|
||||
@MACOSX_TRUE@framedir = /Library/Frameworks/SASL2.framework
|
||||
all: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu lib/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
clean-noinstLIBRARIES:
|
||||
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
list2=; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
list2="$$list2 $$p"; \
|
||||
else :; fi; \
|
||||
done; \
|
||||
test -z "$$list2" || { \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
|
||||
}
|
||||
|
||||
uninstall-libLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-libLTLIBRARIES:
|
||||
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" != "$$p" || dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
libsasl2.la: $(libsasl2_la_OBJECTS) $(libsasl2_la_DEPENDENCIES)
|
||||
$(libsasl2_la_LINK) -rpath $(libdir) $(libsasl2_la_OBJECTS) $(libsasl2_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getaddrinfo.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getnameinfo.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getsubopt.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/snprintf.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auxprop.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/canonusr.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checkpw.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dlopen.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/external.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_common.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/saslutil.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seterror.Plo@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
plugin_common.lo: ../plugins/plugin_common.c
|
||||
@am__fastdepCC_TRUE@ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plugin_common.lo -MD -MP -MF $(DEPDIR)/plugin_common.Tpo -c -o plugin_common.lo `test -f '../plugins/plugin_common.c' || echo '$(srcdir)/'`../plugins/plugin_common.c
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/plugin_common.Tpo $(DEPDIR)/plugin_common.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='../plugins/plugin_common.c' object='plugin_common.lo' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o plugin_common.lo `test -f '../plugins/plugin_common.c' || echo '$(srcdir)/'`../plugins/plugin_common.c
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) check-am
|
||||
all-am: Makefile $(LIBRARIES) $(LTLIBRARIES)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(libdir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||
clean-noinstLIBRARIES mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf $(DEPDIR) ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am: install-libLTLIBRARIES
|
||||
@$(NORMAL_INSTALL)
|
||||
$(MAKE) $(AM_MAKEFLAGS) install-exec-hook
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf $(DEPDIR) ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-libLTLIBRARIES
|
||||
|
||||
.MAKE: all check install install-am install-exec-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-libLTLIBRARIES clean-libtool clean-noinstLIBRARIES ctags \
|
||||
distclean distclean-compile distclean-generic \
|
||||
distclean-libtool distclean-tags distdir dvi dvi-am html \
|
||||
html-am info info-am install install-am install-data \
|
||||
install-data-am install-dvi install-dvi-am install-exec \
|
||||
install-exec-am install-exec-hook install-html install-html-am \
|
||||
install-info install-info-am install-libLTLIBRARIES \
|
||||
install-man install-pdf install-pdf-am install-ps \
|
||||
install-ps-am install-strip installcheck installcheck-am \
|
||||
installdirs maintainer-clean maintainer-clean-generic \
|
||||
mostlyclean mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
|
||||
uninstall-am uninstall-libLTLIBRARIES
|
||||
|
||||
@MACOSX_TRUE@install-exec-hook:
|
||||
@MACOSX_TRUE@ $(mkinstalldirs) $(framedir)/Versions/A
|
||||
@MACOSX_TRUE@ ln -fs $(libdir)/libsasl2.dylib $(framedir)/Versions/A/SASL2
|
||||
@MACOSX_TRUE@ cd $(framedir) ; ln -fs Versions/A/SASL2 .
|
||||
@MACOSX_FALSE@install-exec-hook:
|
||||
|
||||
libsasl2.a: libsasl2.la $(SASL_STATIC_OBJS)
|
||||
@echo adding static plugins and dependencies
|
||||
$(AR) cru .libs/$@ $(SASL_STATIC_OBJS)
|
||||
@for i in ./libsasl2.la ../sasldb/libsasldb.la ../plugins/lib*.la; do \
|
||||
if test ! -f $$i; then continue; fi; . $$i; \
|
||||
for j in $$dependency_libs foo; do \
|
||||
case $$j in foo) ;; \
|
||||
-L*) for k in $$depdirs foo; do \
|
||||
if test $$k = $$j; then break; fi; done; \
|
||||
if test $$k = foo; then depdirs="$$depdirs $$j"; fi ;; \
|
||||
-l*) for k in $$deplibs foo; do \
|
||||
if test $$k = $$j; then break; fi; done; \
|
||||
if test $$k = foo; then deplibs="$$deplibs $$j"; fi ;; \
|
||||
esac; done; dependency_libs=""; done; \
|
||||
sed -e "/^dependency_libs=/s%=.*%='$${depdirs}$${deplibs}'%" \
|
||||
libsasl2.la >TMP.$$ && mv TMP.$$ libsasl2.la
|
||||
rm -f $@
|
||||
ln -s .libs/$@ $@
|
||||
|
||||
$(SASL_STATIC_SRCS): linksrcs
|
||||
|
||||
linksrcs:
|
||||
-ln -s $(SASL_STATIC_SRCS) .
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
Executable
+128
@@ -0,0 +1,128 @@
|
||||
!INCLUDE ..\win32\common.mak
|
||||
|
||||
# WS2tcpip.h included in Visual Studio 7 provides getaddrinfo, ...
|
||||
# emulation on Windows, so there is no need to build getaddrinfo.c
|
||||
|
||||
!IF "$(VCVER)" == "6"
|
||||
compat_sources = getaddrinfo.c getnameinfo.c
|
||||
compat_objs = getaddrinfo.obj getnameinfo.obj
|
||||
!ENDIF
|
||||
|
||||
|
||||
libsasl_sources = auxprop.c canonusr.c checkpw.c client.c common.c config.c external.c md5.c saslutil.c server.c seterror.c windlopen.c getsubopt.c plugin_common.c plugin_common.h $(compat_sources)
|
||||
libsasl_objs = auxprop.obj canonusr.obj checkpw.obj client.obj common.obj config.obj external.obj md5.obj saslutil.obj server.obj seterror.obj windlopen.obj getsubopt.obj plugin_common.obj $(compat_objs)
|
||||
libsasl_res = libsasl.res
|
||||
libsasl_out = libsasl.dll libsasl.exp libsasl.lib $(libsasl_res)
|
||||
|
||||
CPPFLAGS = /wd4996 /Wp64 /D NEED_GETOPT /I "..\win32\include" /I "." /I "..\include" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBSASL_EXPORTS"
|
||||
|
||||
!IF $(TARGET_WIN_SYSTEM) >= 51
|
||||
CPPFLAGS = /D TARGET_WIN_SYSTEM=$(TARGET_WIN_SYSTEM) $(CPPFLAGS)
|
||||
!ENDIF
|
||||
|
||||
all_objs = $(libsasl_objs)
|
||||
all_out = $(libsasl_out)
|
||||
|
||||
libdir = $(prefix)\lib
|
||||
bindir = $(prefix)\bin
|
||||
exclude_list = binexclude.lst
|
||||
|
||||
all: all-recursive
|
||||
|
||||
#
|
||||
# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels
|
||||
#
|
||||
# In order to force xcopy not to confirm if the second parameter is file or directory,
|
||||
# the first parameter has to contain a wildcard character. For example, we use libsasl.l*,
|
||||
# instead of libsasl.lib. Ugly, but works!
|
||||
#
|
||||
install: libsasl.dll
|
||||
@echo libsasl.exp > $(exclude_list)
|
||||
@echo libsasl.res >> $(exclude_list)
|
||||
@echo libsasl.dll.manifest >> $(exclude_list)
|
||||
# .lib is excluded only because it is copied separately below
|
||||
@echo libsasl.lib >> $(exclude_list)
|
||||
@xcopy libsasl.* $(bindir) /I /F /Y /EXCLUDE:$(exclude_list)
|
||||
@xcopy libsasl.l* $(libdir) /I /F /Y
|
||||
|
||||
all-recursive: libsasl.dll
|
||||
|
||||
libsasl.dll: $(libsasl_objs) $(libsasl_res)
|
||||
$(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"libsasl.dll" /implib:"libsasl.lib" /pdb:"libsasl.pdb" $(libsasl_objs) $(libsasl_res)
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
plugin_common.c: ..\plugins\plugin_common.c plugin_common.h
|
||||
xcopy /D /Y ..\plugins\plugin_common.c .
|
||||
|
||||
plugin_common.h: ..\plugins\plugin_common.h
|
||||
xcopy /D /Y ..\plugins\plugin_common.h .
|
||||
|
||||
auxprop.obj checkpw.obj client.obj common.obj external.obj plugin_common.obj server.obj seterror.obj: ..\include\saslplug.h
|
||||
|
||||
auxprop.obj canonusr.obj checkpw.obj client.obj common.obj config.obj external.obj getsubopt.obj md5.obj plugin_common.obj server.obj seterror.obj windlopen.obj: ..\include\sasl.h ..\include\prop.h
|
||||
|
||||
auxprop.obj canonusr.obj checkpw.obj client.obj common.obj config.obj dlopen.obj external.obj saslutil.obj server.obj seterror.obj windlopen.obj: saslint.h
|
||||
|
||||
CLEAN :
|
||||
-@erase $(all_objs)
|
||||
-@erase "*.idb"
|
||||
-@erase "*.pdb"
|
||||
-@erase "*.manifest"
|
||||
-@erase $(all_out)
|
||||
-@erase plugin_common.h
|
||||
-@erase plugin_common.c
|
||||
-@erase $(exclude_list)
|
||||
|
||||
$(libsasl_res): NTMakefile
|
||||
rc /fo"$(libsasl_res)" <<
|
||||
#include "windows.h"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION $(SASL_VERSION_MAJOR),$(SASL_VERSION_MINOR),$(SASL_VERSION_STEP),0
|
||||
PRODUCTVERSION $(SASL_VERSION_MAJOR),$(SASL_VERSION_MINOR),$(SASL_VERSION_STEP),0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Carnegie Mellon University\0"
|
||||
VALUE "FileDescription", "CMU SASL API v2\0"
|
||||
VALUE "FileVersion", "$(SASL_VERSION_MAJOR).$(SASL_VERSION_MINOR).$(SASL_VERSION_STEP).0\0"
|
||||
VALUE "InternalName", "libsasl\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) Carnegie Mellon University 2002-2012\0"
|
||||
VALUE "OriginalFilename", "libsasl.dll\0"
|
||||
VALUE "ProductName", "Carnegie Mellon University SASL\0"
|
||||
VALUE "ProductVersion", "$(SASL_VERSION_MAJOR).$(SASL_VERSION_MINOR).$(SASL_VERSION_STEP)-0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
<<
|
||||
|
||||
.c.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,462 @@
|
||||
/* canonusr.c - user canonicalization support
|
||||
* Rob Siemborski
|
||||
* $Id: canonusr.c,v 1.22 2011/09/01 16:33:42 mel Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <sasl.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <prop.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "saslint.h"
|
||||
|
||||
typedef struct canonuser_plug_list
|
||||
{
|
||||
struct canonuser_plug_list *next;
|
||||
char name[PATH_MAX];
|
||||
const sasl_canonuser_plug_t *plug;
|
||||
} canonuser_plug_list_t;
|
||||
|
||||
static canonuser_plug_list_t *canonuser_head = NULL;
|
||||
|
||||
/* default behavior:
|
||||
* eliminate leading & trailing whitespace,
|
||||
* null-terminate, and get into the outparams
|
||||
* (handled by INTERNAL plugin) */
|
||||
/* a zero ulen or alen indicates that it is strlen(value) */
|
||||
int _sasl_canon_user(sasl_conn_t *conn,
|
||||
const char *user, unsigned ulen,
|
||||
unsigned flags,
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
canonuser_plug_list_t *ptr;
|
||||
sasl_server_conn_t *sconn = NULL;
|
||||
sasl_client_conn_t *cconn = NULL;
|
||||
sasl_canon_user_t *cuser_cb;
|
||||
sasl_getopt_t *getopt;
|
||||
void *context;
|
||||
int result;
|
||||
const char *plugin_name = NULL;
|
||||
char *user_buf;
|
||||
unsigned *lenp;
|
||||
|
||||
if(!conn) return SASL_BADPARAM;
|
||||
if(!user || !oparams) return SASL_BADPARAM;
|
||||
|
||||
if(flags & SASL_CU_AUTHID) {
|
||||
user_buf = conn->authid_buf;
|
||||
lenp = &(oparams->alen);
|
||||
} else if (flags & SASL_CU_AUTHZID) {
|
||||
user_buf = conn->user_buf;
|
||||
lenp = &(oparams->ulen);
|
||||
} else {
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
if(conn->type == SASL_CONN_SERVER) sconn = (sasl_server_conn_t *)conn;
|
||||
else if(conn->type == SASL_CONN_CLIENT) cconn = (sasl_client_conn_t *)conn;
|
||||
else return SASL_FAIL;
|
||||
|
||||
if(!ulen) ulen = (unsigned int)strlen(user);
|
||||
|
||||
/* check to see if we have a callback to make*/
|
||||
result = _sasl_getcallback(conn,
|
||||
SASL_CB_CANON_USER,
|
||||
(sasl_callback_ft *)&cuser_cb,
|
||||
&context);
|
||||
if(result == SASL_OK && cuser_cb) {
|
||||
result = cuser_cb(conn,
|
||||
context,
|
||||
user,
|
||||
ulen,
|
||||
flags,
|
||||
(conn->type == SASL_CONN_SERVER ?
|
||||
sconn->user_realm :
|
||||
NULL),
|
||||
user_buf,
|
||||
CANON_BUF_SIZE,
|
||||
lenp);
|
||||
|
||||
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
/* Point the input copy at the stored buffer */
|
||||
user = user_buf;
|
||||
ulen = *lenp;
|
||||
}
|
||||
|
||||
/* which plugin are we supposed to use? */
|
||||
result = _sasl_getcallback(conn,
|
||||
SASL_CB_GETOPT,
|
||||
(sasl_callback_ft *)&getopt,
|
||||
&context);
|
||||
if (result == SASL_OK && getopt) {
|
||||
getopt(context, NULL, "canon_user_plugin", &plugin_name, NULL);
|
||||
}
|
||||
|
||||
if (!plugin_name) {
|
||||
/* Use Default */
|
||||
plugin_name = "INTERNAL";
|
||||
}
|
||||
|
||||
for (ptr = canonuser_head; ptr; ptr = ptr->next) {
|
||||
/* A match is if we match the internal name of the plugin, or if
|
||||
* we match the filename (old-style) */
|
||||
if ((ptr->plug->name && !strcmp(plugin_name, ptr->plug->name))
|
||||
|| !strcmp(plugin_name, ptr->name)) break;
|
||||
}
|
||||
|
||||
/* We clearly don't have this one! */
|
||||
if (!ptr) {
|
||||
sasl_seterror(conn, 0, "desired canon_user plugin %s not found",
|
||||
plugin_name);
|
||||
return SASL_NOMECH;
|
||||
}
|
||||
|
||||
if (sconn) {
|
||||
/* we're a server */
|
||||
result = ptr->plug->canon_user_server(ptr->plug->glob_context,
|
||||
sconn->sparams,
|
||||
user, ulen,
|
||||
flags,
|
||||
user_buf,
|
||||
CANON_BUF_SIZE, lenp);
|
||||
} else {
|
||||
/* we're a client */
|
||||
result = ptr->plug->canon_user_client(ptr->plug->glob_context,
|
||||
cconn->cparams,
|
||||
user, ulen,
|
||||
flags,
|
||||
user_buf,
|
||||
CANON_BUF_SIZE, lenp);
|
||||
}
|
||||
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
if ((flags & SASL_CU_AUTHID) && (flags & SASL_CU_AUTHZID)) {
|
||||
/* We did both, so we need to copy the result into
|
||||
* the buffer for the authzid from the buffer for the authid */
|
||||
memcpy(conn->user_buf, conn->authid_buf, CANON_BUF_SIZE);
|
||||
oparams->ulen = oparams->alen;
|
||||
}
|
||||
|
||||
/* Set the appropriate oparams (lengths have already been set by lenp) */
|
||||
if (flags & SASL_CU_AUTHID) {
|
||||
oparams->authid = conn->authid_buf;
|
||||
}
|
||||
|
||||
if (flags & SASL_CU_AUTHZID) {
|
||||
oparams->user = conn->user_buf;
|
||||
}
|
||||
|
||||
RETURN(conn, result);
|
||||
}
|
||||
|
||||
/* Lookup all properties for authentication and/or authorization identity. */
|
||||
static int _sasl_auxprop_lookup_user_props (sasl_conn_t *conn,
|
||||
unsigned flags,
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
sasl_server_conn_t *sconn = NULL;
|
||||
int result = SASL_OK;
|
||||
|
||||
if (!conn) return SASL_BADPARAM;
|
||||
if (!oparams) return SASL_BADPARAM;
|
||||
|
||||
#ifndef macintosh
|
||||
if (conn->type == SASL_CONN_SERVER) sconn = (sasl_server_conn_t *)conn;
|
||||
|
||||
/* do auxprop lookups (server only) */
|
||||
if (sconn) {
|
||||
int authz_result;
|
||||
unsigned auxprop_lookup_flags = flags & SASL_CU_ASIS_MASK;
|
||||
|
||||
if (flags & SASL_CU_OVERRIDE) {
|
||||
auxprop_lookup_flags |= SASL_AUXPROP_OVERRIDE;
|
||||
}
|
||||
|
||||
if (flags & SASL_CU_AUTHID) {
|
||||
result = _sasl_auxprop_lookup(sconn->sparams,
|
||||
auxprop_lookup_flags,
|
||||
oparams->authid,
|
||||
oparams->alen);
|
||||
} else {
|
||||
result = SASL_CONTINUE;
|
||||
}
|
||||
if (flags & SASL_CU_AUTHZID) {
|
||||
authz_result = _sasl_auxprop_lookup(sconn->sparams,
|
||||
auxprop_lookup_flags | SASL_AUXPROP_AUTHZID,
|
||||
oparams->user,
|
||||
oparams->ulen);
|
||||
|
||||
if (result == SASL_CONTINUE) {
|
||||
/* Only SASL_CU_AUTHZID was requested.
|
||||
The authz_result value is authoritative. */
|
||||
result = authz_result;
|
||||
} else if (result == SASL_OK && authz_result != SASL_NOUSER) {
|
||||
/* Use the authz_result value, unless "result"
|
||||
already contains an error */
|
||||
result = authz_result;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & SASL_CU_EXTERNALLY_VERIFIED) && (result == SASL_NOUSER || result == SASL_NOMECH)) {
|
||||
/* The called has explicitly told us that the authentication identity
|
||||
was already verified or will be verified independently.
|
||||
So a failure to retrieve any associated properties
|
||||
is not an error. For example the caller is using Kerberos to verify user,
|
||||
but the LDAPDB/SASLDB auxprop plugin doesn't contain any auxprops for
|
||||
the user.
|
||||
Another case is PLAIN/LOGIN not using auxprop to verify user passwords. */
|
||||
result = SASL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
RETURN(conn, result);
|
||||
}
|
||||
|
||||
/* default behavior:
|
||||
* Eliminate leading & trailing whitespace,
|
||||
* null-terminate, and get into the outparams
|
||||
* (handled by INTERNAL plugin).
|
||||
*
|
||||
* Server only: Also does auxprop lookups once username
|
||||
* is canonicalized. */
|
||||
int _sasl_canon_user_lookup (sasl_conn_t *conn,
|
||||
const char *user,
|
||||
unsigned ulen,
|
||||
unsigned flags,
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = _sasl_canon_user (conn,
|
||||
user,
|
||||
ulen,
|
||||
flags,
|
||||
oparams);
|
||||
if (result == SASL_OK) {
|
||||
result = _sasl_auxprop_lookup_user_props (conn,
|
||||
flags,
|
||||
oparams);
|
||||
}
|
||||
|
||||
RETURN(conn, result);
|
||||
}
|
||||
|
||||
void _sasl_canonuser_free()
|
||||
{
|
||||
canonuser_plug_list_t *ptr, *ptr_next;
|
||||
|
||||
for(ptr = canonuser_head; ptr; ptr = ptr_next) {
|
||||
ptr_next = ptr->next;
|
||||
if(ptr->plug->canon_user_free)
|
||||
ptr->plug->canon_user_free(ptr->plug->glob_context,
|
||||
sasl_global_utils);
|
||||
sasl_FREE(ptr);
|
||||
}
|
||||
|
||||
canonuser_head = NULL;
|
||||
}
|
||||
|
||||
int sasl_canonuser_add_plugin(const char *plugname,
|
||||
sasl_canonuser_init_t *canonuserfunc)
|
||||
{
|
||||
int result, out_version;
|
||||
canonuser_plug_list_t *new_item;
|
||||
sasl_canonuser_plug_t *plug;
|
||||
|
||||
if(!plugname || strlen(plugname) > (PATH_MAX - 1)) {
|
||||
sasl_seterror(NULL, 0,
|
||||
"bad plugname passed to sasl_canonuser_add_plugin\n");
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
result = canonuserfunc(sasl_global_utils, SASL_CANONUSER_PLUG_VERSION,
|
||||
&out_version, &plug, plugname);
|
||||
|
||||
if(result != SASL_OK) {
|
||||
_sasl_log(NULL, SASL_LOG_ERR, "%s_canonuser_plug_init() failed in sasl_canonuser_add_plugin(): %z\n",
|
||||
plugname, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!plug->canon_user_server && !plug->canon_user_client) {
|
||||
/* We need at least one of these implemented */
|
||||
_sasl_log(NULL, SASL_LOG_ERR,
|
||||
"canonuser plugin '%s' without either client or server side", plugname);
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
new_item = sasl_ALLOC(sizeof(canonuser_plug_list_t));
|
||||
if(!new_item) return SASL_NOMEM;
|
||||
|
||||
strncpy(new_item->name, plugname, PATH_MAX);
|
||||
|
||||
new_item->plug = plug;
|
||||
new_item->next = canonuser_head;
|
||||
canonuser_head = new_item;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
#ifdef MIN
|
||||
#undef MIN
|
||||
#endif
|
||||
#define MIN(a,b) (((a) < (b))? (a):(b))
|
||||
|
||||
static int _canonuser_internal(const sasl_utils_t *utils,
|
||||
const char *user, unsigned ulen,
|
||||
unsigned flags __attribute__((unused)),
|
||||
char *out_user,
|
||||
unsigned out_umax, unsigned *out_ulen)
|
||||
{
|
||||
unsigned i;
|
||||
char *in_buf, *userin;
|
||||
const char *begin_u;
|
||||
unsigned u_apprealm = 0;
|
||||
sasl_server_conn_t *sconn = NULL;
|
||||
|
||||
if(!utils || !user) return SASL_BADPARAM;
|
||||
|
||||
in_buf = sasl_ALLOC((ulen + 2) * sizeof(char));
|
||||
if(!in_buf) return SASL_NOMEM;
|
||||
|
||||
userin = in_buf;
|
||||
|
||||
memcpy(userin, user, ulen);
|
||||
userin[ulen] = '\0';
|
||||
|
||||
/* Strip User ID */
|
||||
for(i=0;isspace((int)userin[i]) && i<ulen;i++);
|
||||
begin_u = &(userin[i]);
|
||||
if(i>0) ulen -= i;
|
||||
|
||||
for(;ulen > 0 && isspace((int)begin_u[ulen-1]); ulen--);
|
||||
if(begin_u == &(userin[ulen])) {
|
||||
sasl_FREE(in_buf);
|
||||
utils->seterror(utils->conn, 0, "All-whitespace username.");
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
if(utils->conn && utils->conn->type == SASL_CONN_SERVER)
|
||||
sconn = (sasl_server_conn_t *)utils->conn;
|
||||
|
||||
/* Need to append realm if necessary (see sasl.h) */
|
||||
if(sconn && sconn->user_realm && !strchr(user, '@')) {
|
||||
u_apprealm = (unsigned) strlen(sconn->user_realm) + 1;
|
||||
}
|
||||
|
||||
/* Now Copy */
|
||||
memcpy(out_user, begin_u, MIN(ulen, out_umax));
|
||||
if(sconn && u_apprealm) {
|
||||
if(ulen >= out_umax) return SASL_BUFOVER;
|
||||
out_user[ulen] = '@';
|
||||
memcpy(&(out_user[ulen+1]), sconn->user_realm,
|
||||
MIN(u_apprealm-1, out_umax-ulen-1));
|
||||
}
|
||||
out_user[MIN(ulen + u_apprealm,out_umax)] = '\0';
|
||||
|
||||
if(ulen + u_apprealm > out_umax) return SASL_BUFOVER;
|
||||
|
||||
if(out_ulen) *out_ulen = MIN(ulen + u_apprealm,out_umax);
|
||||
|
||||
sasl_FREE(in_buf);
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static int _cu_internal_server(void *glob_context __attribute__((unused)),
|
||||
sasl_server_params_t *sparams,
|
||||
const char *user, unsigned ulen,
|
||||
unsigned flags,
|
||||
char *out_user,
|
||||
unsigned out_umax, unsigned *out_ulen)
|
||||
{
|
||||
return _canonuser_internal(sparams->utils,
|
||||
user, ulen,
|
||||
flags, out_user, out_umax, out_ulen);
|
||||
}
|
||||
|
||||
static int _cu_internal_client(void *glob_context __attribute__((unused)),
|
||||
sasl_client_params_t *cparams,
|
||||
const char *user, unsigned ulen,
|
||||
unsigned flags,
|
||||
char *out_user,
|
||||
unsigned out_umax, unsigned *out_ulen)
|
||||
{
|
||||
return _canonuser_internal(cparams->utils,
|
||||
user, ulen,
|
||||
flags, out_user, out_umax, out_ulen);
|
||||
}
|
||||
|
||||
static sasl_canonuser_plug_t canonuser_internal_plugin = {
|
||||
0, /* features */
|
||||
0, /* spare */
|
||||
NULL, /* glob_context */
|
||||
"INTERNAL", /* name */
|
||||
NULL, /* canon_user_free */
|
||||
_cu_internal_server,
|
||||
_cu_internal_client,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
int internal_canonuser_init(const sasl_utils_t *utils __attribute__((unused)),
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_canonuser_plug_t **plug,
|
||||
const char *plugname __attribute__((unused)))
|
||||
{
|
||||
if(!out_version || !plug) return SASL_BADPARAM;
|
||||
|
||||
if(max_version < SASL_CANONUSER_PLUG_VERSION) return SASL_BADVERS;
|
||||
|
||||
*out_version = SASL_CANONUSER_PLUG_VERSION;
|
||||
|
||||
*plug = &canonuser_internal_plugin;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,168 @@
|
||||
/* SASL Config file API
|
||||
* Rob Siemborski
|
||||
* Tim Martin (originally in Cyrus distribution)
|
||||
* $Id: config.c,v 1.19 2011/11/08 17:22:40 murch Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2009 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "sasl.h"
|
||||
#include "saslint.h"
|
||||
|
||||
struct configlist {
|
||||
char *key;
|
||||
char *value;
|
||||
};
|
||||
|
||||
static struct configlist *configlist = NULL;
|
||||
static int nconfiglist = 0;
|
||||
|
||||
#define CONFIGLISTGROWSIZE 100
|
||||
|
||||
int sasl_config_init(const char *filename)
|
||||
{
|
||||
FILE *infile;
|
||||
int lineno = 0;
|
||||
int alloced = 0;
|
||||
char buf[4096];
|
||||
char *p, *key;
|
||||
char *tail;
|
||||
int result;
|
||||
|
||||
nconfiglist=0;
|
||||
|
||||
infile = fopen(filename, "r");
|
||||
if (!infile) {
|
||||
return SASL_CONTINUE;
|
||||
}
|
||||
|
||||
while (fgets(buf, sizeof(buf), infile)) {
|
||||
lineno++;
|
||||
|
||||
if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0';
|
||||
for (p = buf; *p && isspace((int) *p); p++);
|
||||
if (!*p || *p == '#') continue;
|
||||
|
||||
key = p;
|
||||
while (*p && (isalnum((int) *p) || *p == '-' || *p == '_')) {
|
||||
if (isupper((int) *p)) *p = (char) tolower(*p);
|
||||
p++;
|
||||
}
|
||||
if (*p != ':') {
|
||||
fclose(infile);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
*p++ = '\0';
|
||||
|
||||
while (*p && isspace((int) *p)) p++;
|
||||
|
||||
if (!*p) {
|
||||
fclose(infile);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
/* Now strip trailing spaces, if any */
|
||||
tail = p + strlen(p) - 1;
|
||||
while (tail > p && isspace((int) *tail)) {
|
||||
*tail = '\0';
|
||||
tail--;
|
||||
}
|
||||
|
||||
if (nconfiglist == alloced) {
|
||||
alloced += CONFIGLISTGROWSIZE;
|
||||
configlist=sasl_REALLOC((char *)configlist,
|
||||
alloced * sizeof(struct configlist));
|
||||
if (configlist == NULL) {
|
||||
fclose(infile);
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
result = _sasl_strdup(key,
|
||||
&(configlist[nconfiglist].key),
|
||||
NULL);
|
||||
if (result != SASL_OK) {
|
||||
fclose(infile);
|
||||
return result;
|
||||
}
|
||||
result = _sasl_strdup(p,
|
||||
&(configlist[nconfiglist].value),
|
||||
NULL);
|
||||
if (result != SASL_OK) {
|
||||
fclose(infile);
|
||||
return result;
|
||||
}
|
||||
|
||||
nconfiglist++;
|
||||
}
|
||||
fclose(infile);
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
const char *sasl_config_getstring(const char *key,const char *def)
|
||||
{
|
||||
int opt;
|
||||
|
||||
for (opt = 0; opt < nconfiglist; opt++) {
|
||||
if (*key == configlist[opt].key[0] &&
|
||||
!strcmp(key, configlist[opt].key))
|
||||
return configlist[opt].value;
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
void sasl_config_done(void)
|
||||
{
|
||||
int opt;
|
||||
|
||||
for (opt = 0; opt < nconfiglist; opt++) {
|
||||
if (configlist[opt].key) sasl_FREE(configlist[opt].key);
|
||||
if (configlist[opt].value) sasl_FREE(configlist[opt].value);
|
||||
}
|
||||
|
||||
sasl_FREE(configlist);
|
||||
configlist = NULL;
|
||||
nconfiglist = 0;
|
||||
}
|
||||
@@ -0,0 +1,562 @@
|
||||
/* dlopen.c--Unix dlopen() dynamic loader interface
|
||||
* Rob Siemborski
|
||||
* Rob Earhart
|
||||
* $Id: dlopen.c,v 1.52 2009/04/11 10:21:43 mel Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#ifdef HAVE_DLFCN_H
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include "saslint.h"
|
||||
|
||||
#ifndef PIC
|
||||
#include <saslplug.h>
|
||||
#include "staticopen.h"
|
||||
#endif
|
||||
|
||||
#ifdef DO_DLOPEN
|
||||
#if HAVE_DIRENT_H
|
||||
# include <dirent.h>
|
||||
# define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
#else /* HAVE_DIRENT_H */
|
||||
# define dirent direct
|
||||
# define NAMLEN(dirent) (dirent)->d_namlen
|
||||
# if HAVE_SYS_NDIR_H
|
||||
# include <sys/ndir.h>
|
||||
# endif
|
||||
# if HAVE_SYS_DIR_H
|
||||
# include <sys/dir.h>
|
||||
# endif
|
||||
# if HAVE_NDIR_H
|
||||
# include <ndir.h>
|
||||
# endif
|
||||
#endif /* ! HAVE_DIRENT_H */
|
||||
|
||||
#ifndef NAME_MAX
|
||||
# ifdef _POSIX_NAME_MAX
|
||||
# define NAME_MAX _POSIX_NAME_MAX
|
||||
# else
|
||||
# define NAME_MAX 16
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if NAME_MAX < 8
|
||||
# define NAME_MAX 8
|
||||
#endif
|
||||
|
||||
#ifdef __hpux
|
||||
#ifndef HAVE_DLFCN_H
|
||||
#include <dl.h>
|
||||
|
||||
typedef shl_t * dll_handle;
|
||||
typedef void * dll_func;
|
||||
|
||||
dll_handle
|
||||
dlopen(char *fname, int mode)
|
||||
{
|
||||
shl_t h = shl_load(fname, BIND_DEFERRED, 0L);
|
||||
shl_t *hp = NULL;
|
||||
|
||||
if (h) {
|
||||
hp = (shl_t *)malloc(sizeof (shl_t));
|
||||
if (!hp) {
|
||||
shl_unload(h);
|
||||
} else {
|
||||
*hp = h;
|
||||
}
|
||||
}
|
||||
|
||||
return (dll_handle)hp;
|
||||
}
|
||||
|
||||
int
|
||||
dlclose(dll_handle hp)
|
||||
{
|
||||
shl_t h;
|
||||
|
||||
if (hp != NULL) {
|
||||
h = *((shl_t *)hp);
|
||||
free(hp);
|
||||
return shl_unload(h);
|
||||
} else {
|
||||
/* Return error */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
dll_func
|
||||
dlsym(dll_handle h, char *n)
|
||||
{
|
||||
dll_func handle;
|
||||
|
||||
if (shl_findsym ((shl_t *)h, n, TYPE_PROCEDURE, &handle))
|
||||
return NULL;
|
||||
|
||||
return (dll_func)handle;
|
||||
}
|
||||
|
||||
char *dlerror()
|
||||
{
|
||||
if (errno != 0) {
|
||||
return strerror(errno);
|
||||
}
|
||||
return "Generic shared library error";
|
||||
}
|
||||
|
||||
#endif /* HAVE_DLFCN_H */
|
||||
|
||||
#ifdef __ia64
|
||||
#define SO_SUFFIX ".so"
|
||||
#else
|
||||
#define SO_SUFFIX ".sl"
|
||||
#endif /* __ia64 */
|
||||
#elif defined(__APPLE__)
|
||||
#define SO_SUFFIX ".plugin"
|
||||
#else /* __APPLE__ */
|
||||
#define SO_SUFFIX ".so"
|
||||
#endif
|
||||
|
||||
#define LA_SUFFIX ".la"
|
||||
|
||||
typedef struct lib_list
|
||||
{
|
||||
struct lib_list *next;
|
||||
void *library;
|
||||
} lib_list_t;
|
||||
|
||||
static lib_list_t *lib_list_head = NULL;
|
||||
|
||||
#endif /* DO_DLOPEN */
|
||||
|
||||
int _sasl_locate_entry(void *library, const char *entryname,
|
||||
void **entry_point)
|
||||
{
|
||||
#ifdef DO_DLOPEN
|
||||
/* note that we still check for known problem systems in
|
||||
* case we are cross-compiling */
|
||||
#if defined(DLSYM_NEEDS_UNDERSCORE) || (defined(__OpenBSD__) && !defined(__ELF__))
|
||||
char adj_entryname[1024];
|
||||
#else
|
||||
#define adj_entryname entryname
|
||||
#endif
|
||||
|
||||
if(!entryname) {
|
||||
_sasl_log(NULL, SASL_LOG_ERR,
|
||||
"no entryname in _sasl_locate_entry");
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
if(!library) {
|
||||
_sasl_log(NULL, SASL_LOG_ERR,
|
||||
"no library in _sasl_locate_entry");
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
if(!entry_point) {
|
||||
_sasl_log(NULL, SASL_LOG_ERR,
|
||||
"no entrypoint output pointer in _sasl_locate_entry");
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
#if defined(DLSYM_NEEDS_UNDERSCORE) || (defined(__OpenBSD__) && !defined(__ELF__))
|
||||
snprintf(adj_entryname, sizeof adj_entryname, "_%s", entryname);
|
||||
#endif
|
||||
|
||||
*entry_point = NULL;
|
||||
*entry_point = dlsym(library, adj_entryname);
|
||||
if (*entry_point == NULL) {
|
||||
#if 0 /* This message appears to confuse people */
|
||||
_sasl_log(NULL, SASL_LOG_DEBUG,
|
||||
"unable to get entry point %s: %s", adj_entryname,
|
||||
dlerror());
|
||||
#endif
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
return SASL_OK;
|
||||
#else
|
||||
return SASL_FAIL;
|
||||
#endif /* DO_DLOPEN */
|
||||
}
|
||||
|
||||
#ifdef DO_DLOPEN
|
||||
|
||||
static int _sasl_plugin_load(char *plugin, void *library,
|
||||
const char *entryname,
|
||||
int (*add_plugin)(const char *, void *))
|
||||
{
|
||||
void *entry_point;
|
||||
int result;
|
||||
|
||||
result = _sasl_locate_entry(library, entryname, &entry_point);
|
||||
if(result == SASL_OK) {
|
||||
result = add_plugin(plugin, entry_point);
|
||||
if(result != SASL_OK)
|
||||
_sasl_log(NULL, SASL_LOG_DEBUG,
|
||||
"_sasl_plugin_load failed on %s for plugin: %s\n",
|
||||
entryname, plugin);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* this returns the file to actually open.
|
||||
* out should be a buffer of size PATH_MAX
|
||||
* and may be the same as in. */
|
||||
|
||||
/* We'll use a static buffer for speed unless someone complains */
|
||||
#define MAX_LINE 2048
|
||||
|
||||
static int _parse_la(const char *prefix, const char *in, char *out)
|
||||
{
|
||||
FILE *file;
|
||||
size_t length;
|
||||
char line[MAX_LINE];
|
||||
char *ntmp = NULL;
|
||||
|
||||
if(!in || !out || !prefix || out == in) return SASL_BADPARAM;
|
||||
|
||||
/* Set this so we can detect failure */
|
||||
*out = '\0';
|
||||
|
||||
length = strlen(in);
|
||||
|
||||
if (strcmp(in + (length - strlen(LA_SUFFIX)), LA_SUFFIX)) {
|
||||
if(!strcmp(in + (length - strlen(SO_SUFFIX)),SO_SUFFIX)) {
|
||||
/* check for a .la file */
|
||||
strcpy(line, prefix);
|
||||
strcat(line, in);
|
||||
length = strlen(line);
|
||||
*(line + (length - strlen(SO_SUFFIX))) = '\0';
|
||||
strcat(line, LA_SUFFIX);
|
||||
file = fopen(line, "r");
|
||||
if(file) {
|
||||
/* We'll get it on the .la open */
|
||||
fclose(file);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
}
|
||||
strcpy(out, prefix);
|
||||
strcat(out, in);
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
strcpy(line, prefix);
|
||||
strcat(line, in);
|
||||
|
||||
file = fopen(line, "r");
|
||||
if(!file) {
|
||||
_sasl_log(NULL, SASL_LOG_WARN,
|
||||
"unable to open LA file: %s", line);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
while(!feof(file)) {
|
||||
if(!fgets(line, MAX_LINE, file)) break;
|
||||
if(line[strlen(line) - 1] != '\n') {
|
||||
_sasl_log(NULL, SASL_LOG_WARN,
|
||||
"LA file has too long of a line: %s", in);
|
||||
return SASL_BUFOVER;
|
||||
}
|
||||
if(line[0] == '\n' || line[0] == '#') continue;
|
||||
if(!strncmp(line, "dlname=", sizeof("dlname=") - 1)) {
|
||||
/* We found the line with the name in it */
|
||||
char *end;
|
||||
char *start;
|
||||
size_t len;
|
||||
end = strrchr(line, '\'');
|
||||
if(!end) continue;
|
||||
start = &line[sizeof("dlname=")-1];
|
||||
len = strlen(start);
|
||||
if(len > 3 && start[0] == '\'') {
|
||||
ntmp=&start[1];
|
||||
*end='\0';
|
||||
/* Do we have dlname="" ? */
|
||||
if(ntmp == end) {
|
||||
_sasl_log(NULL, SASL_LOG_DEBUG,
|
||||
"dlname is empty in .la file: %s", in);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
strcpy(out, prefix);
|
||||
strcat(out, ntmp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ferror(file) || feof(file)) {
|
||||
_sasl_log(NULL, SASL_LOG_WARN,
|
||||
"Error reading .la: %s\n", in);
|
||||
fclose(file);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
if(!(*out)) {
|
||||
_sasl_log(NULL, SASL_LOG_WARN,
|
||||
"Could not find a dlname line in .la file: %s", in);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
#endif /* DO_DLOPEN */
|
||||
|
||||
/* loads a plugin library */
|
||||
int _sasl_get_plugin(const char *file,
|
||||
const sasl_callback_t *verifyfile_cb,
|
||||
void **libraryptr)
|
||||
{
|
||||
#ifdef DO_DLOPEN
|
||||
int r = 0;
|
||||
int flag;
|
||||
void *library;
|
||||
lib_list_t *newhead;
|
||||
|
||||
r = ((sasl_verifyfile_t *)(verifyfile_cb->proc))
|
||||
(verifyfile_cb->context, file, SASL_VRFY_PLUGIN);
|
||||
if (r != SASL_OK) return r;
|
||||
|
||||
#ifdef RTLD_NOW
|
||||
flag = RTLD_NOW;
|
||||
#else
|
||||
flag = 0;
|
||||
#endif
|
||||
|
||||
newhead = sasl_ALLOC(sizeof(lib_list_t));
|
||||
if(!newhead) return SASL_NOMEM;
|
||||
|
||||
if (!(library = dlopen(file, flag))) {
|
||||
_sasl_log(NULL, SASL_LOG_ERR,
|
||||
"unable to dlopen %s: %s", file, dlerror());
|
||||
sasl_FREE(newhead);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
newhead->library = library;
|
||||
newhead->next = lib_list_head;
|
||||
lib_list_head = newhead;
|
||||
|
||||
*libraryptr = library;
|
||||
return SASL_OK;
|
||||
#else
|
||||
return SASL_FAIL;
|
||||
#endif /* DO_DLOPEN */
|
||||
}
|
||||
|
||||
/* gets the list of mechanisms */
|
||||
int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
|
||||
const sasl_callback_t *getpath_cb,
|
||||
const sasl_callback_t *verifyfile_cb)
|
||||
{
|
||||
int result;
|
||||
const add_plugin_list_t *cur_ep;
|
||||
#ifdef DO_DLOPEN
|
||||
char str[PATH_MAX], tmp[PATH_MAX+2], prefix[PATH_MAX+2];
|
||||
/* 1 for '/' 1 for trailing '\0' */
|
||||
char c;
|
||||
int pos;
|
||||
const char *path=NULL;
|
||||
int position;
|
||||
DIR *dp;
|
||||
struct dirent *dir;
|
||||
#endif
|
||||
#ifndef PIC
|
||||
add_plugin_t *add_plugin;
|
||||
_sasl_plug_type type;
|
||||
_sasl_plug_rec *p;
|
||||
#endif
|
||||
|
||||
if (! entrypoints
|
||||
|| ! getpath_cb
|
||||
|| getpath_cb->id != SASL_CB_GETPATH
|
||||
|| ! getpath_cb->proc
|
||||
|| ! verifyfile_cb
|
||||
|| verifyfile_cb->id != SASL_CB_VERIFYFILE
|
||||
|| ! verifyfile_cb->proc)
|
||||
return SASL_BADPARAM;
|
||||
|
||||
#ifndef PIC
|
||||
/* do all the static plugins first */
|
||||
|
||||
for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
|
||||
|
||||
/* What type of plugin are we looking for? */
|
||||
if(!strcmp(cur_ep->entryname, "sasl_server_plug_init")) {
|
||||
type = SERVER;
|
||||
add_plugin = (add_plugin_t *)sasl_server_add_plugin;
|
||||
} else if (!strcmp(cur_ep->entryname, "sasl_client_plug_init")) {
|
||||
type = CLIENT;
|
||||
add_plugin = (add_plugin_t *)sasl_client_add_plugin;
|
||||
} else if (!strcmp(cur_ep->entryname, "sasl_auxprop_plug_init")) {
|
||||
type = AUXPROP;
|
||||
add_plugin = (add_plugin_t *)sasl_auxprop_add_plugin;
|
||||
} else if (!strcmp(cur_ep->entryname, "sasl_canonuser_init")) {
|
||||
type = CANONUSER;
|
||||
add_plugin = (add_plugin_t *)sasl_canonuser_add_plugin;
|
||||
} else {
|
||||
/* What are we looking for then? */
|
||||
return SASL_FAIL;
|
||||
}
|
||||
for (p=_sasl_static_plugins; p->type; p++) {
|
||||
if(type == p->type)
|
||||
result = add_plugin(p->name, p->plug);
|
||||
}
|
||||
}
|
||||
#endif /* !PIC */
|
||||
|
||||
/* only do the following if:
|
||||
*
|
||||
* we support dlopen()
|
||||
* AND we are not staticly compiled
|
||||
* OR we are staticly compiled and TRY_DLOPEN_WHEN_STATIC is defined
|
||||
*/
|
||||
#if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC)))
|
||||
/* get the path to the plugins */
|
||||
result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
|
||||
&path);
|
||||
if (result != SASL_OK) return result;
|
||||
if (! path) return SASL_FAIL;
|
||||
|
||||
if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
position=0;
|
||||
do {
|
||||
pos=0;
|
||||
do {
|
||||
c=path[position];
|
||||
position++;
|
||||
str[pos]=c;
|
||||
pos++;
|
||||
} while ((c!=':') && (c!='=') && (c!=0));
|
||||
str[pos-1]='\0';
|
||||
|
||||
strcpy(prefix,str);
|
||||
strcat(prefix,"/");
|
||||
|
||||
if ((dp=opendir(str)) !=NULL) /* ignore errors */
|
||||
{
|
||||
while ((dir=readdir(dp)) != NULL)
|
||||
{
|
||||
size_t length;
|
||||
void *library;
|
||||
char *c;
|
||||
char plugname[PATH_MAX];
|
||||
char name[PATH_MAX];
|
||||
|
||||
length = NAMLEN(dir);
|
||||
if (length < 4)
|
||||
continue; /* can not possibly be what we're looking for */
|
||||
|
||||
if (length + pos>=PATH_MAX) continue; /* too big */
|
||||
|
||||
if (strcmp(dir->d_name + (length - strlen(SO_SUFFIX)),
|
||||
SO_SUFFIX)
|
||||
&& strcmp(dir->d_name + (length - strlen(LA_SUFFIX)),
|
||||
LA_SUFFIX))
|
||||
continue;
|
||||
|
||||
memcpy(name,dir->d_name,length);
|
||||
name[length]='\0';
|
||||
|
||||
result = _parse_la(prefix, name, tmp);
|
||||
if(result != SASL_OK)
|
||||
continue;
|
||||
|
||||
/* skip "lib" and cut off suffix --
|
||||
this only need be approximate */
|
||||
strcpy(plugname, name + 3);
|
||||
c = strchr(plugname, (int)'.');
|
||||
if(c) *c = '\0';
|
||||
|
||||
result = _sasl_get_plugin(tmp, verifyfile_cb, &library);
|
||||
|
||||
if(result != SASL_OK)
|
||||
continue;
|
||||
|
||||
for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
|
||||
_sasl_plugin_load(plugname, library, cur_ep->entryname,
|
||||
cur_ep->add_plugin);
|
||||
/* If this fails, it's not the end of the world */
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dp);
|
||||
} else {
|
||||
_sasl_log(NULL, SASL_LOG_DEBUG,
|
||||
"looking for plugins in '%s', failed to open directory, error: %s",
|
||||
str,
|
||||
strerror(errno));
|
||||
}
|
||||
|
||||
} while ((c!='=') && (c!=0));
|
||||
#endif /* defined(DO_DLOPEN) && (!defined(PIC) || (defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) */
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
_sasl_done_with_plugins(void)
|
||||
{
|
||||
#ifdef DO_DLOPEN
|
||||
lib_list_t *libptr, *libptr_next;
|
||||
|
||||
for(libptr = lib_list_head; libptr; libptr = libptr_next) {
|
||||
libptr_next = libptr->next;
|
||||
if(libptr->library)
|
||||
dlclose(libptr->library);
|
||||
sasl_FREE(libptr);
|
||||
}
|
||||
|
||||
lib_list_head = NULL;
|
||||
#endif /* DO_DLOPEN */
|
||||
return SASL_OK;
|
||||
}
|
||||
@@ -0,0 +1,410 @@
|
||||
/* SASL server API implementation
|
||||
* Rob Siemborski
|
||||
* Tim Martin
|
||||
* $Id: external.c,v 1.24 2009/03/10 16:27:52 mel Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include "saslint.h"
|
||||
|
||||
#include "../plugins/plugin_common.h"
|
||||
|
||||
/***************************** Common Section *****************************/
|
||||
|
||||
static const char plugin_id[] = "$Id: external.c,v 1.24 2009/03/10 16:27:52 mel Exp $";
|
||||
|
||||
/***************************** Server Section *****************************/
|
||||
|
||||
static int
|
||||
external_server_mech_new(void *glob_context __attribute__((unused)),
|
||||
sasl_server_params_t *sparams,
|
||||
const char *challenge __attribute__((unused)),
|
||||
unsigned challen __attribute__((unused)),
|
||||
void **conn_context)
|
||||
{
|
||||
if (!conn_context
|
||||
|| !sparams
|
||||
|| !sparams->utils
|
||||
|| !sparams->utils->conn)
|
||||
return SASL_BADPARAM;
|
||||
|
||||
if (!sparams->utils->conn->external.auth_id)
|
||||
return SASL_NOMECH;
|
||||
|
||||
*conn_context = NULL;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
external_server_mech_step(void *conn_context __attribute__((unused)),
|
||||
sasl_server_params_t *sparams,
|
||||
const char *clientin,
|
||||
unsigned clientinlen,
|
||||
const char **serverout,
|
||||
unsigned *serveroutlen,
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (!sparams
|
||||
|| !sparams->utils
|
||||
|| !sparams->utils->conn
|
||||
|| !sparams->utils->getcallback
|
||||
|| !serverout
|
||||
|| !serveroutlen
|
||||
|| !oparams)
|
||||
return SASL_BADPARAM;
|
||||
|
||||
if (!sparams->utils->conn->external.auth_id)
|
||||
return SASL_BADPROT;
|
||||
|
||||
/* xxx arbitrary limit here */
|
||||
if (clientinlen > 16384) return SASL_BADPROT;
|
||||
|
||||
if ((sparams->props.security_flags & SASL_SEC_NOANONYMOUS) &&
|
||||
(!strcmp(sparams->utils->conn->external.auth_id, "anonymous"))) {
|
||||
sasl_seterror(sparams->utils->conn,0,"anonymous login not allowed");
|
||||
return SASL_NOAUTHZ;
|
||||
}
|
||||
|
||||
*serverout = NULL;
|
||||
*serveroutlen = 0;
|
||||
|
||||
if (!clientin) {
|
||||
/* No initial data; we're in a protocol which doesn't support it.
|
||||
* So we let the server app know that we need some... */
|
||||
return SASL_CONTINUE;
|
||||
}
|
||||
|
||||
if (clientinlen) { /* if we have a non-zero authorization id */
|
||||
/* The user's trying to authorize as someone they didn't
|
||||
* authenticate as */
|
||||
result = sparams->canon_user(sparams->utils->conn,
|
||||
clientin, 0,
|
||||
SASL_CU_AUTHZID, oparams);
|
||||
if(result != SASL_OK) return result;
|
||||
|
||||
result = sparams->canon_user(sparams->utils->conn,
|
||||
sparams->utils->conn->external.auth_id, 0,
|
||||
SASL_CU_AUTHID | SASL_CU_EXTERNALLY_VERIFIED, oparams);
|
||||
} else {
|
||||
result = sparams->canon_user(sparams->utils->conn,
|
||||
sparams->utils->conn->external.auth_id, 0,
|
||||
SASL_CU_AUTHID | SASL_CU_EXTERNALLY_VERIFIED | SASL_CU_AUTHZID, oparams);
|
||||
}
|
||||
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
/* set oparams */
|
||||
oparams->doneflag = 1;
|
||||
oparams->mech_ssf = 0;
|
||||
oparams->maxoutbuf = 0;
|
||||
oparams->encode_context = NULL;
|
||||
oparams->encode = NULL;
|
||||
oparams->decode_context = NULL;
|
||||
oparams->decode = NULL;
|
||||
oparams->param_version = 0;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
external_server_mech_avail(void *glob_context __attribute__((unused)),
|
||||
sasl_server_params_t *sparams,
|
||||
void **conn_context __attribute__((unused)))
|
||||
{
|
||||
if (!sparams->utils->conn->external.auth_id) {
|
||||
/* Return Temporary Failure */
|
||||
return SASL_NOTDONE;
|
||||
}
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static sasl_server_plug_t external_server_plugins[] =
|
||||
{
|
||||
{
|
||||
"EXTERNAL", /* mech_name */
|
||||
0, /* max_ssf */
|
||||
SASL_SEC_NOPLAINTEXT
|
||||
| SASL_SEC_NOANONYMOUS
|
||||
| SASL_SEC_NODICTIONARY, /* security_flags */
|
||||
SASL_FEAT_WANT_CLIENT_FIRST
|
||||
| SASL_FEAT_ALLOWS_PROXY, /* features */
|
||||
NULL, /* glob_context */
|
||||
&external_server_mech_new, /* mech_new */
|
||||
&external_server_mech_step, /* mech_step */
|
||||
NULL, /* mech_dispose */
|
||||
NULL, /* mech_free */
|
||||
NULL, /* setpass */
|
||||
NULL, /* user_query */
|
||||
NULL, /* idle */
|
||||
&external_server_mech_avail, /* mech_avail */
|
||||
NULL /* spare */
|
||||
}
|
||||
};
|
||||
|
||||
int external_server_plug_init(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_server_plug_t **pluglist,
|
||||
int *plugcount)
|
||||
{
|
||||
if (!out_version || !pluglist || !plugcount)
|
||||
return SASL_BADPARAM;
|
||||
|
||||
if (max_version != SASL_SERVER_PLUG_VERSION) {
|
||||
SETERROR( utils, "EXTERNAL version mismatch" );
|
||||
return SASL_BADVERS;
|
||||
}
|
||||
|
||||
*out_version = SASL_SERVER_PLUG_VERSION;
|
||||
*pluglist = external_server_plugins;
|
||||
*plugcount = 1;
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
/***************************** Client Section *****************************/
|
||||
|
||||
typedef struct client_context
|
||||
{
|
||||
char *out_buf;
|
||||
size_t out_buf_len;
|
||||
} client_context_t;
|
||||
|
||||
static int external_client_mech_new(void *glob_context __attribute__((unused)),
|
||||
sasl_client_params_t *params,
|
||||
void **conn_context)
|
||||
{
|
||||
client_context_t *text;
|
||||
|
||||
if (!params
|
||||
|| !params->utils
|
||||
|| !params->utils->conn
|
||||
|| !conn_context)
|
||||
return SASL_BADPARAM;
|
||||
|
||||
if (!params->utils->conn->external.auth_id)
|
||||
return SASL_NOMECH;
|
||||
|
||||
text = sasl_ALLOC(sizeof(client_context_t));
|
||||
if(!text) return SASL_NOMEM;
|
||||
|
||||
memset(text, 0, sizeof(client_context_t));
|
||||
|
||||
*conn_context = text;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
external_client_mech_step(void *conn_context,
|
||||
sasl_client_params_t *params,
|
||||
const char *serverin __attribute__((unused)),
|
||||
unsigned serverinlen,
|
||||
sasl_interact_t **prompt_need,
|
||||
const char **clientout,
|
||||
unsigned *clientoutlen,
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
client_context_t *text = (client_context_t *)conn_context;
|
||||
const char *user = NULL;
|
||||
int user_result = SASL_OK;
|
||||
int result;
|
||||
|
||||
if (!params
|
||||
|| !params->utils
|
||||
|| !params->utils->conn
|
||||
|| !params->utils->getcallback
|
||||
|| !clientout
|
||||
|| !clientoutlen
|
||||
|| !oparams)
|
||||
return SASL_BADPARAM;
|
||||
|
||||
if (!params->utils->conn->external.auth_id)
|
||||
return SASL_BADPROT;
|
||||
|
||||
if (serverinlen != 0)
|
||||
return SASL_BADPROT;
|
||||
|
||||
*clientout = NULL;
|
||||
*clientoutlen = 0;
|
||||
|
||||
/* try to get the userid */
|
||||
if (user == NULL) {
|
||||
user_result = _plug_get_userid(params->utils, &user, prompt_need);
|
||||
|
||||
if ((user_result != SASL_OK) && (user_result != SASL_INTERACT))
|
||||
return user_result;
|
||||
}
|
||||
|
||||
/* free prompts we got */
|
||||
if (prompt_need && *prompt_need) {
|
||||
params->utils->free(*prompt_need);
|
||||
*prompt_need = NULL;
|
||||
}
|
||||
|
||||
/* if there are prompts not filled in */
|
||||
if (user_result == SASL_INTERACT) {
|
||||
/* make the prompt list */
|
||||
int result =
|
||||
_plug_make_prompts(params->utils, prompt_need,
|
||||
user_result == SASL_INTERACT ?
|
||||
"Please enter your authorization name" : NULL,
|
||||
"",
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
return SASL_INTERACT;
|
||||
}
|
||||
|
||||
*clientoutlen = user ? (unsigned) strlen(user) : 0;
|
||||
|
||||
result = _buf_alloc(&text->out_buf, &text->out_buf_len, *clientoutlen + 1);
|
||||
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
if (user && *user) {
|
||||
result = params->canon_user(params->utils->conn,
|
||||
user, 0, SASL_CU_AUTHZID, oparams);
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
result = params->canon_user(params->utils->conn,
|
||||
params->utils->conn->external.auth_id, 0,
|
||||
SASL_CU_AUTHID, oparams);
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
memcpy(text->out_buf, user, *clientoutlen);
|
||||
} else {
|
||||
result = params->canon_user(params->utils->conn,
|
||||
params->utils->conn->external.auth_id, 0,
|
||||
SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
|
||||
if (result != SASL_OK) return result;
|
||||
}
|
||||
|
||||
text->out_buf[*clientoutlen] = '\0';
|
||||
|
||||
*clientout = text->out_buf;
|
||||
|
||||
/* set oparams */
|
||||
oparams->doneflag = 1;
|
||||
oparams->mech_ssf = 0;
|
||||
oparams->maxoutbuf = 0;
|
||||
oparams->encode_context = NULL;
|
||||
oparams->encode = NULL;
|
||||
oparams->decode_context = NULL;
|
||||
oparams->decode = NULL;
|
||||
oparams->param_version = 0;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
external_client_mech_dispose(void *conn_context,
|
||||
const sasl_utils_t *utils __attribute__((unused)))
|
||||
{
|
||||
client_context_t *text = (client_context_t *) conn_context;
|
||||
|
||||
if (!text) return;
|
||||
|
||||
if(text->out_buf) sasl_FREE(text->out_buf);
|
||||
|
||||
sasl_FREE(text);
|
||||
}
|
||||
|
||||
static const unsigned long external_required_prompts[] = {
|
||||
SASL_CB_LIST_END
|
||||
};
|
||||
|
||||
static sasl_client_plug_t external_client_plugins[] =
|
||||
{
|
||||
{
|
||||
"EXTERNAL", /* mech_name */
|
||||
0, /* max_ssf */
|
||||
SASL_SEC_NOPLAINTEXT
|
||||
| SASL_SEC_NOANONYMOUS
|
||||
| SASL_SEC_NODICTIONARY, /* security_flags */
|
||||
SASL_FEAT_WANT_CLIENT_FIRST
|
||||
| SASL_FEAT_ALLOWS_PROXY, /* features */
|
||||
external_required_prompts, /* required_prompts */
|
||||
NULL, /* glob_context */
|
||||
&external_client_mech_new, /* mech_new */
|
||||
&external_client_mech_step, /* mech_step */
|
||||
&external_client_mech_dispose, /* mech_dispose */
|
||||
NULL, /* mech_free */
|
||||
NULL, /* idle */
|
||||
NULL, /* spare */
|
||||
NULL /* spare */
|
||||
}
|
||||
};
|
||||
|
||||
int external_client_plug_init(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_client_plug_t **pluglist,
|
||||
int *plugcount)
|
||||
{
|
||||
if (!utils || !out_version || !pluglist || !plugcount)
|
||||
return SASL_BADPARAM;
|
||||
|
||||
if (max_version != SASL_CLIENT_PLUG_VERSION) {
|
||||
SETERROR( utils, "EXTERNAL version mismatch" );
|
||||
return SASL_BADVERS;
|
||||
}
|
||||
|
||||
*out_version = SASL_CLIENT_PLUG_VERSION;
|
||||
*pluglist = external_client_plugins;
|
||||
*plugcount = 1;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Mar 8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org>
|
||||
* $Id: getaddrinfo.c,v 1.8 2003/03/19 18:25:28 rjs3 Exp $
|
||||
*
|
||||
* This module is based on ssh-1.2.27-IPv6-1.5 written by
|
||||
* KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
|
||||
* These funtions are defined in rfc2133.
|
||||
*
|
||||
* But these functions are not implemented correctly. The minimum subset
|
||||
* is implemented for ssh use only. For exapmle, this routine assumes
|
||||
* that ai_family is AF_INET. Don't use it for another purpose.
|
||||
*
|
||||
* In the case not using 'configure --enable-ipv6', this getaddrinfo.c
|
||||
* will be used if you have broken getaddrinfo or no getaddrinfo.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifndef WIN32
|
||||
#include <sys/param.h>
|
||||
# ifndef macintosh
|
||||
# include <arpa/inet.h>
|
||||
# endif /* macintosh */
|
||||
#endif /* WIN32 */
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef WIN32
|
||||
/* : Windows socket library is missing inet_aton, emulate it with
|
||||
: inet_addr. inet_aton return 0 if the address is uncorrect, a non zero
|
||||
: value otherwise */
|
||||
int
|
||||
inet_aton (const char *cp, struct in_addr *inp)
|
||||
{
|
||||
if (cp == NULL || inp == NULL) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* : handle special case */
|
||||
if (strcmp (cp, "255.255.255.255") == 0) {
|
||||
inp->s_addr = (unsigned int) 0xFFFFFFFF;
|
||||
return (1);
|
||||
}
|
||||
|
||||
inp->s_addr = inet_addr (cp);
|
||||
return (1);
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
static struct addrinfo *
|
||||
malloc_ai(int port, unsigned long addr, int socktype, int proto)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
|
||||
ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) +
|
||||
sizeof(struct sockaddr_in));
|
||||
if (ai) {
|
||||
memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
|
||||
ai->ai_addr = (struct sockaddr *)(ai + 1);
|
||||
/* XXX -- ssh doesn't use sa_len */
|
||||
ai->ai_addrlen = sizeof(struct sockaddr_in);
|
||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||
ai->ai_addr->sa_len = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
ai->ai_addr->sa_family = ai->ai_family = AF_INET;
|
||||
((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
|
||||
((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
|
||||
ai->ai_socktype = socktype;
|
||||
ai->ai_protocol = proto;
|
||||
return ai;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
gai_strerror(int ecode)
|
||||
{
|
||||
switch (ecode) {
|
||||
case EAI_NODATA:
|
||||
return "no address associated with hostname.";
|
||||
case EAI_MEMORY:
|
||||
return "memory allocation failure.";
|
||||
case EAI_FAMILY:
|
||||
return "ai_family not supported.";
|
||||
case EAI_SERVICE:
|
||||
return "servname not supported for ai_socktype.";
|
||||
default:
|
||||
return "unknown error.";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
freeaddrinfo(struct addrinfo *ai)
|
||||
{
|
||||
struct addrinfo *next;
|
||||
|
||||
if (ai->ai_canonname)
|
||||
free(ai->ai_canonname);
|
||||
do {
|
||||
next = ai->ai_next;
|
||||
free(ai);
|
||||
} while ((ai = next) != NULL);
|
||||
}
|
||||
|
||||
int
|
||||
getaddrinfo(const char *hostname, const char *servname,
|
||||
const struct addrinfo *hints, struct addrinfo **res)
|
||||
{
|
||||
struct addrinfo *cur, *prev = NULL;
|
||||
struct hostent *hp;
|
||||
struct in_addr in;
|
||||
int i, port = 0, socktype, proto;
|
||||
|
||||
if (hints && hints->ai_family != PF_INET && hints->ai_family != PF_UNSPEC)
|
||||
return EAI_FAMILY;
|
||||
|
||||
socktype = (hints && hints->ai_socktype) ? hints->ai_socktype
|
||||
: SOCK_STREAM;
|
||||
if (hints && hints->ai_protocol)
|
||||
proto = hints->ai_protocol;
|
||||
else {
|
||||
switch (socktype) {
|
||||
case SOCK_DGRAM:
|
||||
proto = IPPROTO_UDP;
|
||||
break;
|
||||
case SOCK_STREAM:
|
||||
proto = IPPROTO_TCP;
|
||||
break;
|
||||
default:
|
||||
proto = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (servname) {
|
||||
if (isdigit((int)*servname))
|
||||
port = htons((short) atoi(servname));
|
||||
else {
|
||||
struct servent *se;
|
||||
char *pe_proto;
|
||||
|
||||
switch (socktype) {
|
||||
case SOCK_DGRAM:
|
||||
pe_proto = "udp";
|
||||
break;
|
||||
case SOCK_STREAM:
|
||||
pe_proto = "tcp";
|
||||
break;
|
||||
default:
|
||||
pe_proto = NULL;
|
||||
break;
|
||||
}
|
||||
/* xxx thread safety ? */
|
||||
if ((se = getservbyname(servname, pe_proto)) == NULL)
|
||||
return EAI_SERVICE;
|
||||
port = se->s_port;
|
||||
}
|
||||
}
|
||||
if (!hostname) {
|
||||
if (hints && hints->ai_flags & AI_PASSIVE)
|
||||
*res = malloc_ai(port, htonl(0x00000000), socktype, proto);
|
||||
else
|
||||
*res = malloc_ai(port, htonl(0x7f000001), socktype, proto);
|
||||
if (*res)
|
||||
return 0;
|
||||
else
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
#if HAVE_INET_ATON
|
||||
if (inet_aton(hostname, &in))
|
||||
#else
|
||||
if ((in.s_addr = inet_addr(hostname)) != -1)
|
||||
#endif
|
||||
{
|
||||
*res = malloc_ai(port, in.s_addr, socktype, proto);
|
||||
if (*res)
|
||||
return 0;
|
||||
else
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
if (hints && hints->ai_flags & AI_NUMERICHOST)
|
||||
return EAI_NODATA;
|
||||
#ifndef macintosh
|
||||
/* xxx thread safety? / gethostbyname_r */
|
||||
if ((hp = gethostbyname(hostname)) &&
|
||||
hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
|
||||
for (i = 0; hp->h_addr_list[i]; i++) {
|
||||
if ((cur = malloc_ai(port,
|
||||
((struct in_addr *)hp->h_addr_list[i])->s_addr,
|
||||
socktype, proto)) == NULL) {
|
||||
if (*res)
|
||||
freeaddrinfo(*res);
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
if (prev)
|
||||
prev->ai_next = cur;
|
||||
else
|
||||
*res = cur;
|
||||
prev = cur;
|
||||
}
|
||||
if (hints && hints->ai_flags & AI_CANONNAME && *res) {
|
||||
/* NOT sasl_strdup for compatibility */
|
||||
if (((*res)->ai_canonname = strdup(hp->h_name)) == NULL) {
|
||||
freeaddrinfo(*res);
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return EAI_NODATA;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Mar 8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org>
|
||||
* $Id: getnameinfo.c,v 1.5 2003/02/13 19:55:54 rjs3 Exp $
|
||||
*
|
||||
* This module is besed on ssh-1.2.27-IPv6-1.5 written by
|
||||
* KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
/*
|
||||
* fake library for ssh
|
||||
*
|
||||
* This file includes getnameinfo().
|
||||
* These funtions are defined in rfc2133.
|
||||
*
|
||||
* But these functions are not implemented correctly. The minimum subset
|
||||
* is implemented for ssh use only. For exapmle, this routine assumes
|
||||
* that ai_family is AF_INET. Don't use it for another purpose.
|
||||
*
|
||||
* In the case not using 'configure --enable-ipv6', this getnameinfo.c
|
||||
* will be used if you have broken getnameinfo or no getnameinfo.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifndef WIN32
|
||||
# include <arpa/inet.h>
|
||||
#endif /* WIN32 */
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int
|
||||
getnameinfo(const struct sockaddr *sa, socklen_t salen __attribute__((unused)),
|
||||
char *host, size_t hostlen, char *serv, size_t servlen, int flags)
|
||||
{
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||
struct hostent *hp;
|
||||
char tmpserv[16];
|
||||
|
||||
if (serv) {
|
||||
sprintf(tmpserv, "%d", ntohs(sin->sin_port));
|
||||
if (strlen(tmpserv) > servlen)
|
||||
return EAI_MEMORY;
|
||||
else
|
||||
strcpy(serv, tmpserv);
|
||||
}
|
||||
if (host) {
|
||||
if (flags & NI_NUMERICHOST) {
|
||||
if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen)
|
||||
return EAI_MEMORY;
|
||||
else {
|
||||
strcpy(host, inet_ntoa(sin->sin_addr));
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
hp = gethostbyaddr((char *)&sin->sin_addr,
|
||||
sizeof(struct in_addr), AF_INET);
|
||||
if (hp) {
|
||||
if (strlen(hp->h_name) >= hostlen)
|
||||
return EAI_MEMORY;
|
||||
else {
|
||||
strcpy(host, hp->h_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
return EAI_NODATA;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/* $NetBSD: getsubopt.c,v 1.4 1998/02/03 18:44:15 perry Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS 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 THE REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#if ((!defined(WIN32))&&(!defined(macintosh)))
|
||||
#include <sys/cdefs.h>
|
||||
#endif /* WIN32 */
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)getsubopt.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: getsubopt.c,v 1.4 1998/02/03 18:44:15 perry Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif /* HAVE_UNISTD_H */
|
||||
#if (defined(WIN32)||(defined(macintosh)))
|
||||
#include "sasl.h"
|
||||
LIBSASL_API int getsubopt(char **optionp, char * const *tokens, char **valuep);
|
||||
#endif /* WIN32 */
|
||||
/*
|
||||
* The SVID interface to getsubopt provides no way of figuring out which
|
||||
* part of the suboptions list wasn't matched. This makes error messages
|
||||
* tricky... The extern variable suboptarg is a pointer to the token
|
||||
* which didn't match.
|
||||
*/
|
||||
char *suboptarg;
|
||||
|
||||
int
|
||||
getsubopt(optionp, tokens, valuep)
|
||||
char **optionp, **valuep;
|
||||
char * const *tokens;
|
||||
{
|
||||
int cnt;
|
||||
char *p;
|
||||
|
||||
suboptarg = *valuep = NULL;
|
||||
|
||||
if (!optionp || !*optionp)
|
||||
return(-1);
|
||||
|
||||
/* skip leading white-space, commas */
|
||||
for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
|
||||
|
||||
if (!*p) {
|
||||
*optionp = p;
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* save the start of the token, and skip the rest of the token. */
|
||||
for (suboptarg = p;
|
||||
*++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
|
||||
|
||||
if (*p) {
|
||||
/*
|
||||
* If there's an equals sign, set the value pointer, and
|
||||
* skip over the value part of the token. Terminate the
|
||||
* token.
|
||||
*/
|
||||
if (*p == '=') {
|
||||
*p = '\0';
|
||||
for (*valuep = ++p;
|
||||
*p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
|
||||
if (*p)
|
||||
*p++ = '\0';
|
||||
} else
|
||||
*p++ = '\0';
|
||||
/* Skip any whitespace or commas after this token. */
|
||||
for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
|
||||
}
|
||||
|
||||
/* set optionp for next round. */
|
||||
*optionp = p;
|
||||
|
||||
for (cnt = 0; *tokens; ++tokens, ++cnt)
|
||||
if (!strcmp(suboptarg, *tokens))
|
||||
return(cnt);
|
||||
return(-1);
|
||||
}
|
||||
@@ -0,0 +1,527 @@
|
||||
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
||||
*/
|
||||
|
||||
/* Function names changed to avoid namespace collisions: Rob Siemborski */
|
||||
|
||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "md5global.h"
|
||||
#include "md5.h"
|
||||
#include "hmac-md5.h"
|
||||
|
||||
#ifndef WIN32
|
||||
# include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
/* Constants for MD5Transform routine.
|
||||
*/
|
||||
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
static void MD5Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
|
||||
static void Encode PROTO_LIST
|
||||
((unsigned char *, UINT4 *, unsigned int));
|
||||
static void Decode PROTO_LIST
|
||||
((UINT4 *, const unsigned char *, unsigned int));
|
||||
static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
|
||||
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
|
||||
|
||||
static unsigned char PADDING[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* F, G, H and I are basic MD5 functions.
|
||||
|
||||
*/
|
||||
#ifdef I
|
||||
/* This might be defined via NANA */
|
||||
#undef I
|
||||
#endif
|
||||
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits.
|
||||
|
||||
*/
|
||||
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
Rotation is separate from addition to prevent recomputation.
|
||||
*/
|
||||
|
||||
#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
|
||||
#define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
|
||||
#define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
|
||||
#define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
|
||||
|
||||
/* MD5 initialization. Begins an MD5 operation, writing a new context.
|
||||
*/
|
||||
|
||||
void _sasl_MD5Init (context)
|
||||
MD5_CTX *context; /* context */
|
||||
{
|
||||
context->count[0] = context->count[1] = 0;
|
||||
|
||||
/* Load magic initialization constants. */
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xefcdab89;
|
||||
context->state[2] = 0x98badcfe;
|
||||
context->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
/* MD5 block update operation. Continues an MD5 message-digest
|
||||
operation, processing another message block, and updating the context.
|
||||
*/
|
||||
|
||||
void _sasl_MD5Update (context, input, inputLen)
|
||||
MD5_CTX *context; /* context */
|
||||
const unsigned char *input; /* input block */
|
||||
unsigned int inputLen; /* length of input block */
|
||||
{
|
||||
unsigned int i, index, partLen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
|
||||
|
||||
/* Update number of bits */
|
||||
if ((context->count[0] += ((UINT4)inputLen << 3))
|
||||
< ((UINT4)inputLen << 3))
|
||||
context->count[1]++;
|
||||
context->count[1] += ((UINT4)inputLen >> 29);
|
||||
|
||||
partLen = 64 - index;
|
||||
|
||||
/* Transform as many times as possible.
|
||||
|
||||
*/
|
||||
if (inputLen >= partLen) {
|
||||
MD5_memcpy
|
||||
((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform
|
||||
(context->state, context->buffer);
|
||||
|
||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||
MD5Transform (context->state, &input[i]);
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
|
||||
/* Buffer remaining input */
|
||||
MD5_memcpy
|
||||
((POINTER)&context->buffer[index], (POINTER)&input[i],
|
||||
inputLen-i);
|
||||
|
||||
}
|
||||
|
||||
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||
the message digest and zeroizing the context.
|
||||
*/
|
||||
|
||||
void _sasl_MD5Final (digest, context)
|
||||
unsigned char digest[16]; /* message digest */
|
||||
MD5_CTX *context; /* context */
|
||||
{
|
||||
unsigned char bits[8];
|
||||
unsigned int index, padLen;
|
||||
|
||||
/* Save number of bits */
|
||||
Encode (bits, context->count, 8);
|
||||
|
||||
/* Pad out to 56 mod 64. */
|
||||
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
|
||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
_sasl_MD5Update (context, PADDING, padLen);
|
||||
|
||||
/* Append length (before padding) */
|
||||
_sasl_MD5Update (context, bits, 8);
|
||||
|
||||
/* Store state in digest */
|
||||
Encode (digest, context->state, 16);
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
MD5_memset ((POINTER)context, 0, sizeof (*context));
|
||||
}
|
||||
|
||||
/* MD5 basic transformation. Transforms state based on block. */
|
||||
|
||||
static void MD5Transform (state, block)
|
||||
UINT4 state[4];
|
||||
const unsigned char block[64];
|
||||
{
|
||||
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
Decode (x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
/* Zeroize sensitive information.
|
||||
*/
|
||||
MD5_memset ((POINTER)x, 0, sizeof (x));
|
||||
}
|
||||
|
||||
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
|
||||
a multiple of 4.
|
||||
|
||||
*/
|
||||
|
||||
static void Encode (output, input, len)
|
||||
unsigned char *output;
|
||||
UINT4 *input;
|
||||
unsigned int len;
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = (unsigned char)(input[i] & 0xff);
|
||||
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
|
||||
a multiple of 4.
|
||||
|
||||
*/
|
||||
|
||||
static void Decode (output, input, len)
|
||||
UINT4 *output;
|
||||
const unsigned char *input;
|
||||
unsigned int len;
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16)
|
||||
| (((UINT4)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
/* Note: Replace "for loop" with standard memcpy if possible.
|
||||
|
||||
*/
|
||||
|
||||
static void MD5_memcpy (output, input, len)
|
||||
POINTER output;
|
||||
POINTER input;
|
||||
unsigned int len;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
output[i] = input[i];
|
||||
}
|
||||
|
||||
/* Note: Replace "for loop" with standard memset if possible.
|
||||
*/
|
||||
|
||||
static void MD5_memset (output, value, len)
|
||||
POINTER output;
|
||||
int value;
|
||||
unsigned int len;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
((char *)output)[i] = (char)value;
|
||||
}
|
||||
|
||||
void _sasl_hmac_md5_init(HMAC_MD5_CTX *hmac,
|
||||
const unsigned char *key,
|
||||
int key_len)
|
||||
{
|
||||
unsigned char k_ipad[65]; /* inner padding -
|
||||
* key XORd with ipad
|
||||
*/
|
||||
unsigned char k_opad[65]; /* outer padding -
|
||||
* key XORd with opad
|
||||
*/
|
||||
unsigned char tk[16];
|
||||
int i;
|
||||
/* if key is longer than 64 bytes reset it to key=MD5(key) */
|
||||
if (key_len > 64) {
|
||||
|
||||
MD5_CTX tctx;
|
||||
|
||||
_sasl_MD5Init(&tctx);
|
||||
_sasl_MD5Update(&tctx, key, key_len);
|
||||
_sasl_MD5Final(tk, &tctx);
|
||||
|
||||
key = tk;
|
||||
key_len = 16;
|
||||
}
|
||||
|
||||
/*
|
||||
* the HMAC_MD5 transform looks like:
|
||||
*
|
||||
* MD5(K XOR opad, MD5(K XOR ipad, text))
|
||||
*
|
||||
* where K is an n byte key
|
||||
* ipad is the byte 0x36 repeated 64 times
|
||||
* opad is the byte 0x5c repeated 64 times
|
||||
* and text is the data being protected
|
||||
*/
|
||||
|
||||
/* start out by storing key in pads */
|
||||
MD5_memset((POINTER)k_ipad, '\0', sizeof k_ipad);
|
||||
MD5_memset((POINTER)k_opad, '\0', sizeof k_opad);
|
||||
MD5_memcpy( k_ipad, (POINTER)key, key_len);
|
||||
MD5_memcpy( k_opad, (POINTER)key, key_len);
|
||||
|
||||
/* XOR key with ipad and opad values */
|
||||
for (i=0; i<64; i++) {
|
||||
k_ipad[i] ^= 0x36;
|
||||
k_opad[i] ^= 0x5c;
|
||||
}
|
||||
|
||||
_sasl_MD5Init(&hmac->ictx); /* init inner context */
|
||||
_sasl_MD5Update(&hmac->ictx, k_ipad, 64); /* apply inner pad */
|
||||
|
||||
_sasl_MD5Init(&hmac->octx); /* init outer context */
|
||||
_sasl_MD5Update(&hmac->octx, k_opad, 64); /* apply outer pad */
|
||||
|
||||
/* scrub the pads and key context (if used) */
|
||||
MD5_memset((POINTER)&k_ipad, 0, sizeof(k_ipad));
|
||||
MD5_memset((POINTER)&k_opad, 0, sizeof(k_opad));
|
||||
MD5_memset((POINTER)&tk, 0, sizeof(tk));
|
||||
|
||||
/* and we're done. */
|
||||
}
|
||||
|
||||
/* The precalc and import routines here rely on the fact that we pad
|
||||
* the key out to 64 bytes and use that to initialize the md5
|
||||
* contexts, and that updating an md5 context with 64 bytes of data
|
||||
* leaves nothing left over; all of the interesting state is contained
|
||||
* in the state field, and none of it is left over in the count and
|
||||
* buffer fields. So all we have to do is save the state field; we
|
||||
* can zero the others when we reload it. Which is why the decision
|
||||
* was made to pad the key out to 64 bytes in the first place. */
|
||||
void _sasl_hmac_md5_precalc(HMAC_MD5_STATE *state,
|
||||
const unsigned char *key,
|
||||
int key_len)
|
||||
{
|
||||
HMAC_MD5_CTX hmac;
|
||||
unsigned lupe;
|
||||
|
||||
_sasl_hmac_md5_init(&hmac, key, key_len);
|
||||
for (lupe = 0; lupe < 4; lupe++) {
|
||||
state->istate[lupe] = htonl(hmac.ictx.state[lupe]);
|
||||
state->ostate[lupe] = htonl(hmac.octx.state[lupe]);
|
||||
}
|
||||
MD5_memset((POINTER)&hmac, 0, sizeof(hmac));
|
||||
}
|
||||
|
||||
|
||||
void _sasl_hmac_md5_import(HMAC_MD5_CTX *hmac,
|
||||
HMAC_MD5_STATE *state)
|
||||
{
|
||||
unsigned lupe;
|
||||
MD5_memset((POINTER)hmac, 0, sizeof(HMAC_MD5_CTX));
|
||||
for (lupe = 0; lupe < 4; lupe++) {
|
||||
hmac->ictx.state[lupe] = ntohl(state->istate[lupe]);
|
||||
hmac->octx.state[lupe] = ntohl(state->ostate[lupe]);
|
||||
}
|
||||
/* Init the counts to account for our having applied
|
||||
* 64 bytes of key; this works out to 0x200 (64 << 3; see
|
||||
* MD5Update above...) */
|
||||
hmac->ictx.count[0] = hmac->octx.count[0] = 0x200;
|
||||
}
|
||||
|
||||
void _sasl_hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
|
||||
HMAC_MD5_CTX *hmac)
|
||||
{
|
||||
_sasl_MD5Final(digest, &hmac->ictx); /* Finalize inner md5 */
|
||||
_sasl_MD5Update(&hmac->octx, digest, 16); /* Update outer ctx */
|
||||
_sasl_MD5Final(digest, &hmac->octx); /* Finalize outer md5 */
|
||||
}
|
||||
|
||||
|
||||
void _sasl_hmac_md5(text, text_len, key, key_len, digest)
|
||||
const unsigned char* text; /* pointer to data stream */
|
||||
int text_len; /* length of data stream */
|
||||
const unsigned char* key; /* pointer to authentication key */
|
||||
int key_len; /* length of authentication key */
|
||||
unsigned char *digest; /* caller digest to be filled in */
|
||||
{
|
||||
MD5_CTX context;
|
||||
|
||||
unsigned char k_ipad[65]; /* inner padding -
|
||||
* key XORd with ipad
|
||||
*/
|
||||
unsigned char k_opad[65]; /* outer padding -
|
||||
* key XORd with opad
|
||||
*/
|
||||
unsigned char tk[16];
|
||||
int i;
|
||||
/* if key is longer than 64 bytes reset it to key=MD5(key) */
|
||||
if (key_len > 64) {
|
||||
|
||||
MD5_CTX tctx;
|
||||
|
||||
_sasl_MD5Init(&tctx);
|
||||
_sasl_MD5Update(&tctx, key, key_len);
|
||||
_sasl_MD5Final(tk, &tctx);
|
||||
|
||||
key = tk;
|
||||
key_len = 16;
|
||||
}
|
||||
|
||||
/*
|
||||
* the HMAC_MD5 transform looks like:
|
||||
*
|
||||
* MD5(K XOR opad, MD5(K XOR ipad, text))
|
||||
*
|
||||
* where K is an n byte key
|
||||
* ipad is the byte 0x36 repeated 64 times
|
||||
* opad is the byte 0x5c repeated 64 times
|
||||
* and text is the data being protected
|
||||
*/
|
||||
|
||||
/* start out by storing key in pads */
|
||||
MD5_memset(k_ipad, '\0', sizeof k_ipad);
|
||||
MD5_memset(k_opad, '\0', sizeof k_opad);
|
||||
MD5_memcpy( k_ipad, (POINTER)key, key_len);
|
||||
MD5_memcpy( k_opad, (POINTER)key, key_len);
|
||||
|
||||
/* XOR key with ipad and opad values */
|
||||
for (i=0; i<64; i++) {
|
||||
k_ipad[i] ^= 0x36;
|
||||
k_opad[i] ^= 0x5c;
|
||||
}
|
||||
/*
|
||||
* perform inner MD5
|
||||
*/
|
||||
|
||||
_sasl_MD5Init(&context); /* init context for 1st
|
||||
* pass */
|
||||
_sasl_MD5Update(&context, k_ipad, 64); /* start with inner pad */
|
||||
_sasl_MD5Update(&context, text, text_len); /* then text of datagram */
|
||||
_sasl_MD5Final(digest, &context); /* finish up 1st pass */
|
||||
|
||||
/*
|
||||
* perform outer MD5
|
||||
*/
|
||||
_sasl_MD5Init(&context); /* init context for 2nd
|
||||
* pass */
|
||||
_sasl_MD5Update(&context, k_opad, 64); /* start with outer pad */
|
||||
_sasl_MD5Update(&context, digest, 16); /* then results of 1st
|
||||
* hash */
|
||||
_sasl_MD5Final(digest, &context); /* finish up 2nd pass */
|
||||
|
||||
}
|
||||
@@ -0,0 +1,528 @@
|
||||
/* saslint.h - internal SASL library definitions
|
||||
* Rob Siemborski
|
||||
* Tim Martin
|
||||
* $Id: saslint.h,v 1.73 2011/09/01 14:12:53 mel Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef SASLINT_H
|
||||
#define SASLINT_H
|
||||
|
||||
#include <config.h>
|
||||
#include "sasl.h"
|
||||
#include "saslplug.h"
|
||||
#include "saslutil.h"
|
||||
#include "prop.h"
|
||||
|
||||
#ifndef INLINE
|
||||
#if defined (WIN32)
|
||||
/* Visual Studio: "inline" keyword is not available in C, only in C++ */
|
||||
#define INLINE __inline
|
||||
#else
|
||||
#define INLINE inline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* #define'd constants */
|
||||
#define CANON_BUF_SIZE 1024
|
||||
|
||||
/* Error Handling Foo */
|
||||
/* Helpful Hints:
|
||||
* -Error strings are set as soon as possible (first function in stack trace
|
||||
* with a pointer to the sasl_conn_t.
|
||||
* -Error codes are set as late as possible (only in the sasl api functions),
|
||||
* though "as often as possible" also comes to mind to ensure correctness
|
||||
* -Errors from calls to _buf_alloc, _sasl_strdup, etc are assumed to be
|
||||
* memory errors.
|
||||
* -Only errors (error codes < SASL_OK) should be remembered
|
||||
*/
|
||||
#define RETURN(conn, val) { if(conn && (val) < SASL_OK) \
|
||||
(conn)->error_code = (val); \
|
||||
return (val); }
|
||||
#define MEMERROR(conn) {\
|
||||
if(conn) sasl_seterror( (conn), 0, \
|
||||
"Out of Memory in " __FILE__ " near line %d", __LINE__ ); \
|
||||
RETURN(conn, SASL_NOMEM) }
|
||||
#define PARAMERROR(conn) {\
|
||||
if(conn) sasl_seterror( (conn), SASL_NOLOG, \
|
||||
"Parameter error in " __FILE__ " near line %d", __LINE__ ); \
|
||||
RETURN(conn, SASL_BADPARAM) }
|
||||
#define INTERROR(conn, val) {\
|
||||
if(conn) sasl_seterror( (conn), 0, \
|
||||
"Internal Error %d in " __FILE__ " near line %d", (val),\
|
||||
__LINE__ ); \
|
||||
RETURN(conn, (val)) }
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# ifdef WIN32
|
||||
# define PATH_MAX MAX_PATH
|
||||
# else
|
||||
# ifdef _POSIX_PATH_MAX
|
||||
# define PATH_MAX _POSIX_PATH_MAX
|
||||
# else
|
||||
# define PATH_MAX 1024 /* arbitrary; probably big enough.
|
||||
* will probably only be 256+64 on
|
||||
* pre-posix machines */
|
||||
# endif /* _POSIX_PATH_MAX */
|
||||
# endif /* WIN32 */
|
||||
#endif
|
||||
|
||||
/* : Define directory delimiter in SASL_PATH/SASL_CONF_PATH variables */
|
||||
#ifdef WIN32
|
||||
#define PATHS_DELIMITER ';'
|
||||
#else
|
||||
#define PATHS_DELIMITER ':'
|
||||
#endif
|
||||
|
||||
/* Datatype Definitions */
|
||||
typedef struct {
|
||||
const sasl_callback_t *callbacks;
|
||||
const char *appname;
|
||||
} sasl_global_callbacks_t;
|
||||
|
||||
typedef struct _sasl_external_properties
|
||||
{
|
||||
sasl_ssf_t ssf;
|
||||
char *auth_id;
|
||||
} _sasl_external_properties_t;
|
||||
|
||||
typedef struct sasl_string_list
|
||||
{
|
||||
const char *d;
|
||||
struct sasl_string_list *next;
|
||||
} sasl_string_list_t;
|
||||
|
||||
typedef struct buffer_info
|
||||
{
|
||||
char *data;
|
||||
size_t curlen;
|
||||
size_t reallen;
|
||||
} buffer_info_t;
|
||||
|
||||
typedef int add_plugin_t(const char *, void *);
|
||||
|
||||
typedef struct add_plugin_list
|
||||
{
|
||||
const char *entryname;
|
||||
add_plugin_t *add_plugin;
|
||||
} add_plugin_list_t;
|
||||
|
||||
enum Sasl_conn_type { SASL_CONN_UNKNOWN = 0,
|
||||
SASL_CONN_SERVER = 1,
|
||||
SASL_CONN_CLIENT = 2 };
|
||||
|
||||
struct sasl_conn {
|
||||
enum Sasl_conn_type type;
|
||||
|
||||
void (*destroy_conn)(sasl_conn_t *); /* destroy function */
|
||||
|
||||
char *service;
|
||||
|
||||
unsigned int flags; /* flags passed to sasl_*_new */
|
||||
|
||||
/* IP information. A buffer of size 52 is adequate for this in its
|
||||
longest format (see sasl.h) */
|
||||
int got_ip_local, got_ip_remote;
|
||||
char iplocalport[NI_MAXHOST + NI_MAXSERV];
|
||||
char ipremoteport[NI_MAXHOST + NI_MAXSERV];
|
||||
|
||||
void *context;
|
||||
sasl_out_params_t oparams;
|
||||
|
||||
sasl_security_properties_t props;
|
||||
_sasl_external_properties_t external;
|
||||
|
||||
sasl_secret_t *secret;
|
||||
|
||||
int (*idle_hook)(sasl_conn_t *conn);
|
||||
const sasl_callback_t *callbacks;
|
||||
const sasl_global_callbacks_t *global_callbacks; /* global callbacks
|
||||
* connection */
|
||||
char *serverFQDN;
|
||||
|
||||
/* Pointers to memory that we are responsible for */
|
||||
buffer_info_t *encode_buf;
|
||||
|
||||
int error_code;
|
||||
char *error_buf, *errdetail_buf;
|
||||
size_t error_buf_len, errdetail_buf_len;
|
||||
char *mechlist_buf;
|
||||
size_t mechlist_buf_len;
|
||||
|
||||
char *decode_buf;
|
||||
|
||||
char user_buf[CANON_BUF_SIZE+1], authid_buf[CANON_BUF_SIZE+1];
|
||||
|
||||
/* Allocated by sasl_encodev if the output contains multiple SASL packet. */
|
||||
buffer_info_t multipacket_encoded_data;
|
||||
};
|
||||
|
||||
/* Server Conn Type Information */
|
||||
|
||||
typedef struct mechanism
|
||||
{
|
||||
server_sasl_mechanism_t m;
|
||||
struct mechanism *next;
|
||||
} mechanism_t;
|
||||
|
||||
typedef struct mech_list {
|
||||
const sasl_utils_t *utils; /* gotten from plug_init */
|
||||
|
||||
void *mutex; /* mutex for this data */
|
||||
mechanism_t *mech_list; /* list of loaded mechanisms */
|
||||
int mech_length; /* number of loaded mechanisms */
|
||||
} mech_list_t;
|
||||
|
||||
typedef struct context_list
|
||||
{
|
||||
mechanism_t *mech;
|
||||
void *context; /* if NULL, this mech is disabled for this connection
|
||||
* otherwise, use this context instead of a call
|
||||
* to mech_new */
|
||||
struct context_list *next;
|
||||
} context_list_t;
|
||||
|
||||
typedef struct sasl_server_conn {
|
||||
sasl_conn_t base; /* parts common to server + client */
|
||||
|
||||
char *appname; /* application name buffer (for sparams) */
|
||||
char *user_realm; /* domain the user authenticating is in */
|
||||
int sent_last; /* Have we already done the last send? */
|
||||
int authenticated;
|
||||
mechanism_t *mech; /* mechanism trying to use */
|
||||
sasl_server_params_t *sparams;
|
||||
context_list_t *mech_contexts;
|
||||
mechanism_t *mech_list; /* list of available mechanisms */
|
||||
int mech_length; /* number of available mechanisms */
|
||||
} sasl_server_conn_t;
|
||||
|
||||
/* Client Conn Type Information */
|
||||
|
||||
typedef struct cmechanism
|
||||
{
|
||||
client_sasl_mechanism_t m;
|
||||
struct cmechanism *next;
|
||||
} cmechanism_t;
|
||||
|
||||
typedef struct cmech_list {
|
||||
const sasl_utils_t *utils;
|
||||
|
||||
void *mutex; /* mutex for this data */
|
||||
cmechanism_t *mech_list; /* list of mechanisms */
|
||||
int mech_length; /* number of mechanisms */
|
||||
|
||||
} cmech_list_t;
|
||||
|
||||
typedef struct sasl_client_conn {
|
||||
sasl_conn_t base; /* parts common to server + client */
|
||||
|
||||
cmechanism_t *mech;
|
||||
sasl_client_params_t *cparams;
|
||||
|
||||
char *clientFQDN;
|
||||
|
||||
cmechanism_t *mech_list; /* list of available mechanisms */
|
||||
int mech_length; /* number of available mechanisms */
|
||||
} sasl_client_conn_t;
|
||||
|
||||
typedef struct sasl_allocation_utils {
|
||||
sasl_malloc_t *malloc;
|
||||
sasl_calloc_t *calloc;
|
||||
sasl_realloc_t *realloc;
|
||||
sasl_free_t *free;
|
||||
} sasl_allocation_utils_t;
|
||||
|
||||
typedef struct sasl_mutex_utils {
|
||||
sasl_mutex_alloc_t *alloc;
|
||||
sasl_mutex_lock_t *lock;
|
||||
sasl_mutex_unlock_t *unlock;
|
||||
sasl_mutex_free_t *free;
|
||||
} sasl_mutex_utils_t;
|
||||
|
||||
typedef struct sasl_log_utils_s {
|
||||
sasl_log_t *log;
|
||||
} sasl_log_utils_t;
|
||||
|
||||
typedef int sasl_plaintext_verifier(sasl_conn_t *conn,
|
||||
const char *userid,
|
||||
const char *passwd,
|
||||
const char *service,
|
||||
const char *user_realm);
|
||||
|
||||
struct sasl_verify_password_s {
|
||||
char *name;
|
||||
sasl_plaintext_verifier *verify;
|
||||
};
|
||||
|
||||
/*
|
||||
* globals & constants
|
||||
*/
|
||||
/*
|
||||
* common.c
|
||||
*/
|
||||
LIBSASL_API const sasl_utils_t *sasl_global_utils;
|
||||
|
||||
extern int (*_sasl_client_idle_hook)(sasl_conn_t *conn);
|
||||
extern int (*_sasl_server_idle_hook)(sasl_conn_t *conn);
|
||||
|
||||
/* These return SASL_OK if we've actually finished cleanup,
|
||||
* SASL_NOTINIT if that part of the library isn't initialized, and
|
||||
* SASL_CONTINUE if we need to call them again */
|
||||
extern int (*_sasl_client_cleanup_hook)(void);
|
||||
extern int (*_sasl_server_cleanup_hook)(void);
|
||||
|
||||
extern sasl_allocation_utils_t _sasl_allocation_utils;
|
||||
extern sasl_mutex_utils_t _sasl_mutex_utils;
|
||||
extern int _sasl_allocation_locked;
|
||||
|
||||
void sasl_common_done(void);
|
||||
|
||||
extern int _sasl_is_equal_mech(const char *req_mech,
|
||||
const char *plug_mech,
|
||||
size_t req_mech_len,
|
||||
int *plus);
|
||||
|
||||
/*
|
||||
* checkpw.c
|
||||
*/
|
||||
extern struct sasl_verify_password_s _sasl_verify_password[];
|
||||
|
||||
/*
|
||||
* server.c
|
||||
*/
|
||||
/* (this is a function call to ensure this is read-only to the outside) */
|
||||
extern int _is_sasl_server_active(void);
|
||||
|
||||
/*
|
||||
* Allocation and Mutex utility macros
|
||||
*/
|
||||
#define sasl_ALLOC(__size__) (_sasl_allocation_utils.malloc((__size__)))
|
||||
#define sasl_CALLOC(__nelem__, __size__) \
|
||||
(_sasl_allocation_utils.calloc((__nelem__), (__size__)))
|
||||
#define sasl_REALLOC(__ptr__, __size__) \
|
||||
(_sasl_allocation_utils.realloc((__ptr__), (__size__)))
|
||||
#define sasl_FREE(__ptr__) (_sasl_allocation_utils.free((__ptr__)))
|
||||
|
||||
#define sasl_MUTEX_ALLOC() (_sasl_mutex_utils.alloc())
|
||||
#define sasl_MUTEX_LOCK(__mutex__) (_sasl_mutex_utils.lock((__mutex__)))
|
||||
#define sasl_MUTEX_UNLOCK(__mutex__) (_sasl_mutex_utils.unlock((__mutex__)))
|
||||
#define sasl_MUTEX_FREE(__mutex__) \
|
||||
(_sasl_mutex_utils.free((__mutex__)))
|
||||
|
||||
/* function prototypes */
|
||||
/*
|
||||
* dlopen.c and staticopen.c
|
||||
*/
|
||||
/*
|
||||
* The differences here are:
|
||||
* _sasl_load_plugins loads all plugins from all files
|
||||
* _sasl_get_plugin loads the LIBRARY for an individual file
|
||||
* _sasl_done_with_plugins frees the LIBRARIES loaded by the above 2
|
||||
* _sasl_locate_entry locates an entrypoint in a given library
|
||||
*/
|
||||
extern int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
|
||||
const sasl_callback_t *getpath_callback,
|
||||
const sasl_callback_t *verifyfile_callback);
|
||||
extern int _sasl_get_plugin(const char *file,
|
||||
const sasl_callback_t *verifyfile_cb,
|
||||
void **libraryptr);
|
||||
extern int _sasl_locate_entry(void *library, const char *entryname,
|
||||
void **entry_point);
|
||||
extern int _sasl_done_with_plugins();
|
||||
|
||||
/*
|
||||
* common.c
|
||||
*/
|
||||
extern const sasl_callback_t *
|
||||
_sasl_find_getpath_callback(const sasl_callback_t *callbacks);
|
||||
|
||||
extern const sasl_callback_t *
|
||||
_sasl_find_getconfpath_callback(const sasl_callback_t *callbacks);
|
||||
|
||||
extern const sasl_callback_t *
|
||||
_sasl_find_verifyfile_callback(const sasl_callback_t *callbacks);
|
||||
|
||||
extern int _sasl_common_init(sasl_global_callbacks_t *global_callbacks);
|
||||
|
||||
extern int _sasl_conn_init(sasl_conn_t *conn,
|
||||
const char *service,
|
||||
unsigned int flags,
|
||||
enum Sasl_conn_type type,
|
||||
int (*idle_hook)(sasl_conn_t *conn),
|
||||
const char *serverFQDN,
|
||||
const char *iplocalport,
|
||||
const char *ipremoteport,
|
||||
const sasl_callback_t *callbacks,
|
||||
const sasl_global_callbacks_t *global_callbacks);
|
||||
extern void _sasl_conn_dispose(sasl_conn_t *conn);
|
||||
|
||||
extern sasl_utils_t *
|
||||
_sasl_alloc_utils(sasl_conn_t *conn,
|
||||
sasl_global_callbacks_t *global_callbacks);
|
||||
extern int _sasl_free_utils(const sasl_utils_t ** utils);
|
||||
|
||||
extern int
|
||||
_sasl_getcallback(sasl_conn_t * conn,
|
||||
unsigned long callbackid,
|
||||
sasl_callback_ft * pproc,
|
||||
void **pcontext);
|
||||
|
||||
extern void
|
||||
_sasl_log(sasl_conn_t *conn,
|
||||
int level,
|
||||
const char *fmt,
|
||||
...);
|
||||
|
||||
void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl);
|
||||
int _sasl_add_string(char **out, size_t *alloclen,
|
||||
size_t *outlen, const char *add);
|
||||
|
||||
/* More Generic Utilities in common.c */
|
||||
extern int _sasl_strdup(const char *in, char **out, size_t *outlen);
|
||||
|
||||
/* Basically a conditional call to realloc(), if we need more */
|
||||
int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen);
|
||||
|
||||
/* convert an iovec to a single buffer */
|
||||
int _iovec_to_buf(const struct iovec *vec,
|
||||
unsigned numiov, buffer_info_t **output);
|
||||
|
||||
/* Convert between string formats and sockaddr formats */
|
||||
int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen,
|
||||
char *out, unsigned outlen);
|
||||
int _sasl_ipfromstring(const char *addr, struct sockaddr *out,
|
||||
socklen_t outlen);
|
||||
|
||||
/*
|
||||
* external plugin (external.c)
|
||||
*/
|
||||
int external_client_plug_init(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_client_plug_t **pluglist,
|
||||
int *plugcount);
|
||||
int external_server_plug_init(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_server_plug_t **pluglist,
|
||||
int *plugcount);
|
||||
|
||||
/* Mech Listing Functions */
|
||||
int _sasl_build_mechlist(void);
|
||||
int _sasl_server_listmech(sasl_conn_t *conn,
|
||||
const char *user,
|
||||
const char *prefix,
|
||||
const char *sep,
|
||||
const char *suffix,
|
||||
const char **result,
|
||||
unsigned *plen,
|
||||
int *pcount);
|
||||
int _sasl_client_listmech(sasl_conn_t *conn,
|
||||
const char *prefix,
|
||||
const char *sep,
|
||||
const char *suffix,
|
||||
const char **result,
|
||||
unsigned *plen,
|
||||
int *pcount);
|
||||
/* Just create a straight list of them */
|
||||
sasl_string_list_t *_sasl_client_mechs(void);
|
||||
sasl_string_list_t *_sasl_server_mechs(void);
|
||||
|
||||
/*
|
||||
* config file declarations (config.c)
|
||||
*/
|
||||
extern const char *sasl_config_getstring(const char *key,const char *def);
|
||||
|
||||
/* checkpw.c */
|
||||
#ifdef DO_SASL_CHECKAPOP
|
||||
extern int _sasl_auxprop_verify_apop(sasl_conn_t *conn,
|
||||
const char *userstr,
|
||||
const char *challenge,
|
||||
const char *response,
|
||||
const char *user_realm);
|
||||
#endif /* DO_SASL_CHECKAPOP */
|
||||
|
||||
/* Auxprop Plugin (sasldb.c) */
|
||||
extern int sasldb_auxprop_plug_init(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_auxprop_plug_t **plug,
|
||||
const char *plugname);
|
||||
|
||||
/*
|
||||
* auxprop.c
|
||||
*/
|
||||
extern int _sasl_auxprop_add_plugin(void *p, void *library);
|
||||
extern void _sasl_auxprop_free(void);
|
||||
extern int _sasl_auxprop_lookup(sasl_server_params_t *sparams,
|
||||
unsigned flags,
|
||||
const char *user, unsigned ulen);
|
||||
|
||||
/*
|
||||
* canonusr.c
|
||||
*/
|
||||
void _sasl_canonuser_free();
|
||||
extern int internal_canonuser_init(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_canonuser_plug_t **plug,
|
||||
const char *plugname);
|
||||
extern int _sasl_canon_user(sasl_conn_t *conn,
|
||||
const char *user,
|
||||
unsigned ulen,
|
||||
unsigned flags,
|
||||
sasl_out_params_t *oparams);
|
||||
int _sasl_canon_user_lookup (sasl_conn_t *conn,
|
||||
const char *user,
|
||||
unsigned ulen,
|
||||
unsigned flags,
|
||||
sasl_out_params_t *oparams);
|
||||
|
||||
/*
|
||||
* saslutil.c
|
||||
*/
|
||||
int get_fqhostname(
|
||||
char *name,
|
||||
int namelen,
|
||||
int abort_if_no_fqdn
|
||||
);
|
||||
|
||||
#endif /* SASLINT_H */
|
||||
@@ -0,0 +1,812 @@
|
||||
/* saslutil.c
|
||||
* Rob Siemborski
|
||||
* Tim Martin
|
||||
* $Id: saslutil.c,v 1.52 2011/09/22 14:43:01 mel Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(WIN32)
|
||||
#define _CRT_RAND_S
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include "saslint.h"
|
||||
#include <saslutil.h>
|
||||
|
||||
/* Contains:
|
||||
*
|
||||
* sasl_decode64
|
||||
* sasl_encode64
|
||||
* sasl_mkchal
|
||||
* sasl_utf8verify
|
||||
* sasl_randcreate
|
||||
* sasl_randfree
|
||||
* sasl_randseed
|
||||
* sasl_rand
|
||||
* sasl_churn
|
||||
* sasl_erasebuffer
|
||||
*/
|
||||
|
||||
#ifdef sun
|
||||
/* gotta define gethostname ourselves on suns */
|
||||
extern int gethostname(char *, int);
|
||||
#endif
|
||||
|
||||
char *encode_table;
|
||||
char *decode_table;
|
||||
|
||||
#define RPOOL_SIZE 3
|
||||
struct sasl_rand_s {
|
||||
unsigned short pool[RPOOL_SIZE];
|
||||
/* since the init time might be really bad let's make this lazy */
|
||||
int initialized;
|
||||
};
|
||||
|
||||
#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
|
||||
|
||||
static char basis_64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????";
|
||||
|
||||
static char index_64[128] = {
|
||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
|
||||
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
|
||||
52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
|
||||
15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
|
||||
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
|
||||
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
|
||||
};
|
||||
|
||||
/* base64 encode
|
||||
* in -- input data
|
||||
* inlen -- input data length
|
||||
* out -- output buffer (will be NUL terminated)
|
||||
* outmax -- max size of output buffer
|
||||
* result:
|
||||
* outlen -- gets actual length of output buffer (optional)
|
||||
*
|
||||
* Returns SASL_OK on success, SASL_BUFOVER if result won't fit
|
||||
*/
|
||||
|
||||
int sasl_encode64(const char *_in,
|
||||
unsigned inlen,
|
||||
char *_out,
|
||||
unsigned outmax,
|
||||
unsigned *outlen)
|
||||
{
|
||||
const unsigned char *in = (const unsigned char *)_in;
|
||||
unsigned char *out = (unsigned char *)_out;
|
||||
unsigned char oval;
|
||||
char *blah;
|
||||
unsigned olen;
|
||||
|
||||
/* check params */
|
||||
if ((inlen > 0) && (in == NULL)) return SASL_BADPARAM;
|
||||
|
||||
/* Will it fit? */
|
||||
olen = (inlen + 2) / 3 * 4;
|
||||
if (outlen) {
|
||||
*outlen = olen;
|
||||
}
|
||||
if (outmax <= olen) {
|
||||
return SASL_BUFOVER;
|
||||
}
|
||||
|
||||
/* Do the work... */
|
||||
blah = (char *) out;
|
||||
while (inlen >= 3) {
|
||||
/* user provided max buffer size; make sure we don't go over it */
|
||||
*out++ = basis_64[in[0] >> 2];
|
||||
*out++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)];
|
||||
*out++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
|
||||
*out++ = basis_64[in[2] & 0x3f];
|
||||
in += 3;
|
||||
inlen -= 3;
|
||||
}
|
||||
if (inlen > 0) {
|
||||
/* user provided max buffer size; make sure we don't go over it */
|
||||
*out++ = basis_64[in[0] >> 2];
|
||||
oval = (in[0] << 4) & 0x30;
|
||||
if (inlen > 1) oval |= in[1] >> 4;
|
||||
*out++ = basis_64[oval];
|
||||
*out++ = (inlen < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c];
|
||||
*out++ = '=';
|
||||
}
|
||||
|
||||
*out = '\0';
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
/* base64 decode
|
||||
* in -- input data
|
||||
* inlen -- length of input data
|
||||
* out -- output data (may be same as in, must have enough space)
|
||||
* outmax -- max size of output buffer
|
||||
* result:
|
||||
* outlen -- actual output length
|
||||
*
|
||||
* returns:
|
||||
* SASL_BADPROT on bad base64,
|
||||
* SASL_BUFOVER if result won't fit,
|
||||
* SASL_CONTINUE on a partial block,
|
||||
* SASL_OK on success
|
||||
*/
|
||||
|
||||
int sasl_decode64(const char *in,
|
||||
unsigned inlen,
|
||||
char *out,
|
||||
unsigned outmax, /* size of the buffer, not counting the NUL */
|
||||
unsigned *outlen)
|
||||
{
|
||||
unsigned len = 0;
|
||||
unsigned j;
|
||||
int c[4];
|
||||
int saw_equal = 0;
|
||||
|
||||
/* check parameters */
|
||||
if (out == NULL) return SASL_FAIL;
|
||||
|
||||
if (inlen > 0 && *in == '\r') return SASL_FAIL;
|
||||
|
||||
while (inlen > 3) {
|
||||
/* No data is valid after an '=' character */
|
||||
if (saw_equal) {
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
for (j = 0; j < 4; j++) {
|
||||
c[j] = in[0];
|
||||
in++;
|
||||
inlen--;
|
||||
}
|
||||
|
||||
if (CHAR64(c[0]) == -1 || CHAR64(c[1]) == -1) return SASL_BADPROT;
|
||||
if (c[2] != '=' && CHAR64(c[2]) == -1) return SASL_BADPROT;
|
||||
if (c[3] != '=' && CHAR64(c[3]) == -1) return SASL_BADPROT;
|
||||
/* No data is valid after a '=' character, unless it is another '=' */
|
||||
if (c[2] == '=' && c[3] != '=') return SASL_BADPROT;
|
||||
if (c[2] == '=' || c[3] == '=') {
|
||||
saw_equal = 1;
|
||||
}
|
||||
|
||||
*out++ = (CHAR64(c[0]) << 2) | (CHAR64(c[1]) >> 4);
|
||||
if (++len >= outmax) return SASL_BUFOVER;
|
||||
if (c[2] != '=') {
|
||||
*out++ = ((CHAR64(c[1]) << 4) & 0xf0) | (CHAR64(c[2]) >> 2);
|
||||
if (++len >= outmax) return SASL_BUFOVER;
|
||||
if (c[3] != '=') {
|
||||
*out++ = ((CHAR64(c[2]) << 6) & 0xc0) | CHAR64(c[3]);
|
||||
if (++len >= outmax) return SASL_BUFOVER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*out = '\0'; /* NUL terminate the output string */
|
||||
|
||||
if (outlen) *outlen = len;
|
||||
|
||||
if (inlen != 0) {
|
||||
if (saw_equal) {
|
||||
/* Unless there is CRLF at the end? */
|
||||
return SASL_BADPROT;
|
||||
} else {
|
||||
return (SASL_CONTINUE);
|
||||
}
|
||||
}
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
/* make a challenge string (NUL terminated)
|
||||
* buf -- buffer for result
|
||||
* maxlen -- max length of result
|
||||
* hostflag -- 0 = don't include hostname, 1 = include hostname
|
||||
* returns final length or 0 if not enough space
|
||||
*/
|
||||
|
||||
int sasl_mkchal(sasl_conn_t *conn,
|
||||
char *buf,
|
||||
unsigned maxlen,
|
||||
unsigned hostflag)
|
||||
{
|
||||
sasl_rand_t *pool = NULL;
|
||||
unsigned long randnum;
|
||||
int ret;
|
||||
time_t now;
|
||||
unsigned len;
|
||||
|
||||
len = 4 /* <.>\0 */
|
||||
+ (2 * 20); /* 2 numbers, 20 => max size of 64bit
|
||||
* ulong in base 10 */
|
||||
if (hostflag && conn->serverFQDN)
|
||||
len += (unsigned) strlen(conn->serverFQDN) + 1 /* for the @ */;
|
||||
|
||||
if (maxlen < len)
|
||||
return 0;
|
||||
|
||||
ret = sasl_randcreate(&pool);
|
||||
if(ret != SASL_OK) return 0; /* xxx sasl return code? */
|
||||
|
||||
sasl_rand(pool, (char *)&randnum, sizeof(randnum));
|
||||
sasl_randfree(&pool);
|
||||
|
||||
time(&now);
|
||||
|
||||
if (hostflag && conn->serverFQDN)
|
||||
snprintf(buf,maxlen, "<%lu.%lu@%s>", randnum, now, conn->serverFQDN);
|
||||
else
|
||||
snprintf(buf,maxlen, "<%lu.%lu>", randnum, now);
|
||||
|
||||
return (int) strlen(buf);
|
||||
}
|
||||
|
||||
/* borrowed from larry. probably works :)
|
||||
* probably is also in acap server somewhere
|
||||
*/
|
||||
int sasl_utf8verify(const char *str, unsigned len)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < len; i++) {
|
||||
/* how many octets? */
|
||||
int seqlen = 0;
|
||||
while (str[i] & (0x80 >> seqlen)) ++seqlen;
|
||||
if (seqlen == 0) continue; /* this is a valid US-ASCII char */
|
||||
if (seqlen == 1) return SASL_BADPROT; /* this shouldn't happen here */
|
||||
if (seqlen > 6) return SASL_BADPROT; /* illegal */
|
||||
while (--seqlen)
|
||||
if ((str[++i] & 0xC0) != 0xF0) return SASL_BADPROT; /* needed a 10 octet */
|
||||
}
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* To see why this is really bad see RFC 1750
|
||||
*
|
||||
* unfortunatly there currently is no way to make
|
||||
* cryptographically secure pseudo random numbers
|
||||
* without specialized hardware etc...
|
||||
* thus, this is for nonce use only
|
||||
*/
|
||||
void getranddata(unsigned short ret[RPOOL_SIZE])
|
||||
{
|
||||
long curtime;
|
||||
|
||||
memset(ret, 0, RPOOL_SIZE*sizeof(unsigned short));
|
||||
|
||||
#ifdef DEV_RANDOM
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(DEV_RANDOM, O_RDONLY);
|
||||
if(fd != -1) {
|
||||
unsigned char *buf = (unsigned char *)ret;
|
||||
ssize_t bytesread = 0;
|
||||
size_t bytesleft = RPOOL_SIZE*sizeof(unsigned short);
|
||||
|
||||
do {
|
||||
bytesread = read(fd, buf, bytesleft);
|
||||
if(bytesread == -1 && errno == EINTR) continue;
|
||||
else if(bytesread <= 0) break;
|
||||
bytesleft -= bytesread;
|
||||
buf += bytesread;
|
||||
} while(bytesleft != 0);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETPID
|
||||
ret[0] ^= (unsigned short) getpid();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
/* xxx autoconf macro */
|
||||
#ifdef _SVID_GETTOD
|
||||
if (!gettimeofday(&tv))
|
||||
#else
|
||||
if (!gettimeofday(&tv, NULL))
|
||||
#endif
|
||||
{
|
||||
/* longs are guaranteed to be at least 32 bits; we need
|
||||
16 bits in each short */
|
||||
ret[0] ^= (unsigned short) (tv.tv_sec & 0xFFFF);
|
||||
ret[1] ^= (unsigned short) (clock() & 0xFFFF);
|
||||
ret[1] ^= (unsigned short) (tv.tv_usec >> 16);
|
||||
ret[2] ^= (unsigned short) (tv.tv_usec & 0xFFFF);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_GETTIMEOFDAY */
|
||||
|
||||
/* if all else fails just use time() */
|
||||
curtime = (long) time(NULL); /* better be at least 32 bits */
|
||||
|
||||
ret[0] ^= (unsigned short) (curtime >> 16);
|
||||
ret[1] ^= (unsigned short) (curtime & 0xFFFF);
|
||||
ret[2] ^= (unsigned short) (clock() & 0xFFFF);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int sasl_randcreate(sasl_rand_t **rpool)
|
||||
{
|
||||
(*rpool)=sasl_ALLOC(sizeof(sasl_rand_t));
|
||||
if ((*rpool) == NULL) return SASL_NOMEM;
|
||||
|
||||
/* init is lazy */
|
||||
(*rpool)->initialized = 0;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
void sasl_randfree(sasl_rand_t **rpool)
|
||||
{
|
||||
sasl_FREE(*rpool);
|
||||
}
|
||||
|
||||
void sasl_randseed (sasl_rand_t *rpool, const char *seed, unsigned len)
|
||||
{
|
||||
/* is it acceptable to just use the 1st 3 char's given??? */
|
||||
unsigned int lup;
|
||||
|
||||
/* check params */
|
||||
if (seed == NULL) return;
|
||||
if (rpool == NULL) return;
|
||||
|
||||
rpool->initialized = 1;
|
||||
|
||||
if (len > sizeof(unsigned short)*RPOOL_SIZE)
|
||||
len = sizeof(unsigned short)*RPOOL_SIZE;
|
||||
|
||||
for (lup = 0; lup < len; lup += 2)
|
||||
rpool->pool[lup/2] = (seed[lup] << 8) + seed[lup + 1];
|
||||
}
|
||||
|
||||
static void randinit(sasl_rand_t *rpool)
|
||||
{
|
||||
if (!rpool) return;
|
||||
|
||||
if (!rpool->initialized) {
|
||||
getranddata(rpool->pool);
|
||||
rpool->initialized = 1;
|
||||
#if !(defined(WIN32)||defined(macintosh))
|
||||
#ifndef HAVE_JRAND48
|
||||
{
|
||||
/* xxx varies by platform */
|
||||
unsigned int *foo = (unsigned int *)rpool->pool;
|
||||
srandom(*foo);
|
||||
}
|
||||
#endif /* HAVE_JRAND48 */
|
||||
#elif defined(WIN32)
|
||||
{
|
||||
unsigned int *foo = (unsigned int *)rpool->pool;
|
||||
srand(*foo);
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void sasl_rand (sasl_rand_t *rpool, char *buf, unsigned len)
|
||||
{
|
||||
unsigned int lup;
|
||||
#if defined(WIN32) && !defined(__MINGW32__)
|
||||
unsigned int randomValue;
|
||||
#endif
|
||||
|
||||
/* check params */
|
||||
if (!rpool || !buf) return;
|
||||
|
||||
/* init if necessary */
|
||||
randinit(rpool);
|
||||
|
||||
for (lup = 0; lup < len; lup++) {
|
||||
#if defined(__MINGW32__)
|
||||
buf[lup] = (char) (rand() >> 8);
|
||||
#elif defined(WIN32)
|
||||
if (rand_s(&randomValue) != 0) {
|
||||
randomValue = rand();
|
||||
}
|
||||
|
||||
buf[lup] = (char) (randomValue >> 8);
|
||||
#elif defined(macintosh)
|
||||
buf[lup] = (char) (rand() >> 8);
|
||||
#else /* !WIN32 && !macintosh */
|
||||
#ifdef HAVE_JRAND48
|
||||
buf[lup] = (char) (jrand48(rpool->pool) >> 8);
|
||||
#else
|
||||
buf[lup] = (char) (random() >> 8);
|
||||
#endif /* HAVE_JRAND48 */
|
||||
#endif /* WIN32 */
|
||||
}
|
||||
}
|
||||
|
||||
/* this function is just a bad idea all around, since we're not trying to
|
||||
implement a true random number generator */
|
||||
void sasl_churn (sasl_rand_t *rpool, const char *data, unsigned len)
|
||||
{
|
||||
unsigned int lup;
|
||||
|
||||
/* check params */
|
||||
if (!rpool || !data) return;
|
||||
|
||||
/* init if necessary */
|
||||
randinit(rpool);
|
||||
|
||||
for (lup=0; lup<len; lup++)
|
||||
rpool->pool[lup % RPOOL_SIZE] ^= data[lup];
|
||||
}
|
||||
|
||||
void sasl_erasebuffer(char *buf, unsigned len) {
|
||||
memset(buf, 0, len);
|
||||
}
|
||||
|
||||
/* Lowercase string in place */
|
||||
char *sasl_strlower (
|
||||
char *val
|
||||
)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (val == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* don't use tolower(), as it is locale dependent */
|
||||
|
||||
for (i = 0; val[i] != '\0'; i++) {
|
||||
if (val[i] >= 'A' && val[i] <= 'Z') {
|
||||
val[i] = val[i] - 'A' + 'a';
|
||||
}
|
||||
}
|
||||
|
||||
return (val);
|
||||
}
|
||||
|
||||
/* A version of gethostname that tries hard to return a FQDN */
|
||||
int get_fqhostname(
|
||||
char *name,
|
||||
int namelen,
|
||||
int abort_if_no_fqdn
|
||||
)
|
||||
{
|
||||
int return_value;
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result;
|
||||
|
||||
return_value = gethostname (name, namelen);
|
||||
if (return_value != 0) {
|
||||
return (return_value);
|
||||
}
|
||||
|
||||
if (strchr (name, '.') != NULL) {
|
||||
goto LOWERCASE;
|
||||
}
|
||||
|
||||
/* gethostname hasn't returned a FQDN, we have to canonify it ourselves */
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_socktype = SOCK_STREAM; /* TCP only */
|
||||
/* A value of zero for ai_protocol indicates the caller will accept any protocol. or IPPROTO_TCP? */
|
||||
hints.ai_protocol = 0; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
|
||||
hints.ai_addrlen = 0;
|
||||
hints.ai_canonname = NULL;
|
||||
hints.ai_addr = NULL;
|
||||
hints.ai_next = NULL;
|
||||
|
||||
if (getaddrinfo(name,
|
||||
NULL, /* don't care abour service/port */
|
||||
&hints,
|
||||
&result) != 0) {
|
||||
if (abort_if_no_fqdn) {
|
||||
/* errno on Unix, WSASetLastError on Windows are already done by the function */
|
||||
return (-1);
|
||||
} else {
|
||||
goto LOWERCASE;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == NULL || result->ai_canonname == NULL) {
|
||||
freeaddrinfo (result);
|
||||
if (abort_if_no_fqdn) {
|
||||
#ifdef WIN32
|
||||
WSASetLastError (WSANO_DATA);
|
||||
#elif defined(ENODATA)
|
||||
errno = ENODATA;
|
||||
#elif defined(EADDRNOTAVAIL)
|
||||
errno = EADDRNOTAVAIL;
|
||||
#endif
|
||||
return (-1);
|
||||
} else {
|
||||
goto LOWERCASE;
|
||||
}
|
||||
}
|
||||
|
||||
if (strchr (result->ai_canonname, '.') == NULL) {
|
||||
freeaddrinfo (result);
|
||||
if (abort_if_no_fqdn) {
|
||||
#ifdef WIN32
|
||||
WSASetLastError (WSANO_DATA);
|
||||
#elif defined(ENODATA)
|
||||
errno = ENODATA;
|
||||
#elif defined(EADDRNOTAVAIL)
|
||||
errno = EADDRNOTAVAIL;
|
||||
#endif
|
||||
return (-1);
|
||||
} else {
|
||||
goto LOWERCASE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Do we need to check for buffer overflow and set errno? */
|
||||
strncpy (name, result->ai_canonname, namelen);
|
||||
freeaddrinfo (result);
|
||||
|
||||
LOWERCASE:
|
||||
sasl_strlower (name);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
/*****************************************************************************
|
||||
*
|
||||
* MODULE NAME : GETOPT.C
|
||||
*
|
||||
* COPYRIGHTS:
|
||||
* This module contains code made available by IBM
|
||||
* Corporation on an AS IS basis. Any one receiving the
|
||||
* module is considered to be licensed under IBM copyrights
|
||||
* to use the IBM-provided source code in any way he or she
|
||||
* deems fit, including copying it, compiling it, modifying
|
||||
* it, and redistributing it, with or without
|
||||
* modifications. No license under any IBM patents or
|
||||
* patent applications is to be implied from this copyright
|
||||
* license.
|
||||
*
|
||||
* A user of the module should understand that IBM cannot
|
||||
* provide technical support for the module and will not be
|
||||
* responsible for any consequences of use of the program.
|
||||
*
|
||||
* Any notices, including this one, are not to be removed
|
||||
* from the module without the prior written consent of
|
||||
* IBM.
|
||||
*
|
||||
* AUTHOR: Original author:
|
||||
* G. R. Blair (BOBBLAIR at AUSVM1)
|
||||
* Internet: bobblair@bobblair.austin.ibm.com
|
||||
*
|
||||
* Extensively revised by:
|
||||
* John Q. Walker II, Ph.D. (JOHHQ at RALVM6)
|
||||
* Internet: johnq@ralvm6.vnet.ibm.com
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* getopt()
|
||||
*
|
||||
* The getopt() function is a command line parser. It returns the next
|
||||
* option character in argv that matches an option character in opstring.
|
||||
*
|
||||
* The argv argument points to an array of argc+1 elements containing argc
|
||||
* pointers to character strings followed by a null pointer.
|
||||
*
|
||||
* The opstring argument points to a string of option characters; if an
|
||||
* option character is followed by a colon, the option is expected to have
|
||||
* an argument that may or may not be separated from it by white space.
|
||||
* The external variable optarg is set to point to the start of the option
|
||||
* argument on return from getopt().
|
||||
*
|
||||
* The getopt() function places in optind the argv index of the next argument
|
||||
* to be processed. The system initializes the external variable optind to
|
||||
* 1 before the first call to getopt().
|
||||
*
|
||||
* When all options have been processed (that is, up to the first nonoption
|
||||
* argument), getopt() returns EOF. The special option "--" may be used to
|
||||
* delimit the end of the options; EOF will be returned, and "--" will be
|
||||
* skipped.
|
||||
*
|
||||
* The getopt() function returns a question mark (?) when it encounters an
|
||||
* option character not included in opstring. This error message can be
|
||||
* disabled by setting opterr to zero. Otherwise, it returns the option
|
||||
* character that was detected.
|
||||
*
|
||||
* If the special option "--" is detected, or all options have been
|
||||
* processed, EOF is returned.
|
||||
*
|
||||
* Options are marked by either a minus sign (-) or a slash (/).
|
||||
*
|
||||
* No errors are defined.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h> /* for strchr() */
|
||||
|
||||
/* static (global) variables that are specified as exported by getopt() */
|
||||
__declspec(dllexport) char *optarg = NULL; /* pointer to the start of the option argument */
|
||||
__declspec(dllexport) int optind = 1; /* number of the next argv[] to be evaluated */
|
||||
__declspec(dllexport) int opterr = 1; /* non-zero if a question mark should be returned */
|
||||
|
||||
|
||||
/* handle possible future character set concerns by putting this in a macro */
|
||||
#define _next_char(string) (char)(*(string+1))
|
||||
|
||||
int getopt(int argc, char *argv[], char *opstring)
|
||||
{
|
||||
static char *pIndexPosition = NULL; /* place inside current argv string */
|
||||
char *pArgString = NULL; /* where to start from next */
|
||||
char *pOptString; /* the string in our program */
|
||||
|
||||
|
||||
if (pIndexPosition != NULL) {
|
||||
/* we last left off inside an argv string */
|
||||
if (*(++pIndexPosition)) {
|
||||
/* there is more to come in the most recent argv */
|
||||
pArgString = pIndexPosition;
|
||||
}
|
||||
}
|
||||
|
||||
if (pArgString == NULL) {
|
||||
/* we didn't leave off in the middle of an argv string */
|
||||
if (optind >= argc) {
|
||||
/* more command-line arguments than the argument count */
|
||||
pIndexPosition = NULL; /* not in the middle of anything */
|
||||
return EOF; /* used up all command-line arguments */
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
* If the next argv[] is not an option, there can be no more options.
|
||||
*-------------------------------------------------------------------*/
|
||||
pArgString = argv[optind++]; /* set this to the next argument ptr */
|
||||
|
||||
if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */
|
||||
('-' != *pArgString)) {
|
||||
--optind; /* point to current arg once we're done */
|
||||
optarg = NULL; /* no argument follows the option */
|
||||
pIndexPosition = NULL; /* not in the middle of anything */
|
||||
return EOF; /* used up all the command-line flags */
|
||||
}
|
||||
|
||||
/* check for special end-of-flags markers */
|
||||
if ((strcmp(pArgString, "-") == 0) ||
|
||||
(strcmp(pArgString, "--") == 0)) {
|
||||
optarg = NULL; /* no argument follows the option */
|
||||
pIndexPosition = NULL; /* not in the middle of anything */
|
||||
return EOF; /* encountered the special flag */
|
||||
}
|
||||
|
||||
pArgString++; /* look past the / or - */
|
||||
}
|
||||
|
||||
if (':' == *pArgString) { /* is it a colon? */
|
||||
/*---------------------------------------------------------------------
|
||||
* Rare case: if opterr is non-zero, return a question mark;
|
||||
* otherwise, just return the colon we're on.
|
||||
*-------------------------------------------------------------------*/
|
||||
return (opterr ? (int)'?' : (int)':');
|
||||
}
|
||||
else if ((pOptString = strchr(opstring, *pArgString)) == 0) {
|
||||
/*---------------------------------------------------------------------
|
||||
* The letter on the command-line wasn't any good.
|
||||
*-------------------------------------------------------------------*/
|
||||
optarg = NULL; /* no argument follows the option */
|
||||
pIndexPosition = NULL; /* not in the middle of anything */
|
||||
return (opterr ? (int)'?' : (int)*pArgString);
|
||||
}
|
||||
else {
|
||||
/*---------------------------------------------------------------------
|
||||
* The letter on the command-line matches one we expect to see
|
||||
*-------------------------------------------------------------------*/
|
||||
if (':' == _next_char(pOptString)) { /* is the next letter a colon? */
|
||||
/* It is a colon. Look for an argument string. */
|
||||
if ('\0' != _next_char(pArgString)) { /* argument in this argv? */
|
||||
optarg = &pArgString[1]; /* Yes, it is */
|
||||
}
|
||||
else {
|
||||
/*-------------------------------------------------------------
|
||||
* The argument string must be in the next argv.
|
||||
* But, what if there is none (bad input from the user)?
|
||||
* In that case, return the letter, and optarg as NULL.
|
||||
*-----------------------------------------------------------*/
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else {
|
||||
optarg = NULL;
|
||||
return (opterr ? (int)'?' : (int)*pArgString);
|
||||
}
|
||||
}
|
||||
pIndexPosition = NULL; /* not in the middle of anything */
|
||||
}
|
||||
else {
|
||||
/* it's not a colon, so just return the letter */
|
||||
optarg = NULL; /* no argument follows the option */
|
||||
pIndexPosition = pArgString; /* point to the letter we're on */
|
||||
}
|
||||
return (int)*pArgString; /* return the letter that matched */
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PASSWORD_MAX
|
||||
# define PASSWORD_MAX 255
|
||||
#endif
|
||||
|
||||
#include <conio.h>
|
||||
char *
|
||||
getpass(prompt)
|
||||
const char *prompt;
|
||||
{
|
||||
register char *p;
|
||||
register int c;
|
||||
static char pbuf[PASSWORD_MAX];
|
||||
|
||||
fprintf(stderr, "%s", prompt); (void) fflush(stderr);
|
||||
for (p=pbuf; (c = _getch())!=13 && c!=EOF;) {
|
||||
if (p < &pbuf[sizeof(pbuf)-1])
|
||||
*p++ = (char) c;
|
||||
}
|
||||
*p = '\0';
|
||||
fprintf(stderr, "\n"); (void) fflush(stderr);
|
||||
return(pbuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* WIN32 */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,263 @@
|
||||
/* seterror.c - sasl_seterror split out because glue libraries
|
||||
* can't pass varargs lists
|
||||
* Rob Siemborski
|
||||
* Tim Martin
|
||||
* split from common.c by Rolf Braun
|
||||
* $Id: seterror.c,v 1.10 2011/09/01 14:12:53 mel Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#ifdef HAVE_SYSLOG
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslutil.h>
|
||||
#include <saslplug.h>
|
||||
#include "saslint.h"
|
||||
|
||||
#ifdef WIN32
|
||||
/* need to handle the fact that errno has been defined as a function
|
||||
in a dll, not an extern int */
|
||||
# ifdef errno
|
||||
# undef errno
|
||||
# endif /* errno */
|
||||
#endif /* WIN32 */
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* this is apparently no longer a user function */
|
||||
static int _sasl_seterror_usererr(int saslerr)
|
||||
{
|
||||
/* Hide the difference in a username failure and a password failure */
|
||||
if (saslerr == SASL_NOUSER)
|
||||
return SASL_BADAUTH;
|
||||
|
||||
/* otherwise return the error given; no transform necessary */
|
||||
return saslerr;
|
||||
}
|
||||
|
||||
/* set the error string which will be returned by sasl_errdetail() using
|
||||
* syslog()-style formatting (e.g. printf-style with %m as the string form
|
||||
* of an errno error)
|
||||
*
|
||||
* primarily for use by server callbacks such as the sasl_authorize_t
|
||||
* callback and internally to plug-ins
|
||||
*
|
||||
* This will also trigger a call to the SASL logging callback (if any)
|
||||
* with a level of SASL_LOG_FAIL unless the SASL_NOLOG flag is set.
|
||||
*
|
||||
* Messages should be sensitive to the current language setting. If there
|
||||
* is no SASL_CB_LANGUAGE callback messages MUST be US-ASCII otherwise UTF-8
|
||||
* is used and use of RFC 2482 for mixed-language text is encouraged.
|
||||
*
|
||||
* if conn is NULL, function does nothing
|
||||
*/
|
||||
void sasl_seterror(sasl_conn_t *conn,
|
||||
unsigned flags,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
size_t outlen=0; /* current length of output buffer */
|
||||
size_t pos = 0; /* current position in format string */
|
||||
size_t formatlen;
|
||||
int result;
|
||||
sasl_log_t *log_cb = NULL;
|
||||
void *log_ctx;
|
||||
int ival;
|
||||
char *cval;
|
||||
va_list ap; /* varargs thing */
|
||||
char **error_buf;
|
||||
size_t *error_buf_len;
|
||||
|
||||
if(!conn) {
|
||||
#ifndef SASL_OSX_CFMGLUE
|
||||
if(!(flags & SASL_NOLOG)) {
|
||||
/* See if we have a logging callback... */
|
||||
result = _sasl_getcallback(NULL, SASL_CB_LOG, (sasl_callback_ft *)&log_cb, &log_ctx);
|
||||
if (result == SASL_OK && ! log_cb)
|
||||
result = SASL_FAIL;
|
||||
if (result != SASL_OK)
|
||||
return;
|
||||
|
||||
log_cb(log_ctx, SASL_LOG_FAIL,
|
||||
"No sasl_conn_t passed to sasl_seterror");
|
||||
}
|
||||
#endif /* SASL_OSX_CFMGLUE */
|
||||
return;
|
||||
} else if(!fmt) return;
|
||||
|
||||
/* we need to use a back end function to get the buffer because the
|
||||
cfm glue can't be rooting around in the internal structs */
|
||||
_sasl_get_errorbuf(conn, &error_buf, &error_buf_len);
|
||||
|
||||
formatlen = strlen(fmt);
|
||||
|
||||
va_start(ap, fmt); /* start varargs */
|
||||
|
||||
while(pos<formatlen)
|
||||
{
|
||||
if (fmt[pos]!='%') /* regular character */
|
||||
{
|
||||
result = _buf_alloc(error_buf, error_buf_len, outlen+1);
|
||||
if (result != SASL_OK)
|
||||
return;
|
||||
(*error_buf)[outlen]=fmt[pos];
|
||||
outlen++;
|
||||
pos++;
|
||||
} else { /* formating thing */
|
||||
int done=0;
|
||||
char frmt[10];
|
||||
int frmtpos=1;
|
||||
char tempbuf[21];
|
||||
frmt[0]='%';
|
||||
pos++;
|
||||
|
||||
while (done==0)
|
||||
{
|
||||
switch(fmt[pos])
|
||||
{
|
||||
case 's': /* need to handle this */
|
||||
cval = va_arg(ap, char *); /* get the next arg */
|
||||
result = _sasl_add_string(error_buf, error_buf_len,
|
||||
&outlen, cval);
|
||||
|
||||
if (result != SASL_OK) /* add the string */
|
||||
return;
|
||||
|
||||
done=1;
|
||||
break;
|
||||
|
||||
case '%': /* double % output the '%' character */
|
||||
result = _buf_alloc(error_buf, error_buf_len, outlen+1);
|
||||
if (result != SASL_OK)
|
||||
return;
|
||||
(*error_buf)[outlen]='%';
|
||||
outlen++;
|
||||
done=1;
|
||||
break;
|
||||
|
||||
case 'm': /* insert the errno string */
|
||||
result = _sasl_add_string(error_buf, error_buf_len,
|
||||
&outlen,
|
||||
strerror(va_arg(ap, int)));
|
||||
if (result != SASL_OK)
|
||||
return;
|
||||
done=1;
|
||||
break;
|
||||
|
||||
case 'z': /* insert the sasl error string */
|
||||
result = _sasl_add_string(error_buf, error_buf_len, &outlen,
|
||||
(char *)sasl_errstring(_sasl_seterror_usererr(
|
||||
va_arg(ap, int)),NULL,NULL));
|
||||
if (result != SASL_OK)
|
||||
return;
|
||||
done=1;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
frmt[frmtpos++]=fmt[pos];
|
||||
frmt[frmtpos]=0;
|
||||
tempbuf[0] = (char) va_arg(ap, int); /* get the next arg */
|
||||
tempbuf[1]='\0';
|
||||
|
||||
/* now add the character */
|
||||
result = _sasl_add_string(error_buf, error_buf_len,
|
||||
&outlen, tempbuf);
|
||||
if (result != SASL_OK)
|
||||
return;
|
||||
done=1;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
frmt[frmtpos++]=fmt[pos];
|
||||
frmt[frmtpos]=0;
|
||||
ival = va_arg(ap, int); /* get the next arg */
|
||||
|
||||
snprintf(tempbuf,20,frmt,ival); /* have snprintf do the work */
|
||||
/* now add the string */
|
||||
result = _sasl_add_string(error_buf, error_buf_len,
|
||||
&outlen, tempbuf);
|
||||
if (result != SASL_OK)
|
||||
return;
|
||||
done=1;
|
||||
|
||||
break;
|
||||
default:
|
||||
frmt[frmtpos++]=fmt[pos]; /* add to the formating */
|
||||
frmt[frmtpos]=0;
|
||||
if (frmtpos>9)
|
||||
done=1;
|
||||
}
|
||||
pos++;
|
||||
if (pos>formatlen)
|
||||
done=1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
(*error_buf)[outlen]='\0'; /* put 0 at end */
|
||||
|
||||
va_end(ap);
|
||||
|
||||
#ifndef SASL_OSX_CFMGLUE
|
||||
if(!(flags & SASL_NOLOG)) {
|
||||
/* See if we have a logging callback... */
|
||||
result = _sasl_getcallback(conn, SASL_CB_LOG, (sasl_callback_ft *)&log_cb, &log_ctx);
|
||||
if (result == SASL_OK && ! log_cb)
|
||||
result = SASL_FAIL;
|
||||
if (result != SASL_OK)
|
||||
return;
|
||||
|
||||
result = log_cb(log_ctx, SASL_LOG_FAIL, conn->error_buf);
|
||||
}
|
||||
#endif /* SASL_OSX_CFMGLUE */
|
||||
}
|
||||
@@ -0,0 +1,784 @@
|
||||
/**************************************************************
|
||||
* Original:
|
||||
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
|
||||
* A bombproof version of doprnt (dopr) included.
|
||||
* Sigh. This sort of thing is always nasty do deal with. Note that
|
||||
* the version here does not include floating point...
|
||||
*
|
||||
* snprintf() is used instead of sprintf() as it does limit checks
|
||||
* for string length. This covers a nasty loophole.
|
||||
*
|
||||
* The other functions are there to prevent NULL pointers from
|
||||
* causing nast effects.
|
||||
*
|
||||
* More Recently:
|
||||
* Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
|
||||
* This was ugly. It is still ugly. I opted out of floating point
|
||||
* numbers, but the formatter understands just about everything
|
||||
* from the normal C string format, at least as far as I can tell from
|
||||
* the Solaris 2.5 printf(3S) man page.
|
||||
*
|
||||
* Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
|
||||
* Ok, added some minimal floating point support, which means this
|
||||
* probably requires libm on most operating systems. Don't yet
|
||||
* support the exponent (e,E) and sigfig (g,G). Also, fmtint()
|
||||
* was pretty badly broken, it just wasn't being exercised in ways
|
||||
* which showed it, so that's been fixed. Also, formated the code
|
||||
* to mutt conventions, and removed dead code left over from the
|
||||
* original. Also, there is now a builtin-test, just compile with:
|
||||
* gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
|
||||
* and run snprintf for results.
|
||||
*
|
||||
* Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
|
||||
* The PGP code was using unsigned hexadecimal formats.
|
||||
* Unfortunately, unsigned formats simply didn't work.
|
||||
*
|
||||
* Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
|
||||
* The original code assumed that both snprintf() and vsnprintf() were
|
||||
* missing. Some systems only have snprintf() but not vsnprintf(), so
|
||||
* the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
|
||||
*
|
||||
**************************************************************/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
|
||||
|
||||
#include <string.h>
|
||||
# include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* varargs declarations: */
|
||||
|
||||
#if defined(HAVE_STDARG_H)
|
||||
# include <stdarg.h>
|
||||
# define HAVE_STDARGS /* let's hope that works everywhere (mj) */
|
||||
# define VA_LOCAL_DECL va_list ap
|
||||
# define VA_START(f) va_start(ap, f)
|
||||
# define VA_SHIFT(v,t) ; /* no-op for ANSI */
|
||||
# define VA_END va_end(ap)
|
||||
#else
|
||||
# if defined(HAVE_VARARGS_H)
|
||||
# include <varargs.h>
|
||||
# undef HAVE_STDARGS
|
||||
# define VA_LOCAL_DECL va_list ap
|
||||
# define VA_START(f) va_start(ap) /* f is ignored! */
|
||||
# define VA_SHIFT(v,t) v = va_arg(ap,t)
|
||||
# define VA_END va_end(ap)
|
||||
# else
|
||||
/*XX ** NO VARARGS ** XX*/
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*int snprintf (char *str, size_t count, const char *fmt, ...);*/
|
||||
/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/
|
||||
|
||||
static void dopr (char *buffer, size_t maxlen, const char *format,
|
||||
va_list args);
|
||||
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
|
||||
char *value, int flags, int min, int max);
|
||||
static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
|
||||
long value, int base, int min, int max, int flags);
|
||||
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
|
||||
long double fvalue, int min, int max, int flags);
|
||||
static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
|
||||
|
||||
/*
|
||||
* dopr(): poor man's version of doprintf
|
||||
*/
|
||||
|
||||
/* format read states */
|
||||
#define DP_S_DEFAULT 0
|
||||
#define DP_S_FLAGS 1
|
||||
#define DP_S_MIN 2
|
||||
#define DP_S_DOT 3
|
||||
#define DP_S_MAX 4
|
||||
#define DP_S_MOD 5
|
||||
#define DP_S_CONV 6
|
||||
#define DP_S_DONE 7
|
||||
|
||||
/* format flags - Bits */
|
||||
#define DP_F_MINUS (1 << 0)
|
||||
#define DP_F_PLUS (1 << 1)
|
||||
#define DP_F_SPACE (1 << 2)
|
||||
#define DP_F_NUM (1 << 3)
|
||||
#define DP_F_ZERO (1 << 4)
|
||||
#define DP_F_UP (1 << 5)
|
||||
#define DP_F_UNSIGNED (1 << 6)
|
||||
|
||||
/* Conversion Flags */
|
||||
#define DP_C_SHORT 1
|
||||
#define DP_C_LONG 2
|
||||
#define DP_C_LDOUBLE 3
|
||||
|
||||
#define char_to_int(p) (p - '0')
|
||||
#define MAX(p,q) ((p >= q) ? p : q)
|
||||
|
||||
static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
|
||||
{
|
||||
char ch;
|
||||
long value;
|
||||
long double fvalue;
|
||||
char *strvalue;
|
||||
int min;
|
||||
int max;
|
||||
int state;
|
||||
int flags;
|
||||
int cflags;
|
||||
size_t currlen;
|
||||
|
||||
state = DP_S_DEFAULT;
|
||||
currlen = flags = cflags = min = 0;
|
||||
max = -1;
|
||||
ch = *format++;
|
||||
|
||||
while (state != DP_S_DONE)
|
||||
{
|
||||
if ((ch == '\0') || (currlen >= maxlen))
|
||||
state = DP_S_DONE;
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case DP_S_DEFAULT:
|
||||
if (ch == '%')
|
||||
state = DP_S_FLAGS;
|
||||
else
|
||||
dopr_outch (buffer, &currlen, maxlen, ch);
|
||||
ch = *format++;
|
||||
break;
|
||||
case DP_S_FLAGS:
|
||||
switch (ch)
|
||||
{
|
||||
case '-':
|
||||
flags |= DP_F_MINUS;
|
||||
ch = *format++;
|
||||
break;
|
||||
case '+':
|
||||
flags |= DP_F_PLUS;
|
||||
ch = *format++;
|
||||
break;
|
||||
case ' ':
|
||||
flags |= DP_F_SPACE;
|
||||
ch = *format++;
|
||||
break;
|
||||
case '#':
|
||||
flags |= DP_F_NUM;
|
||||
ch = *format++;
|
||||
break;
|
||||
case '0':
|
||||
flags |= DP_F_ZERO;
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
state = DP_S_MIN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case DP_S_MIN:
|
||||
if (isdigit((unsigned char)ch))
|
||||
{
|
||||
min = 10*min + char_to_int (ch);
|
||||
ch = *format++;
|
||||
}
|
||||
else if (ch == '*')
|
||||
{
|
||||
min = va_arg (args, int);
|
||||
ch = *format++;
|
||||
state = DP_S_DOT;
|
||||
}
|
||||
else
|
||||
state = DP_S_DOT;
|
||||
break;
|
||||
case DP_S_DOT:
|
||||
if (ch == '.')
|
||||
{
|
||||
state = DP_S_MAX;
|
||||
ch = *format++;
|
||||
}
|
||||
else
|
||||
state = DP_S_MOD;
|
||||
break;
|
||||
case DP_S_MAX:
|
||||
if (isdigit((unsigned char)ch))
|
||||
{
|
||||
if (max < 0)
|
||||
max = 0;
|
||||
max = 10*max + char_to_int (ch);
|
||||
ch = *format++;
|
||||
}
|
||||
else if (ch == '*')
|
||||
{
|
||||
max = va_arg (args, int);
|
||||
ch = *format++;
|
||||
state = DP_S_MOD;
|
||||
}
|
||||
else
|
||||
state = DP_S_MOD;
|
||||
break;
|
||||
case DP_S_MOD:
|
||||
/* Currently, we don't support Long Long, bummer */
|
||||
switch (ch)
|
||||
{
|
||||
case 'h':
|
||||
cflags = DP_C_SHORT;
|
||||
ch = *format++;
|
||||
break;
|
||||
case 'l':
|
||||
cflags = DP_C_LONG;
|
||||
ch = *format++;
|
||||
break;
|
||||
case 'L':
|
||||
cflags = DP_C_LDOUBLE;
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
state = DP_S_CONV;
|
||||
break;
|
||||
case DP_S_CONV:
|
||||
switch (ch)
|
||||
{
|
||||
case 'd':
|
||||
case 'i':
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg (args, short int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, long int);
|
||||
else
|
||||
value = va_arg (args, int);
|
||||
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||
break;
|
||||
case 'o':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg (args, unsigned short int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, unsigned long int);
|
||||
else
|
||||
value = va_arg (args, unsigned int);
|
||||
fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
|
||||
break;
|
||||
case 'u':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg (args, unsigned short int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, unsigned long int);
|
||||
else
|
||||
value = va_arg (args, unsigned int);
|
||||
fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
|
||||
break;
|
||||
case 'X':
|
||||
flags |= DP_F_UP;
|
||||
case 'x':
|
||||
flags |= DP_F_UNSIGNED;
|
||||
if (cflags == DP_C_SHORT)
|
||||
value = va_arg (args, unsigned short int);
|
||||
else if (cflags == DP_C_LONG)
|
||||
value = va_arg (args, unsigned long int);
|
||||
else
|
||||
value = va_arg (args, unsigned int);
|
||||
fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
|
||||
break;
|
||||
case 'f':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, long double);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
/* um, floating point? */
|
||||
fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
|
||||
break;
|
||||
case 'E':
|
||||
flags |= DP_F_UP;
|
||||
case 'e':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, long double);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
break;
|
||||
case 'G':
|
||||
flags |= DP_F_UP;
|
||||
case 'g':
|
||||
if (cflags == DP_C_LDOUBLE)
|
||||
fvalue = va_arg (args, long double);
|
||||
else
|
||||
fvalue = va_arg (args, double);
|
||||
break;
|
||||
case 'c':
|
||||
dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
|
||||
break;
|
||||
case 's':
|
||||
strvalue = va_arg (args, char *);
|
||||
if (max < 0)
|
||||
max = maxlen; /* ie, no max */
|
||||
fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
|
||||
break;
|
||||
case 'p':
|
||||
strvalue = va_arg (args, void *);
|
||||
fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
|
||||
break;
|
||||
case 'n':
|
||||
if (cflags == DP_C_SHORT)
|
||||
{
|
||||
short int *num;
|
||||
num = va_arg (args, short int *);
|
||||
*num = currlen;
|
||||
}
|
||||
else if (cflags == DP_C_LONG)
|
||||
{
|
||||
long int *num;
|
||||
num = va_arg (args, long int *);
|
||||
*num = currlen;
|
||||
}
|
||||
else
|
||||
{
|
||||
int *num;
|
||||
num = va_arg (args, int *);
|
||||
*num = currlen;
|
||||
}
|
||||
break;
|
||||
case '%':
|
||||
dopr_outch (buffer, &currlen, maxlen, ch);
|
||||
break;
|
||||
case 'w':
|
||||
/* not supported yet, treat as next char */
|
||||
ch = *format++;
|
||||
break;
|
||||
default:
|
||||
/* Unknown, skip */
|
||||
break;
|
||||
}
|
||||
ch = *format++;
|
||||
state = DP_S_DEFAULT;
|
||||
flags = cflags = min = 0;
|
||||
max = -1;
|
||||
break;
|
||||
case DP_S_DONE:
|
||||
break;
|
||||
default:
|
||||
/* hmm? */
|
||||
break; /* some picky compilers need this */
|
||||
}
|
||||
}
|
||||
if (currlen < maxlen - 1)
|
||||
buffer[currlen] = '\0';
|
||||
else
|
||||
buffer[maxlen - 1] = '\0';
|
||||
}
|
||||
|
||||
static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
|
||||
char *value, int flags, int min, int max)
|
||||
{
|
||||
int padlen, strln; /* amount to pad */
|
||||
int cnt = 0;
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
value = "<NULL>";
|
||||
}
|
||||
|
||||
for (strln = 0; value[strln]; ++strln); /* strlen */
|
||||
padlen = min - strln;
|
||||
if (padlen < 0)
|
||||
padlen = 0;
|
||||
if (flags & DP_F_MINUS)
|
||||
padlen = -padlen; /* Left Justify */
|
||||
|
||||
while ((padlen > 0) && (cnt < max))
|
||||
{
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
--padlen;
|
||||
++cnt;
|
||||
}
|
||||
while (*value && (cnt < max))
|
||||
{
|
||||
dopr_outch (buffer, currlen, maxlen, *value++);
|
||||
++cnt;
|
||||
}
|
||||
while ((padlen < 0) && (cnt < max))
|
||||
{
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
++padlen;
|
||||
++cnt;
|
||||
}
|
||||
}
|
||||
|
||||
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
|
||||
|
||||
static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
|
||||
long value, int base, int min, int max, int flags)
|
||||
{
|
||||
int signvalue = 0;
|
||||
unsigned long uvalue;
|
||||
char convert[20];
|
||||
int place = 0;
|
||||
int spadlen = 0; /* amount to space pad */
|
||||
int zpadlen = 0; /* amount to zero pad */
|
||||
int caps = 0;
|
||||
|
||||
if (max < 0)
|
||||
max = 0;
|
||||
|
||||
uvalue = value;
|
||||
|
||||
if(!(flags & DP_F_UNSIGNED))
|
||||
{
|
||||
if( value < 0 ) {
|
||||
signvalue = '-';
|
||||
uvalue = -value;
|
||||
}
|
||||
else
|
||||
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
|
||||
signvalue = '+';
|
||||
else
|
||||
if (flags & DP_F_SPACE)
|
||||
signvalue = ' ';
|
||||
}
|
||||
|
||||
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
|
||||
|
||||
do {
|
||||
convert[place++] =
|
||||
(caps? "0123456789ABCDEF":"0123456789abcdef")
|
||||
[uvalue % (unsigned)base ];
|
||||
uvalue = (uvalue / (unsigned)base );
|
||||
} while(uvalue && (place < 20));
|
||||
if (place == 20) place--;
|
||||
convert[place] = 0;
|
||||
|
||||
zpadlen = max - place;
|
||||
spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
|
||||
if (zpadlen < 0) zpadlen = 0;
|
||||
if (spadlen < 0) spadlen = 0;
|
||||
if (flags & DP_F_ZERO)
|
||||
{
|
||||
zpadlen = MAX(zpadlen, spadlen);
|
||||
spadlen = 0;
|
||||
}
|
||||
if (flags & DP_F_MINUS)
|
||||
spadlen = -spadlen; /* Left Justifty */
|
||||
|
||||
#ifdef DEBUG_SNPRINTF
|
||||
dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
|
||||
zpadlen, spadlen, min, max, place));
|
||||
#endif
|
||||
|
||||
/* Spaces */
|
||||
while (spadlen > 0)
|
||||
{
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
--spadlen;
|
||||
}
|
||||
|
||||
/* Sign */
|
||||
if (signvalue)
|
||||
dopr_outch (buffer, currlen, maxlen, signvalue);
|
||||
|
||||
/* Zeros */
|
||||
if (zpadlen > 0)
|
||||
{
|
||||
while (zpadlen > 0)
|
||||
{
|
||||
dopr_outch (buffer, currlen, maxlen, '0');
|
||||
--zpadlen;
|
||||
}
|
||||
}
|
||||
|
||||
/* Digits */
|
||||
while (place > 0)
|
||||
dopr_outch (buffer, currlen, maxlen, convert[--place]);
|
||||
|
||||
/* Left Justified spaces */
|
||||
while (spadlen < 0) {
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
++spadlen;
|
||||
}
|
||||
}
|
||||
|
||||
static long double abs_val (long double value)
|
||||
{
|
||||
long double result = value;
|
||||
|
||||
if (value < 0)
|
||||
result = -value;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static long double pow10 (int exp)
|
||||
{
|
||||
long double result = 1;
|
||||
|
||||
while (exp)
|
||||
{
|
||||
result *= 10;
|
||||
exp--;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static long round (long double value)
|
||||
{
|
||||
long intpart;
|
||||
|
||||
intpart = value;
|
||||
value = value - intpart;
|
||||
if (value >= 0.5)
|
||||
intpart++;
|
||||
|
||||
return intpart;
|
||||
}
|
||||
|
||||
static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
|
||||
long double fvalue, int min, int max, int flags)
|
||||
{
|
||||
int signvalue = 0;
|
||||
long double ufvalue;
|
||||
char iconvert[20];
|
||||
char fconvert[20];
|
||||
int iplace = 0;
|
||||
int fplace = 0;
|
||||
int padlen = 0; /* amount to pad */
|
||||
int zpadlen = 0;
|
||||
int caps = 0;
|
||||
long intpart;
|
||||
long fracpart;
|
||||
|
||||
/*
|
||||
* AIX manpage says the default is 0, but Solaris says the default
|
||||
* is 6, and sprintf on AIX defaults to 6
|
||||
*/
|
||||
if (max < 0)
|
||||
max = 6;
|
||||
|
||||
ufvalue = abs_val (fvalue);
|
||||
|
||||
if (fvalue < 0)
|
||||
signvalue = '-';
|
||||
else
|
||||
if (flags & DP_F_PLUS) /* Do a sign (+/i) */
|
||||
signvalue = '+';
|
||||
else
|
||||
if (flags & DP_F_SPACE)
|
||||
signvalue = ' ';
|
||||
|
||||
#if 0
|
||||
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
|
||||
#endif
|
||||
|
||||
intpart = ufvalue;
|
||||
|
||||
/*
|
||||
* Sorry, we only support 9 digits past the decimal because of our
|
||||
* conversion method
|
||||
*/
|
||||
if (max > 9)
|
||||
max = 9;
|
||||
|
||||
/* We "cheat" by converting the fractional part to integer by
|
||||
* multiplying by a factor of 10
|
||||
*/
|
||||
fracpart = round ((pow10 (max)) * (ufvalue - intpart));
|
||||
|
||||
if (fracpart >= pow10 (max))
|
||||
{
|
||||
intpart++;
|
||||
fracpart -= pow10 (max);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SNPRINTF
|
||||
dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
|
||||
#endif
|
||||
|
||||
/* Convert integer part */
|
||||
do {
|
||||
iconvert[iplace++] =
|
||||
(caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
|
||||
intpart = (intpart / 10);
|
||||
} while(intpart && (iplace < 20));
|
||||
if (iplace == 20) iplace--;
|
||||
iconvert[iplace] = 0;
|
||||
|
||||
/* Convert fractional part */
|
||||
do {
|
||||
fconvert[fplace++] =
|
||||
(caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
|
||||
fracpart = (fracpart / 10);
|
||||
} while(fracpart && (fplace < 20));
|
||||
if (fplace == 20) fplace--;
|
||||
fconvert[fplace] = 0;
|
||||
|
||||
/* -1 for decimal point, another -1 if we are printing a sign */
|
||||
padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
|
||||
zpadlen = max - fplace;
|
||||
if (zpadlen < 0)
|
||||
zpadlen = 0;
|
||||
if (padlen < 0)
|
||||
padlen = 0;
|
||||
if (flags & DP_F_MINUS)
|
||||
padlen = -padlen; /* Left Justifty */
|
||||
|
||||
if ((flags & DP_F_ZERO) && (padlen > 0))
|
||||
{
|
||||
if (signvalue)
|
||||
{
|
||||
dopr_outch (buffer, currlen, maxlen, signvalue);
|
||||
--padlen;
|
||||
signvalue = 0;
|
||||
}
|
||||
while (padlen > 0)
|
||||
{
|
||||
dopr_outch (buffer, currlen, maxlen, '0');
|
||||
--padlen;
|
||||
}
|
||||
}
|
||||
while (padlen > 0)
|
||||
{
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
--padlen;
|
||||
}
|
||||
if (signvalue)
|
||||
dopr_outch (buffer, currlen, maxlen, signvalue);
|
||||
|
||||
while (iplace > 0)
|
||||
dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
|
||||
|
||||
/*
|
||||
* Decimal point. This should probably use locale to find the correct
|
||||
* char to print out.
|
||||
*/
|
||||
dopr_outch (buffer, currlen, maxlen, '.');
|
||||
|
||||
while (fplace > 0)
|
||||
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
|
||||
|
||||
while (zpadlen > 0)
|
||||
{
|
||||
dopr_outch (buffer, currlen, maxlen, '0');
|
||||
--zpadlen;
|
||||
}
|
||||
|
||||
while (padlen < 0)
|
||||
{
|
||||
dopr_outch (buffer, currlen, maxlen, ' ');
|
||||
++padlen;
|
||||
}
|
||||
}
|
||||
|
||||
static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
|
||||
{
|
||||
if (*currlen < maxlen)
|
||||
buffer[(*currlen)++] = c;
|
||||
}
|
||||
#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
|
||||
|
||||
#ifndef HAVE_VSNPRINTF
|
||||
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
|
||||
{
|
||||
str[0] = 0;
|
||||
dopr(str, count, fmt, args);
|
||||
return(strlen(str));
|
||||
}
|
||||
#endif /* !HAVE_VSNPRINTF */
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
/* VARARGS3 */
|
||||
#ifdef HAVE_STDARGS
|
||||
int snprintf (char *str,size_t count,const char *fmt,...)
|
||||
#else
|
||||
int snprintf (va_alist) va_dcl
|
||||
#endif
|
||||
{
|
||||
#ifndef HAVE_STDARGS
|
||||
char *str;
|
||||
size_t count;
|
||||
char *fmt;
|
||||
#endif
|
||||
VA_LOCAL_DECL;
|
||||
|
||||
VA_START (fmt);
|
||||
VA_SHIFT (str, char *);
|
||||
VA_SHIFT (count, size_t );
|
||||
VA_SHIFT (fmt, char *);
|
||||
(void) vsnprintf(str, count, fmt, ap);
|
||||
VA_END;
|
||||
return(strlen(str));
|
||||
}
|
||||
|
||||
#ifdef TEST_SNPRINTF
|
||||
#ifndef LONG_STRING
|
||||
#define LONG_STRING 1024
|
||||
#endif
|
||||
int main (void)
|
||||
{
|
||||
char buf1[LONG_STRING];
|
||||
char buf2[LONG_STRING];
|
||||
char *fp_fmt[] = {
|
||||
"%-1.5f",
|
||||
"%1.5f",
|
||||
"%123.9f",
|
||||
"%10.5f",
|
||||
"% 10.5f",
|
||||
"%+22.9f",
|
||||
"%+4.9f",
|
||||
"%01.3f",
|
||||
"%4f",
|
||||
"%3.1f",
|
||||
"%3.2f",
|
||||
NULL
|
||||
};
|
||||
double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
|
||||
0.9996, 1.996, 4.136, 0};
|
||||
char *int_fmt[] = {
|
||||
"%-1.5d",
|
||||
"%1.5d",
|
||||
"%123.9d",
|
||||
"%5.5d",
|
||||
"%10.5d",
|
||||
"% 10.5d",
|
||||
"%+22.33d",
|
||||
"%01.3d",
|
||||
"%4d",
|
||||
NULL
|
||||
};
|
||||
long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
|
||||
int x, y;
|
||||
int fail = 0;
|
||||
int num = 0;
|
||||
|
||||
printf ("Testing snprintf format codes against system sprintf...\n");
|
||||
|
||||
for (x = 0; fp_fmt[x] != NULL ; x++)
|
||||
for (y = 0; fp_nums[y] != 0 ; y++)
|
||||
{
|
||||
snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
|
||||
sprintf (buf2, fp_fmt[x], fp_nums[y]);
|
||||
if (strcmp (buf1, buf2))
|
||||
{
|
||||
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
|
||||
fp_fmt[x], buf1, buf2);
|
||||
fail++;
|
||||
}
|
||||
num++;
|
||||
}
|
||||
|
||||
for (x = 0; int_fmt[x] != NULL ; x++)
|
||||
for (y = 0; int_nums[y] != 0 ; y++)
|
||||
{
|
||||
snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
|
||||
sprintf (buf2, int_fmt[x], int_nums[y]);
|
||||
if (strcmp (buf1, buf2))
|
||||
{
|
||||
printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n",
|
||||
int_fmt[x], buf1, buf2);
|
||||
fail++;
|
||||
}
|
||||
num++;
|
||||
}
|
||||
printf ("%d tests failed out of %d.\n", fail, num);
|
||||
}
|
||||
#endif /* SNPRINTF_TEST */
|
||||
|
||||
#endif /* !HAVE_SNPRINTF */
|
||||
@@ -0,0 +1,184 @@
|
||||
/* staticopen.h
|
||||
* Rob Siemborski
|
||||
* Howard Chu
|
||||
* $Id: staticopen.h,v 1.9 2011/04/05 14:50:07 mel Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN = 0, SERVER = 1, CLIENT = 2, AUXPROP = 3, CANONUSER = 4
|
||||
} _sasl_plug_type;
|
||||
|
||||
typedef struct {
|
||||
_sasl_plug_type type;
|
||||
char *name;
|
||||
sasl_client_plug_init_t *plug;
|
||||
} _sasl_plug_rec;
|
||||
|
||||
/* For static linking */
|
||||
#define SPECIFIC_CLIENT_PLUG_INIT_PROTO( x ) \
|
||||
sasl_client_plug_init_t x##_client_plug_init
|
||||
|
||||
#define SPECIFIC_SERVER_PLUG_INIT_PROTO( x ) \
|
||||
sasl_server_plug_init_t x##_server_plug_init
|
||||
|
||||
#define SPECIFIC_AUXPROP_PLUG_INIT_PROTO( x ) \
|
||||
sasl_auxprop_init_t x##_auxprop_plug_init
|
||||
|
||||
#define SPECIFIC_CANONUSER_PLUG_INIT_PROTO( x ) \
|
||||
sasl_canonuser_init_t x##_canonuser_plug_init
|
||||
|
||||
/* Static Compillation Foo */
|
||||
#define SPECIFIC_CLIENT_PLUG_INIT( x, n )\
|
||||
{ CLIENT, n, x##_client_plug_init }
|
||||
#define SPECIFIC_SERVER_PLUG_INIT( x, n )\
|
||||
{ SERVER, n, (sasl_client_plug_init_t *)x##_server_plug_init }
|
||||
#define SPECIFIC_AUXPROP_PLUG_INIT( x, n )\
|
||||
{ AUXPROP, n, (sasl_client_plug_init_t *)x##_auxprop_plug_init }
|
||||
#define SPECIFIC_CANONUSER_PLUG_INIT( x, n )\
|
||||
{ CANONUSER, n, (sasl_client_plug_init_t *)x##_canonuser_plug_init }
|
||||
|
||||
#ifdef STATIC_ANONYMOUS
|
||||
extern SPECIFIC_SERVER_PLUG_INIT_PROTO( anonymous );
|
||||
extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( anonymous );
|
||||
#endif
|
||||
#ifdef STATIC_CRAMMD5
|
||||
extern SPECIFIC_SERVER_PLUG_INIT_PROTO( crammd5 );
|
||||
extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( crammd5 );
|
||||
#endif
|
||||
#ifdef STATIC_DIGESTMD5
|
||||
extern SPECIFIC_SERVER_PLUG_INIT_PROTO( digestmd5 );
|
||||
extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( digestmd5 );
|
||||
#endif
|
||||
#ifdef STATIC_SCRAM
|
||||
extern SPECIFIC_SERVER_PLUG_INIT_PROTO( scram );
|
||||
extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( scram );
|
||||
#endif
|
||||
#ifdef STATIC_GSSAPIV2
|
||||
extern SPECIFIC_SERVER_PLUG_INIT_PROTO( gssapiv2 );
|
||||
extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( gssapiv2 );
|
||||
#endif
|
||||
#ifdef STATIC_KERBEROS4
|
||||
extern SPECIFIC_SERVER_PLUG_INIT_PROTO( kerberos4 );
|
||||
extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( kerberos4 );
|
||||
#endif
|
||||
#ifdef STATIC_LOGIN
|
||||
extern SPECIFIC_SERVER_PLUG_INIT_PROTO( login );
|
||||
extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( login );
|
||||
#endif
|
||||
#ifdef STATIC_NTLM
|
||||
extern SPECIFIC_SERVER_PLUG_INIT_PROTO( ntlm );
|
||||
extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( ntlm );
|
||||
#endif
|
||||
#ifdef STATIC_OTP
|
||||
extern SPECIFIC_SERVER_PLUG_INIT_PROTO( otp );
|
||||
extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( otp );
|
||||
#endif
|
||||
#ifdef STATIC_PLAIN
|
||||
extern SPECIFIC_SERVER_PLUG_INIT_PROTO( plain );
|
||||
extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( plain );
|
||||
#endif
|
||||
#ifdef STATIC_SRP
|
||||
extern SPECIFIC_SERVER_PLUG_INIT_PROTO( srp );
|
||||
extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( srp );
|
||||
#endif
|
||||
#ifdef STATIC_SASLDB
|
||||
extern SPECIFIC_AUXPROP_PLUG_INIT_PROTO( sasldb );
|
||||
#endif
|
||||
#ifdef STATIC_SQL
|
||||
extern SPECIFIC_AUXPROP_PLUG_INIT_PROTO( sql );
|
||||
#endif
|
||||
#ifdef STATIC_LDAPDB
|
||||
extern SPECIFIC_AUXPROP_PLUG_INIT_PROTO( ldapdb );
|
||||
#endif
|
||||
|
||||
_sasl_plug_rec _sasl_static_plugins[] = {
|
||||
#ifdef STATIC_ANONYMOUS
|
||||
SPECIFIC_SERVER_PLUG_INIT( anonymous, "ANONYMOUS" ),
|
||||
SPECIFIC_CLIENT_PLUG_INIT( anonymous, "ANONYMOUS" ),
|
||||
#endif
|
||||
#ifdef STATIC_CRAMMD5
|
||||
SPECIFIC_SERVER_PLUG_INIT( crammd5, "CRAM-MD5" ),
|
||||
SPECIFIC_CLIENT_PLUG_INIT( crammd5, "CRAM-MD5" ),
|
||||
#endif
|
||||
#ifdef STATIC_DIGESTMD5
|
||||
SPECIFIC_SERVER_PLUG_INIT( digestmd5, "DIGEST-MD5" ),
|
||||
SPECIFIC_CLIENT_PLUG_INIT( digestmd5, "DIGEST-MD5" ),
|
||||
#endif
|
||||
#ifdef STATIC_GSSAPIV2
|
||||
SPECIFIC_SERVER_PLUG_INIT( gssapiv2, "GSSAPI" ),
|
||||
SPECIFIC_CLIENT_PLUG_INIT( gssapiv2, "GSSAPI" ),
|
||||
#endif
|
||||
#ifdef STATIC_KERBEROS4
|
||||
SPECIFIC_SERVER_PLUG_INIT( kerberos4, "KERBEROS_V4" ),
|
||||
SPECIFIC_CLIENT_PLUG_INIT( kerberos4, "KERBEROS_V4" ),
|
||||
#endif
|
||||
#ifdef STATIC_LOGIN
|
||||
SPECIFIC_SERVER_PLUG_INIT( login, "LOGIN" ),
|
||||
SPECIFIC_CLIENT_PLUG_INIT( login, "LOGIN" ),
|
||||
#endif
|
||||
#ifdef STATIC_NTLM
|
||||
SPECIFIC_SERVER_PLUG_INIT( ntlm, "NTLM" ),
|
||||
SPECIFIC_CLIENT_PLUG_INIT( ntlm, "NTLM" ),
|
||||
#endif
|
||||
#ifdef STATIC_OTP
|
||||
SPECIFIC_SERVER_PLUG_INIT( otp, "OTP" ),
|
||||
SPECIFIC_CLIENT_PLUG_INIT( otp, "OTP" ),
|
||||
#endif
|
||||
#ifdef STATIC_PLAIN
|
||||
SPECIFIC_SERVER_PLUG_INIT( plain, "PLAIN" ),
|
||||
SPECIFIC_CLIENT_PLUG_INIT( plain, "PLAIN" ),
|
||||
#endif
|
||||
#ifdef STATIC_SRP
|
||||
SPECIFIC_SERVER_PLUG_INIT( srp, "SRP" ),
|
||||
SPECIFIC_CLIENT_PLUG_INIT( srp, "SRP" ),
|
||||
#endif
|
||||
#ifdef STATIC_SASLDB
|
||||
SPECIFIC_AUXPROP_PLUG_INIT( sasldb, "SASLDB" ),
|
||||
#endif
|
||||
#ifdef STATIC_SQL
|
||||
SPECIFIC_AUXPROP_PLUG_INIT( sql, "SQL" ),
|
||||
#endif
|
||||
#ifdef STATIC_LDAPDB
|
||||
SPECIFIC_AUXPROP_PLUG_INIT( ldapdb, "LDAPDB" ),
|
||||
#endif
|
||||
{ UNKNOWN, NULL, NULL }
|
||||
};
|
||||
@@ -0,0 +1,330 @@
|
||||
/* windlopen.c--Windows dynamic loader interface
|
||||
* Ryan Troll
|
||||
* $Id: windlopen.c,v 1.17 2009/01/25 20:20:57 mel Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <config.h>
|
||||
#include <sasl.h>
|
||||
#include "saslint.h"
|
||||
|
||||
#define DLL_SUFFIX ".dll"
|
||||
#define DLL_MASK "*" DLL_SUFFIX
|
||||
#define DLL_MASK_LEN 5
|
||||
|
||||
const int _is_sasl_server_static = 0;
|
||||
|
||||
/* : inefficient representation, but works */
|
||||
typedef struct lib_list
|
||||
{
|
||||
struct lib_list *next;
|
||||
HMODULE library;
|
||||
} lib_list_t;
|
||||
|
||||
static lib_list_t *lib_list_head = NULL;
|
||||
|
||||
int _sasl_locate_entry(void *library,
|
||||
const char *entryname,
|
||||
void **entry_point)
|
||||
{
|
||||
if(entryname == NULL) {
|
||||
_sasl_log(NULL, SASL_LOG_ERR,
|
||||
"no entryname in _sasl_locate_entry");
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
if(library == NULL) {
|
||||
_sasl_log(NULL, SASL_LOG_ERR,
|
||||
"no library in _sasl_locate_entry");
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
if(entry_point == NULL) {
|
||||
_sasl_log(NULL, SASL_LOG_ERR,
|
||||
"no entrypoint output pointer in _sasl_locate_entry");
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
*entry_point = GetProcAddress(library, entryname);
|
||||
|
||||
if (*entry_point == NULL) {
|
||||
#if 0 /* This message appears to confuse people */
|
||||
_sasl_log(NULL, SASL_LOG_DEBUG,
|
||||
"unable to get entry point %s: %s", entryname,
|
||||
GetLastError());
|
||||
#endif
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static int _sasl_plugin_load(char *plugin, void *library,
|
||||
const char *entryname,
|
||||
int (*add_plugin)(const char *, void *))
|
||||
{
|
||||
void *entry_point;
|
||||
int result;
|
||||
|
||||
result = _sasl_locate_entry(library, entryname, &entry_point);
|
||||
if(result == SASL_OK) {
|
||||
result = add_plugin(plugin, entry_point);
|
||||
if(result != SASL_OK)
|
||||
_sasl_log(NULL, SASL_LOG_DEBUG,
|
||||
"_sasl_plugin_load failed on %s for plugin: %s\n",
|
||||
entryname, plugin);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* loads a plugin library */
|
||||
int _sasl_get_plugin(const char *file,
|
||||
const sasl_callback_t *verifyfile_cb,
|
||||
void **libraryptr)
|
||||
{
|
||||
int r = 0;
|
||||
HINSTANCE library;
|
||||
lib_list_t *newhead;
|
||||
|
||||
r = ((sasl_verifyfile_t *)(verifyfile_cb->proc))
|
||||
(verifyfile_cb->context, file, SASL_VRFY_PLUGIN);
|
||||
if (r != SASL_OK) return r;
|
||||
|
||||
newhead = sasl_ALLOC(sizeof(lib_list_t));
|
||||
if (!newhead) return SASL_NOMEM;
|
||||
|
||||
if (!(library = LoadLibrary (file))) {
|
||||
_sasl_log(NULL, SASL_LOG_ERR,
|
||||
"unable to LoadLibrary %s: %s", file, GetLastError());
|
||||
sasl_FREE(newhead);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
newhead->library = library;
|
||||
newhead->next = lib_list_head;
|
||||
lib_list_head = newhead;
|
||||
|
||||
*libraryptr = library;
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
/* undoes actions done by _sasl_get_plugin */
|
||||
void _sasl_remove_last_plugin()
|
||||
{
|
||||
lib_list_t *last_plugin = lib_list_head;
|
||||
lib_list_head = lib_list_head->next;
|
||||
if (last_plugin->library) {
|
||||
FreeLibrary(last_plugin->library);
|
||||
}
|
||||
sasl_FREE(last_plugin);
|
||||
}
|
||||
|
||||
/* gets the list of mechanisms */
|
||||
int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
|
||||
const sasl_callback_t *getpath_cb,
|
||||
const sasl_callback_t *verifyfile_cb)
|
||||
{
|
||||
int result;
|
||||
char cur_dir[PATH_MAX], full_name[PATH_MAX+2], prefix[PATH_MAX+2];
|
||||
/* 1 for '\\' 1 for trailing '\0' */
|
||||
char * pattern;
|
||||
char c;
|
||||
int pos;
|
||||
const char *path=NULL;
|
||||
int position;
|
||||
const add_plugin_list_t *cur_ep;
|
||||
struct stat statbuf; /* filesystem entry information */
|
||||
intptr_t fhandle; /* file handle for _findnext function */
|
||||
struct _finddata_t finddata; /* data returned by _findnext() */
|
||||
size_t prefix_len;
|
||||
|
||||
if (! entrypoints
|
||||
|| ! getpath_cb
|
||||
|| getpath_cb->id != SASL_CB_GETPATH
|
||||
|| ! getpath_cb->proc
|
||||
|| ! verifyfile_cb
|
||||
|| verifyfile_cb->id != SASL_CB_VERIFYFILE
|
||||
|| ! verifyfile_cb->proc)
|
||||
return SASL_BADPARAM;
|
||||
|
||||
/* get the path to the plugins */
|
||||
result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
|
||||
&path);
|
||||
if (result != SASL_OK) return result;
|
||||
if (! path) return SASL_FAIL;
|
||||
|
||||
if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
position=0;
|
||||
do {
|
||||
pos=0;
|
||||
do {
|
||||
c=path[position];
|
||||
position++;
|
||||
cur_dir[pos]=c;
|
||||
pos++;
|
||||
} while ((c!=PATHS_DELIMITER) && (c!=0));
|
||||
cur_dir[pos-1]='\0';
|
||||
|
||||
|
||||
/* : check to make sure that a valid directory name was passed in */
|
||||
if (stat (cur_dir, &statbuf) < 0) {
|
||||
continue;
|
||||
}
|
||||
if ((statbuf.st_mode & S_IFDIR) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
strcpy (prefix, cur_dir);
|
||||
prefix_len = strlen (prefix);
|
||||
|
||||
/* : Don't append trailing \ unless required */
|
||||
if (prefix[prefix_len-1] != '\\') {
|
||||
strcat (prefix,"\\");
|
||||
prefix_len++;
|
||||
}
|
||||
|
||||
pattern = prefix;
|
||||
|
||||
/* : Check that we have enough space for "*.dll" */
|
||||
if ((prefix_len + DLL_MASK_LEN) > (sizeof(prefix) - 1)) {
|
||||
_sasl_log(NULL, SASL_LOG_WARN, "plugin search mask is too big");
|
||||
continue;
|
||||
}
|
||||
|
||||
strcat (prefix + prefix_len, "*" DLL_SUFFIX);
|
||||
|
||||
fhandle = _findfirst (pattern, &finddata);
|
||||
if (fhandle == -1) { /* no matching files */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* : Truncate "*.dll" */
|
||||
prefix[prefix_len] = '\0';
|
||||
|
||||
do {
|
||||
size_t length;
|
||||
void *library;
|
||||
char *c;
|
||||
char plugname[PATH_MAX];
|
||||
int entries;
|
||||
|
||||
length = strlen(finddata.name);
|
||||
if (length < 5) { /* At least <Ch>.dll */
|
||||
continue; /* can not possibly be what we're looking for */
|
||||
}
|
||||
|
||||
/* : Check for overflow */
|
||||
if (length + prefix_len >= PATH_MAX) continue; /* too big */
|
||||
|
||||
if (stricmp(finddata.name + (length - strlen(DLL_SUFFIX)), DLL_SUFFIX) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* : Check that it is not a directory */
|
||||
if ((finddata.attrib & _A_SUBDIR) == _A_SUBDIR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* : Construct full name from prefix and name */
|
||||
|
||||
strcpy (full_name, prefix);
|
||||
strcat (full_name, finddata.name);
|
||||
|
||||
/* cut off .dll suffix -- this only need be approximate */
|
||||
strcpy (plugname, finddata.name);
|
||||
c = strrchr(plugname, '.');
|
||||
if (c != NULL) *c = '\0';
|
||||
|
||||
result = _sasl_get_plugin (full_name, verifyfile_cb, &library);
|
||||
|
||||
if (result != SASL_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
entries = 0;
|
||||
for (cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
|
||||
result = _sasl_plugin_load(plugname,
|
||||
library,
|
||||
cur_ep->entryname,
|
||||
cur_ep->add_plugin);
|
||||
if (result == SASL_OK) {
|
||||
++entries;
|
||||
}
|
||||
/* If this fails, it's not the end of the world */
|
||||
}
|
||||
if (entries == 0) {
|
||||
_sasl_remove_last_plugin();
|
||||
}
|
||||
|
||||
} while (_findnext (fhandle, &finddata) == 0);
|
||||
|
||||
_findclose (fhandle);
|
||||
|
||||
} while ((c!='=') && (c!=0));
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
_sasl_done_with_plugins(void)
|
||||
{
|
||||
lib_list_t *libptr, *libptr_next;
|
||||
|
||||
for(libptr = lib_list_head; libptr; libptr = libptr_next) {
|
||||
libptr_next = libptr->next;
|
||||
if (libptr->library != NULL) {
|
||||
FreeLibrary(libptr->library);
|
||||
}
|
||||
sasl_FREE(libptr);
|
||||
}
|
||||
|
||||
lib_list_head = NULL;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
# Makefile.am for the SASL plugins
|
||||
# Rob Siemborski
|
||||
# Rob Earhart
|
||||
# $Id: Makefile.am,v 1.86 2011/09/05 14:18:10 murch Exp $
|
||||
#
|
||||
################################################################
|
||||
# Copyright (c) 2000 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# prior written permission. For permission or any other legal
|
||||
# details, please contact
|
||||
# Office of Technology Transfer
|
||||
# Carnegie Mellon University
|
||||
# 5000 Forbes Avenue
|
||||
# Pittsburgh, PA 15213-3890
|
||||
# (412) 268-4387, fax: (412) 268-7395
|
||||
# tech-transfer@andrew.cmu.edu
|
||||
#
|
||||
# 4. Redistributions of any form whatsoever must retain the following
|
||||
# acknowledgment:
|
||||
# "This product includes software developed by Computing Services
|
||||
# at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
#
|
||||
# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
################################################################
|
||||
|
||||
# Library version info - here at the top, for sanity
|
||||
# See <http://www.gnu.org/software/libtool/manual/libtool.html#Versioning>
|
||||
# CURRENT:REVISION:AGE
|
||||
plugin_version = 3:0:0
|
||||
|
||||
INCLUDES=-I$(top_srcdir)/include -I$(top_srcdir)/lib -I$(top_srcdir)/sasldb -I$(top_builddir)/include
|
||||
AM_LDFLAGS = -module -export-dynamic -rpath $(plugindir) -version-info $(plugin_version)
|
||||
|
||||
COMPAT_OBJS = @LTGETADDRINFOOBJS@ @LTGETNAMEINFOOBJS@ @LTSNPRINTFOBJS@
|
||||
|
||||
EXTRA_DIST = makeinit.sh NTMakefile
|
||||
noinst_SCRIPTS = makeinit.sh
|
||||
|
||||
LIB_MYSQL = @LIB_MYSQL@
|
||||
|
||||
plugindir = @plugindir@
|
||||
|
||||
common_sources = plugin_common.c plugin_common.h
|
||||
|
||||
sasldir = $(prefix)/lib/sasl2
|
||||
sasl_LTLIBRARIES = @SASL_MECHS@
|
||||
EXTRA_LTLIBRARIES = libplain.la libanonymous.la libkerberos4.la libcrammd5.la \
|
||||
libgs2.la libgssapiv2.la libdigestmd5.la liblogin.la libsrp.la libotp.la \
|
||||
libscram.la libntlm.la libpassdss.la libsasldb.la libsql.la libldapdb.la
|
||||
|
||||
libplain_la_SOURCES = plain.c plain_init.c $(common_sources)
|
||||
libplain_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libplain_la_LIBADD = $(PLAIN_LIBS) $(COMPAT_OBJS)
|
||||
|
||||
libanonymous_la_SOURCES = anonymous.c anonymous_init.c $(common_sources)
|
||||
libanonymous_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libanonymous_la_LIBADD = $(COMPAT_OBJS)
|
||||
|
||||
libkerberos4_la_SOURCES = kerberos4.c kerberos4_init.c $(common_sources)
|
||||
libkerberos4_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libkerberos4_la_LIBADD = $(SASL_KRB_LIB) $(LIB_SOCKET) $(COMPAT_OBJS)
|
||||
|
||||
libgs2_la_SOURCES = gs2.c gs2_init.c gs2_token.c gs2_token.h $(common_sources)
|
||||
libgs2_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libgs2_la_LIBADD = $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) $(COMPAT_OBJS)
|
||||
|
||||
libgssapiv2_la_SOURCES = gssapi.c gssapiv2_init.c $(common_sources)
|
||||
libgssapiv2_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libgssapiv2_la_LIBADD = $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) $(COMPAT_OBJS)
|
||||
|
||||
libcrammd5_la_SOURCES = cram.c crammd5_init.c $(common_sources)
|
||||
libcrammd5_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libcrammd5_la_LIBADD = $(COMPAT_OBJS)
|
||||
|
||||
libdigestmd5_la_SOURCES = digestmd5.c digestmd5_init.c $(common_sources)
|
||||
libdigestmd5_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libdigestmd5_la_LIBADD = $(LIB_DES) $(LIB_SOCKET) $(COMPAT_OBJS)
|
||||
|
||||
libscram_la_SOURCES = scram.c scram_init.c $(common_sources)
|
||||
libscram_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libscram_la_LIBADD = $(SCRAM_LIBS) $(COMPAT_OBJS)
|
||||
|
||||
liblogin_la_SOURCES = login.c login_init.c $(common_sources)
|
||||
liblogin_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
liblogin_la_LIBADD = $(PLAIN_LIBS) $(COMPAT_OBJS)
|
||||
|
||||
libsrp_la_SOURCES = srp.c srp_init.c $(common_sources)
|
||||
libsrp_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libsrp_la_LIBADD = $(SRP_LIBS) $(COMPAT_OBJS)
|
||||
|
||||
libotp_la_SOURCES = otp.c otp_init.c otp.h $(common_sources)
|
||||
libotp_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libotp_la_LIBADD = $(OTP_LIBS) $(COMPAT_OBJS)
|
||||
|
||||
libntlm_la_SOURCES = ntlm.c ntlm_init.c $(common_sources)
|
||||
libntlm_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libntlm_la_LIBADD = $(NTLM_LIBS) $(COMPAT_OBJS)
|
||||
|
||||
libpassdss_la_SOURCES = passdss.c passdss_init.c $(common_sources)
|
||||
libpassdss_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libpassdss_la_LIBADD = $(PASSDSS_LIBS) $(COMPAT_OBJS)
|
||||
|
||||
# Auxprop Plugins
|
||||
libsasldb_la_SOURCES = sasldb.c sasldb_init.c $(common_sources)
|
||||
libsasldb_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libsasldb_la_LIBADD = ../sasldb/libsasldb.la $(SASL_DB_LIB) $(COMPAT_OBJS)
|
||||
|
||||
libldapdb_la_SOURCES = ldapdb.c ldapdb_init.c $(common_sources)
|
||||
libldapdb_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libldapdb_la_LIBADD = $(LIB_LDAP) $(COMPAT_OBJS)
|
||||
|
||||
libsql_la_SOURCES = sql.c sql_init.c $(common_sources)
|
||||
libsql_la_LDFLAGS = $(LIB_MYSQL) $(LIB_PGSQL) $(LIB_SQLITE) $(LIB_SQLITE3) \
|
||||
$(AM_LDFLAGS)
|
||||
libsql_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libsql_la_LIBADD = $(COMPAT_OBJS)
|
||||
|
||||
|
||||
# Instructions for making the _init files
|
||||
|
||||
init_src=anonymous_init.c crammd5_init.c digestmd5_init.c scram_init.c gs2_init.c gssapiv2_init.c \
|
||||
kerberos4_init.c login_init.c plain_init.c srp_init.c otp_init.c ntlm_init.c \
|
||||
passdss_init.c sasldb_init.c sql_init.c ldapdb_init.c
|
||||
|
||||
|
||||
CLEANFILES=$(init_src)
|
||||
|
||||
${init_src}: $(srcdir)/makeinit.sh
|
||||
$(SHELL) $(srcdir)/makeinit.sh
|
||||
|
||||
# Compatibility function build rules (they build in lib/)
|
||||
$(COMPAT_OBJS):
|
||||
rm -f $(COMPAT_OBJS)
|
||||
cd ../lib; $(MAKE) $(COMPAT_OBJS)
|
||||
for file in $(COMPAT_OBJS); do ln -s ../lib/$$file .; done
|
||||
|
||||
|
||||
@@ -0,0 +1,818 @@
|
||||
# Makefile.in generated by automake 1.11 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# Makefile.am for the SASL plugins
|
||||
# Rob Siemborski
|
||||
# Rob Earhart
|
||||
# $Id: Makefile.am,v 1.86 2011/09/05 14:18:10 murch Exp $
|
||||
#
|
||||
################################################################
|
||||
# Copyright (c) 2000 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# prior written permission. For permission or any other legal
|
||||
# details, please contact
|
||||
# Office of Technology Transfer
|
||||
# Carnegie Mellon University
|
||||
# 5000 Forbes Avenue
|
||||
# Pittsburgh, PA 15213-3890
|
||||
# (412) 268-4387, fax: (412) 268-7395
|
||||
# tech-transfer@andrew.cmu.edu
|
||||
#
|
||||
# 4. Redistributions of any form whatsoever must retain the following
|
||||
# acknowledgment:
|
||||
# "This product includes software developed by Computing Services
|
||||
# at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
#
|
||||
# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
################################################################
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
subdir = plugins
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/config/kerberos_v4.m4 \
|
||||
$(top_srcdir)/config/libtool.m4 $(top_srcdir)/config/plain.m4 \
|
||||
$(top_srcdir)/config/sasldb.m4 \
|
||||
$(top_srcdir)/cmulocal/berkdb.m4 \
|
||||
$(top_srcdir)/cmulocal/bsd_sockets.m4 \
|
||||
$(top_srcdir)/cmulocal/c-attribute.m4 \
|
||||
$(top_srcdir)/cmulocal/common.m4 \
|
||||
$(top_srcdir)/cmulocal/cyrus.m4 \
|
||||
$(top_srcdir)/cmulocal/init_automake.m4 \
|
||||
$(top_srcdir)/cmulocal/ipv6.m4 \
|
||||
$(top_srcdir)/cmulocal/openldap.m4 \
|
||||
$(top_srcdir)/cmulocal/openssl.m4 \
|
||||
$(top_srcdir)/cmulocal/sasl2.m4 $(top_srcdir)/configure.in
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__installdirs = "$(DESTDIR)$(sasldir)"
|
||||
LTLIBRARIES = $(sasl_LTLIBRARIES)
|
||||
am__DEPENDENCIES_1 =
|
||||
am__objects_1 = plugin_common.lo
|
||||
am_libanonymous_la_OBJECTS = anonymous.lo anonymous_init.lo \
|
||||
$(am__objects_1)
|
||||
libanonymous_la_OBJECTS = $(am_libanonymous_la_OBJECTS)
|
||||
am_libcrammd5_la_OBJECTS = cram.lo crammd5_init.lo $(am__objects_1)
|
||||
libcrammd5_la_OBJECTS = $(am_libcrammd5_la_OBJECTS)
|
||||
am_libdigestmd5_la_OBJECTS = digestmd5.lo digestmd5_init.lo \
|
||||
$(am__objects_1)
|
||||
libdigestmd5_la_OBJECTS = $(am_libdigestmd5_la_OBJECTS)
|
||||
am_libgs2_la_OBJECTS = gs2.lo gs2_init.lo gs2_token.lo \
|
||||
$(am__objects_1)
|
||||
libgs2_la_OBJECTS = $(am_libgs2_la_OBJECTS)
|
||||
am_libgssapiv2_la_OBJECTS = gssapi.lo gssapiv2_init.lo \
|
||||
$(am__objects_1)
|
||||
libgssapiv2_la_OBJECTS = $(am_libgssapiv2_la_OBJECTS)
|
||||
am_libkerberos4_la_OBJECTS = kerberos4.lo kerberos4_init.lo \
|
||||
$(am__objects_1)
|
||||
libkerberos4_la_OBJECTS = $(am_libkerberos4_la_OBJECTS)
|
||||
am_libldapdb_la_OBJECTS = ldapdb.lo ldapdb_init.lo $(am__objects_1)
|
||||
libldapdb_la_OBJECTS = $(am_libldapdb_la_OBJECTS)
|
||||
am_liblogin_la_OBJECTS = login.lo login_init.lo $(am__objects_1)
|
||||
liblogin_la_OBJECTS = $(am_liblogin_la_OBJECTS)
|
||||
am_libntlm_la_OBJECTS = ntlm.lo ntlm_init.lo $(am__objects_1)
|
||||
libntlm_la_OBJECTS = $(am_libntlm_la_OBJECTS)
|
||||
am_libotp_la_OBJECTS = otp.lo otp_init.lo $(am__objects_1)
|
||||
libotp_la_OBJECTS = $(am_libotp_la_OBJECTS)
|
||||
am_libpassdss_la_OBJECTS = passdss.lo passdss_init.lo $(am__objects_1)
|
||||
libpassdss_la_OBJECTS = $(am_libpassdss_la_OBJECTS)
|
||||
am_libplain_la_OBJECTS = plain.lo plain_init.lo $(am__objects_1)
|
||||
libplain_la_OBJECTS = $(am_libplain_la_OBJECTS)
|
||||
am_libsasldb_la_OBJECTS = sasldb.lo sasldb_init.lo $(am__objects_1)
|
||||
libsasldb_la_OBJECTS = $(am_libsasldb_la_OBJECTS)
|
||||
am_libscram_la_OBJECTS = scram.lo scram_init.lo $(am__objects_1)
|
||||
libscram_la_OBJECTS = $(am_libscram_la_OBJECTS)
|
||||
am_libsql_la_OBJECTS = sql.lo sql_init.lo $(am__objects_1)
|
||||
libsql_la_OBJECTS = $(am_libsql_la_OBJECTS)
|
||||
libsql_la_LINK = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(libsql_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
am_libsrp_la_OBJECTS = srp.lo srp_init.lo $(am__objects_1)
|
||||
libsrp_la_OBJECTS = $(am_libsrp_la_OBJECTS)
|
||||
SCRIPTS = $(noinst_SCRIPTS)
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
|
||||
depcomp = $(SHELL) $(top_srcdir)/config/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link \
|
||||
$(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
SOURCES = $(libanonymous_la_SOURCES) $(libcrammd5_la_SOURCES) \
|
||||
$(libdigestmd5_la_SOURCES) $(libgs2_la_SOURCES) \
|
||||
$(libgssapiv2_la_SOURCES) $(libkerberos4_la_SOURCES) \
|
||||
$(libldapdb_la_SOURCES) $(liblogin_la_SOURCES) \
|
||||
$(libntlm_la_SOURCES) $(libotp_la_SOURCES) \
|
||||
$(libpassdss_la_SOURCES) $(libplain_la_SOURCES) \
|
||||
$(libsasldb_la_SOURCES) $(libscram_la_SOURCES) \
|
||||
$(libsql_la_SOURCES) $(libsrp_la_SOURCES)
|
||||
DIST_SOURCES = $(libanonymous_la_SOURCES) $(libcrammd5_la_SOURCES) \
|
||||
$(libdigestmd5_la_SOURCES) $(libgs2_la_SOURCES) \
|
||||
$(libgssapiv2_la_SOURCES) $(libkerberos4_la_SOURCES) \
|
||||
$(libldapdb_la_SOURCES) $(liblogin_la_SOURCES) \
|
||||
$(libntlm_la_SOURCES) $(libotp_la_SOURCES) \
|
||||
$(libpassdss_la_SOURCES) $(libplain_la_SOURCES) \
|
||||
$(libsasldb_la_SOURCES) $(libscram_la_SOURCES) \
|
||||
$(libsql_la_SOURCES) $(libsrp_la_SOURCES)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DIRS = @DIRS@
|
||||
DMALLOC_LIBS = @DMALLOC_LIBS@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
GETADDRINFOOBJS = @GETADDRINFOOBJS@
|
||||
GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
|
||||
GETSUBOPT = @GETSUBOPT@
|
||||
GREP = @GREP@
|
||||
GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
|
||||
GSSAPI_LIBS = @GSSAPI_LIBS@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
IPCTYPE = @IPCTYPE@
|
||||
JAVAC = @JAVAC@
|
||||
JAVADOC = @JAVADOC@
|
||||
JAVAH = @JAVAH@
|
||||
JAVAROOT = @JAVAROOT@
|
||||
JAVA_INCLUDES = @JAVA_INCLUDES@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIB_CRYPT = @LIB_CRYPT@
|
||||
LIB_DES = @LIB_DES@
|
||||
LIB_DOOR = @LIB_DOOR@
|
||||
LIB_LDAP = @LIB_LDAP@
|
||||
LIB_MYSQL = @LIB_MYSQL@
|
||||
LIB_PGSQL = @LIB_PGSQL@
|
||||
LIB_SOCKET = @LIB_SOCKET@
|
||||
LIB_SQLITE = @LIB_SQLITE@
|
||||
LIB_SQLITE3 = @LIB_SQLITE3@
|
||||
LN_S = @LN_S@
|
||||
LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
|
||||
LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NTLM_LIBS = @NTLM_LIBS@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTP_LIBS = @OTP_LIBS@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PASSDSS_LIBS = @PASSDSS_LIBS@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
PLAIN_LIBS = @PLAIN_LIBS@
|
||||
PURECOV = @PURECOV@
|
||||
PURIFY = @PURIFY@
|
||||
PWCHECKMETH = @PWCHECKMETH@
|
||||
RANLIB = @RANLIB@
|
||||
SASL_DB_BACKEND = @SASL_DB_BACKEND@
|
||||
SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
|
||||
SASL_DB_INC = @SASL_DB_INC@
|
||||
SASL_DB_LIB = @SASL_DB_LIB@
|
||||
SASL_DB_MANS = @SASL_DB_MANS@
|
||||
SASL_DB_UTILS = @SASL_DB_UTILS@
|
||||
SASL_DL_LIB = @SASL_DL_LIB@
|
||||
SASL_KRB_LIB = @SASL_KRB_LIB@
|
||||
SASL_MECHS = @SASL_MECHS@
|
||||
SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
|
||||
SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
|
||||
SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
|
||||
SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
|
||||
SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
|
||||
SCRAM_LIBS = @SCRAM_LIBS@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
|
||||
SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
|
||||
SHELL = @SHELL@
|
||||
SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
|
||||
SNPRINTFOBJS = @SNPRINTFOBJS@
|
||||
SRP_LIBS = @SRP_LIBS@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
configdir = @configdir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
plugindir = @plugindir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
subdirs = @subdirs@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
# Library version info - here at the top, for sanity
|
||||
# See <http://www.gnu.org/software/libtool/manual/libtool.html#Versioning>
|
||||
# CURRENT:REVISION:AGE
|
||||
plugin_version = 3:0:0
|
||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/lib -I$(top_srcdir)/sasldb -I$(top_builddir)/include
|
||||
AM_LDFLAGS = -module -export-dynamic -rpath $(plugindir) -version-info $(plugin_version)
|
||||
COMPAT_OBJS = @LTGETADDRINFOOBJS@ @LTGETNAMEINFOOBJS@ @LTSNPRINTFOBJS@
|
||||
EXTRA_DIST = makeinit.sh NTMakefile
|
||||
noinst_SCRIPTS = makeinit.sh
|
||||
common_sources = plugin_common.c plugin_common.h
|
||||
sasldir = $(prefix)/lib/sasl2
|
||||
sasl_LTLIBRARIES = @SASL_MECHS@
|
||||
EXTRA_LTLIBRARIES = libplain.la libanonymous.la libkerberos4.la libcrammd5.la \
|
||||
libgs2.la libgssapiv2.la libdigestmd5.la liblogin.la libsrp.la libotp.la \
|
||||
libscram.la libntlm.la libpassdss.la libsasldb.la libsql.la libldapdb.la
|
||||
|
||||
libplain_la_SOURCES = plain.c plain_init.c $(common_sources)
|
||||
libplain_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libplain_la_LIBADD = $(PLAIN_LIBS) $(COMPAT_OBJS)
|
||||
libanonymous_la_SOURCES = anonymous.c anonymous_init.c $(common_sources)
|
||||
libanonymous_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libanonymous_la_LIBADD = $(COMPAT_OBJS)
|
||||
libkerberos4_la_SOURCES = kerberos4.c kerberos4_init.c $(common_sources)
|
||||
libkerberos4_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libkerberos4_la_LIBADD = $(SASL_KRB_LIB) $(LIB_SOCKET) $(COMPAT_OBJS)
|
||||
libgs2_la_SOURCES = gs2.c gs2_init.c gs2_token.c gs2_token.h $(common_sources)
|
||||
libgs2_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libgs2_la_LIBADD = $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) $(COMPAT_OBJS)
|
||||
libgssapiv2_la_SOURCES = gssapi.c gssapiv2_init.c $(common_sources)
|
||||
libgssapiv2_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libgssapiv2_la_LIBADD = $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) $(COMPAT_OBJS)
|
||||
libcrammd5_la_SOURCES = cram.c crammd5_init.c $(common_sources)
|
||||
libcrammd5_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libcrammd5_la_LIBADD = $(COMPAT_OBJS)
|
||||
libdigestmd5_la_SOURCES = digestmd5.c digestmd5_init.c $(common_sources)
|
||||
libdigestmd5_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libdigestmd5_la_LIBADD = $(LIB_DES) $(LIB_SOCKET) $(COMPAT_OBJS)
|
||||
libscram_la_SOURCES = scram.c scram_init.c $(common_sources)
|
||||
libscram_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libscram_la_LIBADD = $(SCRAM_LIBS) $(COMPAT_OBJS)
|
||||
liblogin_la_SOURCES = login.c login_init.c $(common_sources)
|
||||
liblogin_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
liblogin_la_LIBADD = $(PLAIN_LIBS) $(COMPAT_OBJS)
|
||||
libsrp_la_SOURCES = srp.c srp_init.c $(common_sources)
|
||||
libsrp_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libsrp_la_LIBADD = $(SRP_LIBS) $(COMPAT_OBJS)
|
||||
libotp_la_SOURCES = otp.c otp_init.c otp.h $(common_sources)
|
||||
libotp_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libotp_la_LIBADD = $(OTP_LIBS) $(COMPAT_OBJS)
|
||||
libntlm_la_SOURCES = ntlm.c ntlm_init.c $(common_sources)
|
||||
libntlm_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libntlm_la_LIBADD = $(NTLM_LIBS) $(COMPAT_OBJS)
|
||||
libpassdss_la_SOURCES = passdss.c passdss_init.c $(common_sources)
|
||||
libpassdss_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libpassdss_la_LIBADD = $(PASSDSS_LIBS) $(COMPAT_OBJS)
|
||||
|
||||
# Auxprop Plugins
|
||||
libsasldb_la_SOURCES = sasldb.c sasldb_init.c $(common_sources)
|
||||
libsasldb_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libsasldb_la_LIBADD = ../sasldb/libsasldb.la $(SASL_DB_LIB) $(COMPAT_OBJS)
|
||||
libldapdb_la_SOURCES = ldapdb.c ldapdb_init.c $(common_sources)
|
||||
libldapdb_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libldapdb_la_LIBADD = $(LIB_LDAP) $(COMPAT_OBJS)
|
||||
libsql_la_SOURCES = sql.c sql_init.c $(common_sources)
|
||||
libsql_la_LDFLAGS = $(LIB_MYSQL) $(LIB_PGSQL) $(LIB_SQLITE) $(LIB_SQLITE3) \
|
||||
$(AM_LDFLAGS)
|
||||
|
||||
libsql_la_DEPENDENCIES = $(COMPAT_OBJS)
|
||||
libsql_la_LIBADD = $(COMPAT_OBJS)
|
||||
|
||||
# Instructions for making the _init files
|
||||
init_src = anonymous_init.c crammd5_init.c digestmd5_init.c scram_init.c gs2_init.c gssapiv2_init.c \
|
||||
kerberos4_init.c login_init.c plain_init.c srp_init.c otp_init.c ntlm_init.c \
|
||||
passdss_init.c sasldb_init.c sql_init.c ldapdb_init.c
|
||||
|
||||
CLEANFILES = $(init_src)
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
|
||||
&& { if test -f $@; then exit 0; else break; fi; }; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu plugins/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnu plugins/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
|
||||
$(top_srcdir)/configure: $(am__configure_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
|
||||
$(am__aclocal_m4_deps):
|
||||
install-saslLTLIBRARIES: $(sasl_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(sasldir)" || $(MKDIR_P) "$(DESTDIR)$(sasldir)"
|
||||
@list='$(sasl_LTLIBRARIES)'; test -n "$(sasldir)" || list=; \
|
||||
list2=; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
list2="$$list2 $$p"; \
|
||||
else :; fi; \
|
||||
done; \
|
||||
test -z "$$list2" || { \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(sasldir)'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(sasldir)"; \
|
||||
}
|
||||
|
||||
uninstall-saslLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(sasl_LTLIBRARIES)'; test -n "$(sasldir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(sasldir)/$$f'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(sasldir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-saslLTLIBRARIES:
|
||||
-test -z "$(sasl_LTLIBRARIES)" || rm -f $(sasl_LTLIBRARIES)
|
||||
@list='$(sasl_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" != "$$p" || dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
libanonymous.la: $(libanonymous_la_OBJECTS) $(libanonymous_la_DEPENDENCIES)
|
||||
$(LINK) $(libanonymous_la_OBJECTS) $(libanonymous_la_LIBADD) $(LIBS)
|
||||
libcrammd5.la: $(libcrammd5_la_OBJECTS) $(libcrammd5_la_DEPENDENCIES)
|
||||
$(LINK) $(libcrammd5_la_OBJECTS) $(libcrammd5_la_LIBADD) $(LIBS)
|
||||
libdigestmd5.la: $(libdigestmd5_la_OBJECTS) $(libdigestmd5_la_DEPENDENCIES)
|
||||
$(LINK) $(libdigestmd5_la_OBJECTS) $(libdigestmd5_la_LIBADD) $(LIBS)
|
||||
libgs2.la: $(libgs2_la_OBJECTS) $(libgs2_la_DEPENDENCIES)
|
||||
$(LINK) $(libgs2_la_OBJECTS) $(libgs2_la_LIBADD) $(LIBS)
|
||||
libgssapiv2.la: $(libgssapiv2_la_OBJECTS) $(libgssapiv2_la_DEPENDENCIES)
|
||||
$(LINK) $(libgssapiv2_la_OBJECTS) $(libgssapiv2_la_LIBADD) $(LIBS)
|
||||
libkerberos4.la: $(libkerberos4_la_OBJECTS) $(libkerberos4_la_DEPENDENCIES)
|
||||
$(LINK) $(libkerberos4_la_OBJECTS) $(libkerberos4_la_LIBADD) $(LIBS)
|
||||
libldapdb.la: $(libldapdb_la_OBJECTS) $(libldapdb_la_DEPENDENCIES)
|
||||
$(LINK) $(libldapdb_la_OBJECTS) $(libldapdb_la_LIBADD) $(LIBS)
|
||||
liblogin.la: $(liblogin_la_OBJECTS) $(liblogin_la_DEPENDENCIES)
|
||||
$(LINK) $(liblogin_la_OBJECTS) $(liblogin_la_LIBADD) $(LIBS)
|
||||
libntlm.la: $(libntlm_la_OBJECTS) $(libntlm_la_DEPENDENCIES)
|
||||
$(LINK) $(libntlm_la_OBJECTS) $(libntlm_la_LIBADD) $(LIBS)
|
||||
libotp.la: $(libotp_la_OBJECTS) $(libotp_la_DEPENDENCIES)
|
||||
$(LINK) $(libotp_la_OBJECTS) $(libotp_la_LIBADD) $(LIBS)
|
||||
libpassdss.la: $(libpassdss_la_OBJECTS) $(libpassdss_la_DEPENDENCIES)
|
||||
$(LINK) $(libpassdss_la_OBJECTS) $(libpassdss_la_LIBADD) $(LIBS)
|
||||
libplain.la: $(libplain_la_OBJECTS) $(libplain_la_DEPENDENCIES)
|
||||
$(LINK) $(libplain_la_OBJECTS) $(libplain_la_LIBADD) $(LIBS)
|
||||
libsasldb.la: $(libsasldb_la_OBJECTS) $(libsasldb_la_DEPENDENCIES)
|
||||
$(LINK) $(libsasldb_la_OBJECTS) $(libsasldb_la_LIBADD) $(LIBS)
|
||||
libscram.la: $(libscram_la_OBJECTS) $(libscram_la_DEPENDENCIES)
|
||||
$(LINK) $(libscram_la_OBJECTS) $(libscram_la_LIBADD) $(LIBS)
|
||||
libsql.la: $(libsql_la_OBJECTS) $(libsql_la_DEPENDENCIES)
|
||||
$(libsql_la_LINK) $(libsql_la_OBJECTS) $(libsql_la_LIBADD) $(LIBS)
|
||||
libsrp.la: $(libsrp_la_OBJECTS) $(libsrp_la_DEPENDENCIES)
|
||||
$(LINK) $(libsrp_la_OBJECTS) $(libsrp_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/anonymous.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/anonymous_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cram.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crammd5_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digestmd5.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digestmd5_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gs2.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gs2_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gs2_token.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gssapi.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gssapiv2_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kerberos4.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kerberos4_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldapdb.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldapdb_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/login.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/login_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntlm.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntlm_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otp.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otp_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passdss.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passdss_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plain.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plain_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_common.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sasldb.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sasldb_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scram.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scram_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql_init.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/srp.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/srp_init.Plo@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LTLIBRARIES) $(SCRIPTS)
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(sasldir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool clean-saslLTLIBRARIES \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-saslLTLIBRARIES
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-saslLTLIBRARIES
|
||||
|
||||
.MAKE: install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
|
||||
clean-libtool clean-saslLTLIBRARIES ctags distclean \
|
||||
distclean-compile distclean-generic distclean-libtool \
|
||||
distclean-tags distdir dvi dvi-am html html-am info info-am \
|
||||
install install-am install-data install-data-am install-dvi \
|
||||
install-dvi-am install-exec install-exec-am install-html \
|
||||
install-html-am install-info install-info-am install-man \
|
||||
install-pdf install-pdf-am install-ps install-ps-am \
|
||||
install-saslLTLIBRARIES install-strip installcheck \
|
||||
installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags uninstall uninstall-am uninstall-saslLTLIBRARIES
|
||||
|
||||
|
||||
${init_src}: $(srcdir)/makeinit.sh
|
||||
$(SHELL) $(srcdir)/makeinit.sh
|
||||
|
||||
# Compatibility function build rules (they build in lib/)
|
||||
$(COMPAT_OBJS):
|
||||
rm -f $(COMPAT_OBJS)
|
||||
cd ../lib; $(MAKE) $(COMPAT_OBJS)
|
||||
for file in $(COMPAT_OBJS); do ln -s ../lib/$$file .; done
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
+325
@@ -0,0 +1,325 @@
|
||||
!INCLUDE ..\win32\common.mak
|
||||
|
||||
SCRAM=1
|
||||
|
||||
!IF "$(NTLM)" == "1"
|
||||
PLUGINS_EXT=saslNTLM.dll
|
||||
!ELSE
|
||||
PLUGINS_EXT=
|
||||
!ENDIF
|
||||
|
||||
!IF "$(GSSAPI)" == "CyberSafe"
|
||||
PLUGINS_EXT=$(PLUGINS_EXT) saslGSSAPI.dll
|
||||
!ENDIF
|
||||
|
||||
!IF "$(SRP)" == "1"
|
||||
PLUGINS_EXT=$(PLUGINS_EXT) saslSRP.dll
|
||||
!IF "$(DO_SRP_SETPASS)" == "1"
|
||||
SRP_FLAGS=/DDO_SRP_SETPASS=1
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
!IF "$(OTP)" == "1"
|
||||
PLUGINS_EXT=$(PLUGINS_EXT) saslOTP.dll
|
||||
!ENDIF
|
||||
|
||||
!IF "$(LDAP)" == "1"
|
||||
PLUGINS_EXT=$(PLUGINS_EXT) saslLDAPDB.dll
|
||||
|
||||
# NB: linking to libsasl itself!!!
|
||||
LDAP_FLAGS = /I $(LDAP_INCLUDE)
|
||||
LDAP_LIBS = $(LDAP_LIB_BASE)\olber32.lib $(LDAP_LIB_BASE)\oldap32.lib ..\lib\libsasl.lib
|
||||
!ENDIF
|
||||
|
||||
!IF "$(SQL)" == "SQLITE"
|
||||
PLUGINS_EXT=$(PLUGINS_EXT) saslSQLITE.dll
|
||||
SQL_FLAGS= $(SQLITE_INCLUDES) /DHAVE_SQLITE=1
|
||||
SQLITE_LIBS = /libpath:$(SQLITE_LIBPATH) libsqlite.lib
|
||||
!ENDIF
|
||||
!IF "$(SQL)" == "SQLITE3"
|
||||
PLUGINS_EXT=$(PLUGINS_EXT) saslSQLITE.dll
|
||||
SQL_FLAGS= $(SQLITE_INCLUDES3) /DHAVE_SQLITE3=1
|
||||
SQLITE_LIBS = /libpath:$(SQLITE_LIBPATH3) libsqlite3.lib
|
||||
!ENDIF
|
||||
|
||||
PLUGINS=saslANONYMOUS.dll \
|
||||
saslPLAIN.dll \
|
||||
saslCRAMMD5.dll \
|
||||
saslDIGESTMD5.dll \
|
||||
saslLOGIN.dll \
|
||||
saslSCRAM.dll \
|
||||
$(PLUGINS_EXT) \
|
||||
saslSASLDB.dll
|
||||
|
||||
generated_rc=saslANONYMOUS.rc saslPLAIN.rc saslCRAMMD5.rc saslDIGESTMD5.rc saslLOGIN.rc saslNTLM.rc saslSCRAM.rc saslGSSAPI.rc saslSRP.rc saslOTP.rc saslSASLDB.rc saslSQLITE.rc saslLDAPDB.rc
|
||||
|
||||
# WS2tcpip.h included in Visual Studio 7 provides getaddrinfo, ...
|
||||
# emulation on Windows, so there is no need to build getaddrinfo.c
|
||||
|
||||
!IF "$(VCVER)" == "6"
|
||||
compat_sources = getaddrinfo.c getnameinfo.c
|
||||
compat_objs = getaddrinfo.obj getnameinfo.obj
|
||||
!ENDIF
|
||||
|
||||
common_sources = plugin_common.c plugin_common.h
|
||||
common_objs = plugin_common.obj $(compat_objs)
|
||||
|
||||
saslANONYMOUS_sources = anonymous.c anonymous_init.c $(common_sources)
|
||||
saslANONYMOUS_objs = anonymous.obj anonymous_init.obj $(common_objs)
|
||||
saslANONYMOUS_out = saslANONYMOUS.dll saslANONYMOUS.exp saslANONYMOUS.lib
|
||||
|
||||
saslPLAIN_sources = plain.c plain_init.c $(common_sources)
|
||||
saslPLAIN_objs = plain.obj plain_init.obj $(common_objs)
|
||||
saslPLAIN_out = saslPLAIN.dll saslPLAIN.exp saslPLAIN.lib
|
||||
|
||||
saslCRAMMD5_sources = cram.c crammd5_init.c $(common_sources)
|
||||
saslCRAMMD5_objs = cram.obj crammd5_init.obj $(common_objs)
|
||||
saslCRAMMD5_out = saslCRAMMD5.dll saslCRAMMD5.exp saslCRAMMD5.lib
|
||||
|
||||
saslDIGESTMD5_sources = digestmd5.c digestmd5_init.c $(common_sources)
|
||||
saslDIGESTMD5_objs = digestmd5.obj digestmd5_init.obj $(common_objs)
|
||||
saslDIGESTMD5_out = saslDIGESTMD5.dll saslDIGESTMD5.exp saslDIGESTMD5.lib
|
||||
|
||||
saslLOGIN_sources = login.c login_init.c $(common_sources)
|
||||
saslLOGIN_objs = login.obj login_init.obj $(common_objs)
|
||||
saslLOGIN_out = saslLOGIN.dll saslLOGIN.exp saslLOGIN.lib
|
||||
|
||||
saslSCRAM_sources = scram.c scram_init.c $(common_sources)
|
||||
saslSCRAM_objs = scram.obj scram_init.obj $(common_objs)
|
||||
saslSCRAM_out = saslSCRAM.dll saslSCRAM.exp saslSCRAM.lib
|
||||
|
||||
saslNTLM_sources = ntlm.c ntlm_init.c $(common_sources)
|
||||
saslNTLM_objs = ntlm.obj ntlm_init.obj $(common_objs)
|
||||
saslNTLM_out = saslNTLM.dll saslNTLM.exp saslNTLM.lib
|
||||
|
||||
saslGSSAPI_sources = gssapi.c gssapiv2_init.c $(common_sources)
|
||||
saslGSSAPI_objs = gssapi.obj gssapiv2_init.obj $(common_objs)
|
||||
saslGSSAPI_out = saslGSSAPI.dll saslGSSAPI.exp saslGSSAPI.lib
|
||||
|
||||
saslSRP_sources = srp.c srp_init.c $(common_sources)
|
||||
saslSRP_objs = srp.obj srp_init.obj $(common_objs)
|
||||
saslSRP_out = saslSRP.dll saslSRP.exp saslSRP.lib
|
||||
|
||||
saslOTP_sources = otp.c otp_init.c $(common_sources)
|
||||
saslOTP_objs = otp.obj otp_init.obj $(common_objs)
|
||||
saslOTP_out = saslOTP.dll saslOTP.exp saslOTP.lib
|
||||
|
||||
saslSQL_sources = sql.c sql_init.c $(common_sources)
|
||||
saslSQL_objs = sql.obj sql_init.obj $(common_objs)
|
||||
# saslSQL_out is an agregation of all generated files for all SQL plugins
|
||||
saslSQL_out = saslSQLITE.dll saslSQLITE.exp saslSQLITE.lib
|
||||
|
||||
saslLDAPDB_sources = ldapdb.c $(common_sources)
|
||||
saslLDAPDB_objs = ldapdb.obj $(common_objs)
|
||||
saslLDAPDB_out = saslLDAPDB.dll saslLDAPDB.exp saslLDAPDB.lib
|
||||
|
||||
!IF "$(NTLM)" == "1" || "$(SRP)" == "1" || "$(OTP)" == "1" || "$(SCRAM)" == "1"
|
||||
OPENSSL_FLAGS= /I $(OPENSSL_INCLUDE)
|
||||
!ELSE
|
||||
OPENSSL_FLAGS=
|
||||
!ENDIF
|
||||
|
||||
!IF "$(GSSAPI)" == "CyberSafe"
|
||||
GSS_FLAGS= /I $(GSSAPI_INCLUDE) /D "HAVE_GSS_C_NT_HOSTBASED_SERVICE" /D "HAVE_GSS_C_NT_USER_NAME"
|
||||
GSS_LIBS=/libpath:$(GSSAPI_LIBPATH) gssapi32.lib
|
||||
!ELSE
|
||||
GSS_FLAGS=
|
||||
GSS_LIBS=
|
||||
!ENDIF
|
||||
|
||||
CRAM_FLAGS=/DOBSOLETE_CRAM_ATTR=1
|
||||
|
||||
DIGEST_FLAGS=/D "WITH_RC4"
|
||||
|
||||
# Auxprop Plugin
|
||||
libsasldb_sources = allockey.c db_berkeley.c
|
||||
libsasldb_objs = allockey.obj db_berkeley.obj
|
||||
|
||||
saslSASLDB_sources = sasldb.c sasldb_init.c $(libsasldb_sources) $(common_sources)
|
||||
saslSASLDB_objs = sasldb.obj sasldb_init.obj $(libsasldb_objs) $(common_objs)
|
||||
saslSASLDB_out = saslSASLDB.dll saslSASLDB.exp saslSASLDB.lib
|
||||
|
||||
all_objs = $(saslANONYMOUS_objs) $(saslPLAIN_objs) $(saslCRAMMD5_objs) $(saslDIGESTMD5_objs) $(saslLOGIN_objs) $(saslSCRAM_objs) $(saslNTLM_objs) $(saslGSSAPI_objs) $(saslSRP_objs) $(saslOTP_objs) $(saslSASLDB_objs) $(saslSQL_objs) $(saslLDAPDB_objs)
|
||||
all_out = $(saslANONYMOUS_out) $(saslPLAIN_out) $(saslCRAMMD5_out) $(saslDIGESTMD5_out) $(saslLOGIN_out) $(saslSCRAM_out) $(saslNTLM_out) $(saslGSSAPI_out) $(saslSRP_out) $(saslOTP_out) $(saslSASLDB_out) $(saslSQL_out) $(saslLDAPDB_out)
|
||||
|
||||
# LIBSASL_EXPORTS is required to export additional DB routines from sasldb
|
||||
DB_FLAGS = /I $(DB_INCLUDE) /I "..\sasldb" /D "LIBSASL_EXPORTS" /D "KEEP_DB_OPEN"
|
||||
|
||||
!IF $(TARGET_WIN_SYSTEM) >= 51
|
||||
EXTRA_FLAGS = /D TARGET_WIN_SYSTEM=$(TARGET_WIN_SYSTEM) $(EXTRA_FLAGS)
|
||||
!ENDIF
|
||||
|
||||
EXTRA_FLAGS=$(EXTRA_FLAGS) $(DB_FLAGS) $(OPENSSL_FLAGS) $(GSS_FLAGS) $(SRP_FLAGS) $(SQL_FLAGS) $(DIGEST_FLAGS) $(CRAM_FLAGS) $(LDAP_FLAGS)
|
||||
CPPFLAGS = /I "..\win32\include" /I "." /I "..\include" $(EXTRA_FLAGS) /D "WIN32" /D "_WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL"
|
||||
|
||||
DB_LIBS=/libpath:$(DB_LIBPATH) $(DB_LIB)
|
||||
OPENSSL_LIBS=/libpath:$(OPENSSL_LIBPATH) libeay32.lib ssleay32.lib
|
||||
|
||||
# Where to install files from this directory
|
||||
libdir = $(prefix)\lib
|
||||
bindir = $(prefix)\bin\sasl2
|
||||
|
||||
all : all-recursive
|
||||
|
||||
#
|
||||
# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels
|
||||
#
|
||||
# In order to force xcopy not to confirm if the second parameter is file or directory,
|
||||
# the first parameter has to contain a wildcard character. For example, we use libsasl.l*,
|
||||
# instead of libsasl.lib. Ugly, but works!
|
||||
#
|
||||
# Note, that we will copy all dlls here, not just $(PLUGINS). This is a bug, but it allows
|
||||
# us to copy GSSAPI plugin, which might not be in $(PLUGINS).
|
||||
#
|
||||
install: $(PLUGINS)
|
||||
@xcopy *.dll $(bindir) /I /F /Y
|
||||
|
||||
all-recursive : $(PLUGINS)
|
||||
|
||||
getaddrinfo.c: ..\lib\getaddrinfo.c
|
||||
xcopy /D /Y ..\lib\getaddrinfo.c .
|
||||
|
||||
getnameinfo.c: ..\lib\getnameinfo.c
|
||||
xcopy /D /Y ..\lib\getnameinfo.c .
|
||||
|
||||
allockey.c: ..\sasldb\allockey.c
|
||||
xcopy /D /Y ..\sasldb\allockey.c .
|
||||
|
||||
db_berkeley.c: ..\sasldb\db_berkeley.c
|
||||
xcopy /D /Y ..\sasldb\db_berkeley.c .
|
||||
|
||||
#Add /pdb: option?
|
||||
|
||||
saslANONYMOUS.dll: $(saslANONYMOUS_objs) saslANONYMOUS.res
|
||||
$(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslANONYMOUS.dll" /implib:"saslANONYMOUS.lib" $(saslANONYMOUS_objs) saslANONYMOUS.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslPLAIN.dll: $(saslPLAIN_objs) saslPLAIN.res
|
||||
$(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslPLAIN.dll" /implib:"saslPLAIN.lib" $(saslPLAIN_objs) saslPLAIN.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslCRAMMD5.dll: $(saslCRAMMD5_objs) saslCRAMMD5.res
|
||||
$(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslCRAMMD5.dll" /implib:"saslCRAMMD5.lib" $(saslCRAMMD5_objs) saslCRAMMD5.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslDIGESTMD5.dll: $(saslDIGESTMD5_objs) saslDIGESTMD5.res
|
||||
$(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslDIGESTMD5.dll" /implib:"saslDIGESTMD5.lib" $(saslDIGESTMD5_objs) saslDIGESTMD5.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslLOGIN.dll: $(saslLOGIN_objs) saslLOGIN.res
|
||||
$(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslLOGIN.dll" /implib:"saslLOGIN.lib" $(saslLOGIN_objs) saslLOGIN.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslSCRAM.dll: $(saslSCRAM_objs) saslSCRAM.res
|
||||
$(LINK32DLL) @<< $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslSCRAM.dll" /implib:"saslSCRAM.lib" $(saslSCRAM_objs) saslSCRAM.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslNTLM.dll: $(saslNTLM_objs) saslNTLM.res
|
||||
$(LINK32DLL) @<< $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslNTLM.dll" /implib:"saslNTLM.lib" $(saslNTLM_objs) saslNTLM.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslGSSAPI.dll: $(saslGSSAPI_objs) saslGSSAPI.res
|
||||
$(LINK32DLL) @<< $(GSS_LIBS) $(LINK32DLL_FLAGS) /out:"saslGSSAPI.dll" /implib:"saslGSSAPI.lib" $(saslGSSAPI_objs) saslGSSAPI.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslSRP.dll: $(saslSRP_objs) saslSRP.res
|
||||
$(LINK32DLL) @<< $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslSRP.dll" /implib:"saslSRP.lib" $(saslSRP_objs) saslSRP.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslOTP.dll: $(saslOTP_objs) saslOTP.res
|
||||
$(LINK32DLL) @<< $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslOTP.dll" /implib:"saslOTP.lib" $(saslOTP_objs) saslOTP.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslSASLDB.dll: $(saslSASLDB_objs) saslSASLDB.res
|
||||
$(LINK32DLL) @<< $(DB_LIBS) $(LINK32DLL_FLAGS) /out:"saslSASLDB.dll" /implib:"saslSASLDB.lib" $(saslSASLDB_objs) saslSASLDB.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslSQLITE.dll: $(saslSQL_objs) saslSQLITE.res
|
||||
$(LINK32DLL) @<< $(SQLITE_LIBS) $(LINK32DLL_FLAGS) /out:"saslSQLITE.dll" /implib:"saslSQLITE.lib" $(saslSQL_objs) saslSQLITE.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
saslLDAPDB.dll: $(saslLDAPDB_objs) saslLDAPDB.res
|
||||
$(LINK32DLL) @<< $(LDAP_LIBS) $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslLDAPDB.dll" /implib:"saslLDAPDB.lib" $(saslLDAPDB_objs) saslLDAPDB.res
|
||||
<<
|
||||
IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2
|
||||
|
||||
CLEAN :
|
||||
-@erase $(all_objs)
|
||||
-@erase "*.idb"
|
||||
-@erase "*.pdb"
|
||||
-@erase "*.manifest"
|
||||
-@erase getaddrinfo.c
|
||||
-@erase allockey.c
|
||||
-@erase db_berkeley.c
|
||||
-@erase getnameinfo.c
|
||||
-@erase $(generated_rc)
|
||||
-@erase "*.res"
|
||||
-@erase $(all_out)
|
||||
|
||||
.c.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cpp.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.cxx.obj::
|
||||
$(CPP) @<<
|
||||
$(CPP_PROJ) $<
|
||||
<<
|
||||
|
||||
.rc.res:
|
||||
rc $<
|
||||
|
||||
$(generated_rc):
|
||||
copy <<temp.rc $@
|
||||
#include "windows.h"
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION $(SASL_VERSION_MAJOR),$(SASL_VERSION_MINOR),$(SASL_VERSION_STEP),0
|
||||
PRODUCTVERSION $(SASL_VERSION_MAJOR),$(SASL_VERSION_MINOR),$(SASL_VERSION_STEP),0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x1L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Carnegie Mellon University\0"
|
||||
VALUE "FileDescription", "CMU SASL $(@B) plugin\0"
|
||||
VALUE "FileVersion", "$(SASL_VERSION_MAJOR).$(SASL_VERSION_MINOR).$(SASL_VERSION_STEP).0\0"
|
||||
VALUE "InternalName", "$(@B)\0"
|
||||
VALUE "LegalCopyright", "Copyright (c) Carnegie Mellon University 2002-2012\0"
|
||||
VALUE "OriginalFilename", "$(@B).dll\0"
|
||||
VALUE "ProductName", "Carnegie Mellon University SASL\0"
|
||||
VALUE "ProductVersion", "$(SASL_VERSION_MAJOR).$(SASL_VERSION_MINOR).$(SASL_VERSION_STEP)-0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
<<
|
||||
@@ -0,0 +1,390 @@
|
||||
/* Anonymous SASL plugin
|
||||
* Rob Siemborski
|
||||
* Tim Martin
|
||||
* $Id: anonymous.c,v 1.53 2009/02/13 14:46:47 mel Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_anonymous_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
/***************************** Common Section *****************************/
|
||||
|
||||
static const char plugin_id[] = "$Id: anonymous.c,v 1.53 2009/02/13 14:46:47 mel Exp $";
|
||||
|
||||
static const char anonymous_id[] = "anonymous";
|
||||
|
||||
/***************************** Server Section *****************************/
|
||||
|
||||
static int
|
||||
anonymous_server_mech_new(void *glob_context __attribute__((unused)),
|
||||
sasl_server_params_t *sparams,
|
||||
const char *challenge __attribute__((unused)),
|
||||
unsigned challen __attribute__((unused)),
|
||||
void **conn_context)
|
||||
{
|
||||
/* holds state are in */
|
||||
if (!conn_context) {
|
||||
PARAMERROR( sparams->utils );
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
*conn_context = NULL;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
anonymous_server_mech_step(void *conn_context __attribute__((unused)),
|
||||
sasl_server_params_t *sparams,
|
||||
const char *clientin,
|
||||
unsigned clientinlen,
|
||||
const char **serverout,
|
||||
unsigned *serveroutlen,
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
char *clientdata;
|
||||
int result;
|
||||
|
||||
if (!sparams
|
||||
|| !serverout
|
||||
|| !serveroutlen
|
||||
|| !oparams) {
|
||||
PARAMERROR( sparams->utils );
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
*serverout = NULL;
|
||||
*serveroutlen = 0;
|
||||
|
||||
if (!clientin) {
|
||||
return SASL_CONTINUE;
|
||||
}
|
||||
|
||||
/* We force a truncation 255 characters (specified by RFC 2245) */
|
||||
if (clientinlen > 255) clientinlen = 255;
|
||||
|
||||
/* NULL-terminate the clientin... */
|
||||
clientdata = sparams->utils->malloc(clientinlen + 1);
|
||||
if (!clientdata) {
|
||||
MEMERROR(sparams->utils);
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
strncpy(clientdata, clientin, clientinlen);
|
||||
clientdata[clientinlen] = '\0';
|
||||
|
||||
sparams->utils->log(sparams->utils->conn,
|
||||
SASL_LOG_NOTE,
|
||||
"ANONYMOUS login: \"%s\"",
|
||||
clientdata);
|
||||
|
||||
if (clientdata != clientin)
|
||||
sparams->utils->free(clientdata);
|
||||
|
||||
result = sparams->canon_user(sparams->utils->conn,
|
||||
anonymous_id, 0,
|
||||
SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
|
||||
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
/* set oparams */
|
||||
oparams->doneflag = 1;
|
||||
oparams->mech_ssf = 0;
|
||||
oparams->maxoutbuf = 0;
|
||||
oparams->encode_context = NULL;
|
||||
oparams->encode = NULL;
|
||||
oparams->decode_context = NULL;
|
||||
oparams->decode = NULL;
|
||||
oparams->param_version = 0;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static sasl_server_plug_t anonymous_server_plugins[] =
|
||||
{
|
||||
{
|
||||
"ANONYMOUS", /* mech_name */
|
||||
0, /* max_ssf */
|
||||
SASL_SEC_NOPLAINTEXT, /* security_flags */
|
||||
SASL_FEAT_WANT_CLIENT_FIRST
|
||||
| SASL_FEAT_DONTUSE_USERPASSWD, /* features */
|
||||
NULL, /* glob_context */
|
||||
&anonymous_server_mech_new, /* mech_new */
|
||||
&anonymous_server_mech_step, /* mech_step */
|
||||
NULL, /* mech_dispose */
|
||||
NULL, /* mech_free */
|
||||
NULL, /* setpass */
|
||||
NULL, /* user_query */
|
||||
NULL, /* idle */
|
||||
NULL, /* mech_avail */
|
||||
NULL /* spare */
|
||||
}
|
||||
};
|
||||
|
||||
int anonymous_server_plug_init(const sasl_utils_t *utils,
|
||||
int maxversion,
|
||||
int *out_version,
|
||||
sasl_server_plug_t **pluglist,
|
||||
int *plugcount)
|
||||
{
|
||||
if (maxversion < SASL_SERVER_PLUG_VERSION) {
|
||||
SETERROR( utils, "ANONYMOUS version mismatch" );
|
||||
return SASL_BADVERS;
|
||||
}
|
||||
|
||||
*out_version = SASL_SERVER_PLUG_VERSION;
|
||||
*pluglist = anonymous_server_plugins;
|
||||
*plugcount = 1;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
/***************************** Client Section *****************************/
|
||||
|
||||
typedef struct client_context {
|
||||
char *out_buf;
|
||||
unsigned out_buf_len;
|
||||
} client_context_t;
|
||||
|
||||
static int
|
||||
anonymous_client_mech_new(void *glob_context __attribute__((unused)),
|
||||
sasl_client_params_t *cparams,
|
||||
void **conn_context)
|
||||
{
|
||||
client_context_t *text;
|
||||
|
||||
if (!conn_context) {
|
||||
PARAMERROR(cparams->utils);
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
/* holds state are in */
|
||||
text = cparams->utils->malloc(sizeof(client_context_t));
|
||||
if (text == NULL) {
|
||||
MEMERROR(cparams->utils);
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
memset(text, 0, sizeof(client_context_t));
|
||||
|
||||
*conn_context = text;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
anonymous_client_mech_step(void *conn_context,
|
||||
sasl_client_params_t *cparams,
|
||||
const char *serverin __attribute__((unused)),
|
||||
unsigned serverinlen,
|
||||
sasl_interact_t **prompt_need,
|
||||
const char **clientout,
|
||||
unsigned *clientoutlen,
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
client_context_t *text = (client_context_t *) conn_context;
|
||||
size_t userlen;
|
||||
char hostname[256];
|
||||
const char *user = NULL;
|
||||
int user_result = SASL_OK;
|
||||
int result;
|
||||
|
||||
if (!cparams
|
||||
|| !clientout
|
||||
|| !clientoutlen
|
||||
|| !oparams) {
|
||||
PARAMERROR( cparams->utils );
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
*clientout = NULL;
|
||||
*clientoutlen = 0;
|
||||
|
||||
if (serverinlen != 0) {
|
||||
SETERROR( cparams->utils,
|
||||
"Nonzero serverinlen in ANONYMOUS continue_step" );
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
/* check if sec layer strong enough */
|
||||
if (cparams->props.min_ssf > cparams->external_ssf) {
|
||||
SETERROR( cparams->utils, "SSF requested of ANONYMOUS plugin");
|
||||
return SASL_TOOWEAK;
|
||||
}
|
||||
|
||||
/* try to get the trace info */
|
||||
if (user == NULL) {
|
||||
user_result = _plug_get_userid(cparams->utils, &user, prompt_need);
|
||||
|
||||
if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) {
|
||||
return user_result;
|
||||
}
|
||||
}
|
||||
|
||||
/* free prompts we got */
|
||||
if (prompt_need && *prompt_need) {
|
||||
cparams->utils->free(*prompt_need);
|
||||
*prompt_need = NULL;
|
||||
}
|
||||
|
||||
/* if there are prompts not filled in */
|
||||
if (user_result == SASL_INTERACT) {
|
||||
/* make the prompt list */
|
||||
result =
|
||||
_plug_make_prompts(cparams->utils, prompt_need,
|
||||
user_result == SASL_INTERACT ?
|
||||
"Please enter anonymous identification" : NULL,
|
||||
"",
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
return SASL_INTERACT;
|
||||
}
|
||||
|
||||
if (!user || !*user) {
|
||||
user = anonymous_id;
|
||||
}
|
||||
userlen = strlen(user);
|
||||
|
||||
result = cparams->canon_user(cparams->utils->conn,
|
||||
anonymous_id, 0,
|
||||
SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
memset(hostname, 0, sizeof(hostname));
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
hostname[sizeof(hostname)-1] = '\0';
|
||||
|
||||
*clientoutlen = (unsigned) (userlen + strlen(hostname) + 1);
|
||||
|
||||
result = _plug_buf_alloc(cparams->utils, &text->out_buf,
|
||||
&text->out_buf_len, *clientoutlen);
|
||||
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
strcpy(text->out_buf, user);
|
||||
text->out_buf[userlen] = '@';
|
||||
/* use memcpy() instead of strcpy() so we don't add the NUL */
|
||||
memcpy(text->out_buf + userlen + 1, hostname, strlen(hostname));
|
||||
|
||||
*clientout = text->out_buf;
|
||||
|
||||
/* set oparams */
|
||||
oparams->doneflag = 1;
|
||||
oparams->mech_ssf = 0;
|
||||
oparams->maxoutbuf = 0;
|
||||
oparams->encode_context = NULL;
|
||||
oparams->encode = NULL;
|
||||
oparams->decode_context = NULL;
|
||||
oparams->decode = NULL;
|
||||
oparams->param_version = 0;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static void anonymous_client_dispose(void *conn_context,
|
||||
const sasl_utils_t *utils)
|
||||
{
|
||||
client_context_t *text = (client_context_t *) conn_context;
|
||||
|
||||
if(!text) return;
|
||||
|
||||
if (text->out_buf) utils->free(text->out_buf);
|
||||
|
||||
utils->free(text);
|
||||
}
|
||||
|
||||
static const unsigned long anonymous_required_prompts[] = {
|
||||
SASL_CB_LIST_END
|
||||
};
|
||||
|
||||
static sasl_client_plug_t anonymous_client_plugins[] =
|
||||
{
|
||||
{
|
||||
"ANONYMOUS", /* mech_name */
|
||||
0, /* max_ssf */
|
||||
SASL_SEC_NOPLAINTEXT, /* security_flags */
|
||||
SASL_FEAT_WANT_CLIENT_FIRST, /* features */
|
||||
anonymous_required_prompts, /* required_prompts */
|
||||
NULL, /* glob_context */
|
||||
&anonymous_client_mech_new, /* mech_new */
|
||||
&anonymous_client_mech_step, /* mech_step */
|
||||
&anonymous_client_dispose, /* mech_dispose */
|
||||
NULL, /* mech_free */
|
||||
NULL, /* idle */
|
||||
NULL, /* spare */
|
||||
NULL /* spare */
|
||||
}
|
||||
};
|
||||
|
||||
int anonymous_client_plug_init(const sasl_utils_t *utils,
|
||||
int maxversion,
|
||||
int *out_version,
|
||||
sasl_client_plug_t **pluglist,
|
||||
int *plugcount)
|
||||
{
|
||||
if (maxversion < SASL_CLIENT_PLUG_VERSION) {
|
||||
SETERROR( utils, "ANONYMOUS version mismatch" );
|
||||
return SASL_BADVERS;
|
||||
}
|
||||
|
||||
*out_version = SASL_CLIENT_PLUG_VERSION;
|
||||
*pluglist = anonymous_client_plugins;
|
||||
*plugcount = 1;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_anonymous_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_CLIENT_PLUG_INIT( anonymous )
|
||||
SASL_SERVER_PLUG_INIT( anonymous )
|
||||
|
||||
@@ -0,0 +1,689 @@
|
||||
/* CRAM-MD5 SASL plugin
|
||||
* Rob Siemborski
|
||||
* Tim Martin
|
||||
* $Id: cram.c,v 1.87 2011/09/07 13:19:44 murch Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_cram_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
/***************************** Common Section *****************************/
|
||||
|
||||
static const char plugin_id[] = "$Id: cram.c,v 1.87 2011/09/07 13:19:44 murch Exp $";
|
||||
|
||||
/* convert a string of 8bit chars to it's representation in hex
|
||||
* using lowercase letters
|
||||
*/
|
||||
static char *convert16(unsigned char *in, int inlen, const sasl_utils_t *utils)
|
||||
{
|
||||
static char hex[]="0123456789abcdef";
|
||||
int lup;
|
||||
char *out;
|
||||
|
||||
out = utils->malloc(inlen*2+1);
|
||||
if (out == NULL) return NULL;
|
||||
|
||||
for (lup=0; lup < inlen; lup++) {
|
||||
out[lup*2] = hex[in[lup] >> 4];
|
||||
out[lup*2+1] = hex[in[lup] & 15];
|
||||
}
|
||||
|
||||
out[lup*2] = 0;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
/***************************** Server Section *****************************/
|
||||
|
||||
typedef struct server_context {
|
||||
int state;
|
||||
|
||||
char *challenge;
|
||||
} server_context_t;
|
||||
|
||||
static int
|
||||
crammd5_server_mech_new(void *glob_context __attribute__((unused)),
|
||||
sasl_server_params_t *sparams,
|
||||
const char *challenge __attribute__((unused)),
|
||||
unsigned challen __attribute__((unused)),
|
||||
void **conn_context)
|
||||
{
|
||||
server_context_t *text;
|
||||
|
||||
/* holds state are in */
|
||||
text = sparams->utils->malloc(sizeof(server_context_t));
|
||||
if (text == NULL) {
|
||||
MEMERROR( sparams->utils );
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
memset(text, 0, sizeof(server_context_t));
|
||||
|
||||
text->state = 1;
|
||||
|
||||
*conn_context = text;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the current time (or part of it) in string form
|
||||
* maximum length=15
|
||||
*/
|
||||
static char *gettime(sasl_server_params_t *sparams)
|
||||
{
|
||||
char *ret;
|
||||
time_t t;
|
||||
|
||||
t=time(NULL);
|
||||
ret= sparams->utils->malloc(15);
|
||||
if (ret==NULL) return NULL;
|
||||
|
||||
/* the bottom bits are really the only random ones so if
|
||||
we overflow we don't want to loose them */
|
||||
snprintf(ret,15,"%lu",t%(0xFFFFFF));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *randomdigits(sasl_server_params_t *sparams)
|
||||
{
|
||||
unsigned int num;
|
||||
char *ret;
|
||||
unsigned char temp[5]; /* random 32-bit number */
|
||||
|
||||
sparams->utils->rand(sparams->utils->rpool,(char *) temp,4);
|
||||
num=(temp[0] * 256 * 256 * 256) +
|
||||
(temp[1] * 256 * 256) +
|
||||
(temp[2] * 256) +
|
||||
(temp[3] );
|
||||
|
||||
ret = sparams->utils->malloc(15); /* there's no way an unsigned can be longer than this right? */
|
||||
if (ret == NULL) return NULL;
|
||||
sprintf(ret, "%u", num);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
crammd5_server_mech_step1(server_context_t *text,
|
||||
sasl_server_params_t *sparams,
|
||||
const char *clientin __attribute__((unused)),
|
||||
unsigned clientinlen,
|
||||
const char **serverout,
|
||||
unsigned *serveroutlen,
|
||||
sasl_out_params_t *oparams __attribute__((unused)))
|
||||
{
|
||||
char *time, *randdigits;
|
||||
|
||||
/* we shouldn't have received anything */
|
||||
if (clientinlen != 0) {
|
||||
SETERROR(sparams->utils, "CRAM-MD5 does not accept inital data");
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
/* get time and a random number for the nonce */
|
||||
time = gettime(sparams);
|
||||
randdigits = randomdigits(sparams);
|
||||
if ((time == NULL) || (randdigits == NULL)) {
|
||||
MEMERROR( sparams->utils );
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
/* allocate some space for the challenge */
|
||||
text->challenge = sparams->utils->malloc(200 + 1);
|
||||
if (text->challenge == NULL) {
|
||||
MEMERROR(sparams->utils);
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
/* create the challenge */
|
||||
snprintf(text->challenge, 200, "<%s.%s@%s>", randdigits, time,
|
||||
sparams->serverFQDN);
|
||||
|
||||
*serverout = text->challenge;
|
||||
*serveroutlen = (unsigned) strlen(text->challenge);
|
||||
|
||||
/* free stuff */
|
||||
sparams->utils->free(time);
|
||||
sparams->utils->free(randdigits);
|
||||
|
||||
text->state = 2;
|
||||
|
||||
return SASL_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
crammd5_server_mech_step2(server_context_t *text,
|
||||
sasl_server_params_t *sparams,
|
||||
const char *clientin,
|
||||
unsigned clientinlen,
|
||||
const char **serverout __attribute__((unused)),
|
||||
unsigned *serveroutlen __attribute__((unused)),
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
char *userid = NULL;
|
||||
sasl_secret_t *sec = NULL;
|
||||
int pos;
|
||||
size_t len;
|
||||
int result = SASL_FAIL;
|
||||
const char *password_request[] = { SASL_AUX_PASSWORD,
|
||||
#if defined(OBSOLETE_CRAM_ATTR)
|
||||
"*cmusaslsecretCRAM-MD5",
|
||||
#endif
|
||||
NULL };
|
||||
struct propval auxprop_values[3];
|
||||
HMAC_MD5_CTX tmphmac;
|
||||
HMAC_MD5_STATE md5state;
|
||||
int clear_md5state = 0;
|
||||
char *digest_str = NULL;
|
||||
UINT4 digest[4];
|
||||
|
||||
/* extract userid; everything before last space */
|
||||
pos = clientinlen-1;
|
||||
while ((pos > 0) && (clientin[pos] != ' ')) pos--;
|
||||
|
||||
if (pos <= 0) {
|
||||
SETERROR( sparams->utils,"need authentication name");
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
userid = (char *) sparams->utils->malloc(pos+1);
|
||||
if (userid == NULL) {
|
||||
MEMERROR( sparams->utils);
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
/* copy authstr out */
|
||||
memcpy(userid, clientin, pos);
|
||||
userid[pos] = '\0';
|
||||
|
||||
result = sparams->utils->prop_request(sparams->propctx, password_request);
|
||||
if (result != SASL_OK) goto done;
|
||||
|
||||
/* this will trigger the getting of the aux properties */
|
||||
result = sparams->canon_user(sparams->utils->conn,
|
||||
userid, 0, SASL_CU_AUTHID | SASL_CU_AUTHZID,
|
||||
oparams);
|
||||
if (result != SASL_OK) goto done;
|
||||
|
||||
result = sparams->utils->prop_getnames(sparams->propctx,
|
||||
password_request,
|
||||
auxprop_values);
|
||||
if (result < 0 ||
|
||||
((!auxprop_values[0].name || !auxprop_values[0].values)
|
||||
#if defined(OBSOLETE_CRAM_ATTR)
|
||||
&& (!auxprop_values[1].name || !auxprop_values[1].values)
|
||||
#endif
|
||||
)) {
|
||||
/* We didn't find this username */
|
||||
sparams->utils->seterror(sparams->utils->conn,0,
|
||||
"no secret in database");
|
||||
result = sparams->transition ? SASL_TRANS : SASL_NOUSER;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (auxprop_values[0].name && auxprop_values[0].values) {
|
||||
len = strlen(auxprop_values[0].values[0]);
|
||||
if (len == 0) {
|
||||
sparams->utils->seterror(sparams->utils->conn,0,
|
||||
"empty secret");
|
||||
result = SASL_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
sec = sparams->utils->malloc(sizeof(sasl_secret_t) + len);
|
||||
if (!sec) goto done;
|
||||
|
||||
sec->len = (unsigned) len;
|
||||
strncpy((char *)sec->data, auxprop_values[0].values[0], len + 1);
|
||||
|
||||
clear_md5state = 1;
|
||||
/* Do precalculation on plaintext secret */
|
||||
sparams->utils->hmac_md5_precalc(&md5state, /* OUT */
|
||||
sec->data,
|
||||
sec->len);
|
||||
#if defined(OBSOLETE_CRAM_ATTR)
|
||||
} else if (auxprop_values[1].name && auxprop_values[1].values) {
|
||||
/* We have a precomputed secret */
|
||||
memcpy(&md5state, auxprop_values[1].values[0],
|
||||
sizeof(HMAC_MD5_STATE));
|
||||
#endif
|
||||
} else {
|
||||
sparams->utils->seterror(sparams->utils->conn, 0,
|
||||
"Have neither type of secret");
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
/* erase the plaintext password */
|
||||
sparams->utils->prop_erase(sparams->propctx, password_request[0]);
|
||||
|
||||
/* ok this is annoying:
|
||||
so we have this half-way hmac transform instead of the plaintext
|
||||
that means we half to:
|
||||
-import it back into a md5 context
|
||||
-do an md5update with the nonce
|
||||
-finalize it
|
||||
*/
|
||||
sparams->utils->hmac_md5_import(&tmphmac, (HMAC_MD5_STATE *) &md5state);
|
||||
sparams->utils->MD5Update(&(tmphmac.ictx),
|
||||
(const unsigned char *) text->challenge,
|
||||
(unsigned) strlen(text->challenge));
|
||||
sparams->utils->hmac_md5_final((unsigned char *) &digest, &tmphmac);
|
||||
|
||||
/* convert to base 16 with lower case letters */
|
||||
digest_str = convert16((unsigned char *) digest, 16, sparams->utils);
|
||||
|
||||
/* if same then verified
|
||||
* - we know digest_str is null terminated but clientin might not be
|
||||
* - verify the length of clientin anyway!
|
||||
*/
|
||||
len = strlen(digest_str);
|
||||
if (clientinlen-pos-1 < len ||
|
||||
strncmp(digest_str, clientin+pos+1, len) != 0) {
|
||||
sparams->utils->seterror(sparams->utils->conn, 0,
|
||||
"incorrect digest response");
|
||||
result = SASL_BADAUTH;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* set oparams */
|
||||
oparams->doneflag = 1;
|
||||
oparams->mech_ssf = 0;
|
||||
oparams->maxoutbuf = 0;
|
||||
oparams->encode_context = NULL;
|
||||
oparams->encode = NULL;
|
||||
oparams->decode_context = NULL;
|
||||
oparams->decode = NULL;
|
||||
oparams->param_version = 0;
|
||||
|
||||
result = SASL_OK;
|
||||
|
||||
done:
|
||||
if (userid) sparams->utils->free(userid);
|
||||
if (sec) _plug_free_secret(sparams->utils, &sec);
|
||||
|
||||
if (digest_str) sparams->utils->free(digest_str);
|
||||
if (clear_md5state) memset(&md5state, 0, sizeof(md5state));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int crammd5_server_mech_step(void *conn_context,
|
||||
sasl_server_params_t *sparams,
|
||||
const char *clientin,
|
||||
unsigned clientinlen,
|
||||
const char **serverout,
|
||||
unsigned *serveroutlen,
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
server_context_t *text = (server_context_t *) conn_context;
|
||||
|
||||
*serverout = NULL;
|
||||
*serveroutlen = 0;
|
||||
|
||||
if (text == NULL) {
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
/* this should be well more than is ever needed */
|
||||
if (clientinlen > 1024) {
|
||||
SETERROR(sparams->utils, "CRAM-MD5 input longer than 1024 bytes");
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
switch (text->state) {
|
||||
|
||||
case 1:
|
||||
return crammd5_server_mech_step1(text, sparams,
|
||||
clientin, clientinlen,
|
||||
serverout, serveroutlen,
|
||||
oparams);
|
||||
|
||||
case 2:
|
||||
return crammd5_server_mech_step2(text, sparams,
|
||||
clientin, clientinlen,
|
||||
serverout, serveroutlen,
|
||||
oparams);
|
||||
|
||||
default: /* should never get here */
|
||||
sparams->utils->log(NULL, SASL_LOG_ERR,
|
||||
"Invalid CRAM-MD5 server step %d\n", text->state);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
return SASL_FAIL; /* should never get here */
|
||||
}
|
||||
|
||||
static void crammd5_server_mech_dispose(void *conn_context,
|
||||
const sasl_utils_t *utils)
|
||||
{
|
||||
server_context_t *text = (server_context_t *) conn_context;
|
||||
|
||||
if (!text) return;
|
||||
|
||||
if (text->challenge) _plug_free_string(utils,&(text->challenge));
|
||||
|
||||
utils->free(text);
|
||||
}
|
||||
|
||||
static sasl_server_plug_t crammd5_server_plugins[] =
|
||||
{
|
||||
{
|
||||
"CRAM-MD5", /* mech_name */
|
||||
0, /* max_ssf */
|
||||
SASL_SEC_NOPLAINTEXT
|
||||
| SASL_SEC_NOANONYMOUS, /* security_flags */
|
||||
SASL_FEAT_SERVER_FIRST, /* features */
|
||||
NULL, /* glob_context */
|
||||
&crammd5_server_mech_new, /* mech_new */
|
||||
&crammd5_server_mech_step, /* mech_step */
|
||||
&crammd5_server_mech_dispose, /* mech_dispose */
|
||||
NULL, /* mech_free */
|
||||
NULL, /* setpass */
|
||||
NULL, /* user_query */
|
||||
NULL, /* idle */
|
||||
NULL, /* mech avail */
|
||||
NULL /* spare */
|
||||
}
|
||||
};
|
||||
|
||||
int crammd5_server_plug_init(const sasl_utils_t *utils,
|
||||
int maxversion,
|
||||
int *out_version,
|
||||
sasl_server_plug_t **pluglist,
|
||||
int *plugcount)
|
||||
{
|
||||
if (maxversion < SASL_SERVER_PLUG_VERSION) {
|
||||
SETERROR( utils, "CRAM version mismatch");
|
||||
return SASL_BADVERS;
|
||||
}
|
||||
|
||||
*out_version = SASL_SERVER_PLUG_VERSION;
|
||||
*pluglist = crammd5_server_plugins;
|
||||
*plugcount = 1;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
/***************************** Client Section *****************************/
|
||||
|
||||
typedef struct client_context {
|
||||
char *out_buf;
|
||||
unsigned out_buf_len;
|
||||
} client_context_t;
|
||||
|
||||
static int crammd5_client_mech_new(void *glob_context __attribute__((unused)),
|
||||
sasl_client_params_t *params,
|
||||
void **conn_context)
|
||||
{
|
||||
client_context_t *text;
|
||||
|
||||
/* holds state are in */
|
||||
text = params->utils->malloc(sizeof(client_context_t));
|
||||
if (text == NULL) {
|
||||
MEMERROR(params->utils);
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
memset(text, 0, sizeof(client_context_t));
|
||||
|
||||
*conn_context = text;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static char *make_hashed(sasl_secret_t *sec, char *nonce, int noncelen,
|
||||
const sasl_utils_t *utils)
|
||||
{
|
||||
unsigned char digest[24];
|
||||
char *in16;
|
||||
|
||||
if (sec == NULL) return NULL;
|
||||
|
||||
/* do the hmac md5 hash output 128 bits */
|
||||
utils->hmac_md5((unsigned char *) nonce, noncelen,
|
||||
sec->data, sec->len, digest);
|
||||
|
||||
/* convert that to hex form */
|
||||
in16 = convert16(digest, 16, utils);
|
||||
if (in16 == NULL) return NULL;
|
||||
|
||||
return in16;
|
||||
}
|
||||
|
||||
static int crammd5_client_mech_step(void *conn_context,
|
||||
sasl_client_params_t *params,
|
||||
const char *serverin,
|
||||
unsigned serverinlen,
|
||||
sasl_interact_t **prompt_need,
|
||||
const char **clientout,
|
||||
unsigned *clientoutlen,
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
client_context_t *text = (client_context_t *) conn_context;
|
||||
const char *authid = NULL;
|
||||
sasl_secret_t *password = NULL;
|
||||
unsigned int free_password = 0; /* set if we need to free password */
|
||||
int auth_result = SASL_OK;
|
||||
int pass_result = SASL_OK;
|
||||
int result;
|
||||
size_t maxsize;
|
||||
char *in16 = NULL;
|
||||
|
||||
*clientout = NULL;
|
||||
*clientoutlen = 0;
|
||||
|
||||
/* First check for absurd lengths */
|
||||
if (serverinlen > 1024) {
|
||||
params->utils->seterror(params->utils->conn, 0,
|
||||
"CRAM-MD5 input longer than 1024 bytes");
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
/* check if sec layer strong enough */
|
||||
if (params->props.min_ssf > params->external_ssf) {
|
||||
SETERROR( params->utils, "SSF requested of CRAM-MD5 plugin");
|
||||
return SASL_TOOWEAK;
|
||||
}
|
||||
|
||||
/* try to get the userid */
|
||||
if (oparams->authid == NULL) {
|
||||
auth_result=_plug_get_authid(params->utils, &authid, prompt_need);
|
||||
|
||||
if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT))
|
||||
return auth_result;
|
||||
}
|
||||
|
||||
/* try to get the password */
|
||||
if (password == NULL) {
|
||||
pass_result=_plug_get_password(params->utils, &password,
|
||||
&free_password, prompt_need);
|
||||
|
||||
if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT))
|
||||
return pass_result;
|
||||
}
|
||||
|
||||
/* free prompts we got */
|
||||
if (prompt_need && *prompt_need) {
|
||||
params->utils->free(*prompt_need);
|
||||
*prompt_need = NULL;
|
||||
}
|
||||
|
||||
/* if there are prompts not filled in */
|
||||
if ((auth_result == SASL_INTERACT) || (pass_result == SASL_INTERACT)) {
|
||||
/* make the prompt list */
|
||||
result =
|
||||
_plug_make_prompts(params->utils, prompt_need,
|
||||
NULL, NULL,
|
||||
auth_result == SASL_INTERACT ?
|
||||
"Please enter your authentication name" : NULL,
|
||||
NULL,
|
||||
pass_result == SASL_INTERACT ?
|
||||
"Please enter your password" : NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
if (result != SASL_OK) goto cleanup;
|
||||
|
||||
return SASL_INTERACT;
|
||||
}
|
||||
|
||||
if (!password) {
|
||||
PARAMERROR(params->utils);
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
result = params->canon_user(params->utils->conn, authid, 0,
|
||||
SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
|
||||
if (result != SASL_OK) goto cleanup;
|
||||
|
||||
/*
|
||||
* username SP digest (keyed md5 where key is passwd)
|
||||
*/
|
||||
|
||||
in16 = make_hashed(password, (char *) serverin, serverinlen,
|
||||
params->utils);
|
||||
|
||||
if (in16 == NULL) {
|
||||
SETERROR(params->utils, "whoops, make_hashed failed us this time");
|
||||
result = SASL_FAIL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
maxsize = 32+1+strlen(oparams->authid)+30;
|
||||
result = _plug_buf_alloc(params->utils, &(text->out_buf),
|
||||
&(text->out_buf_len), (unsigned) maxsize);
|
||||
if (result != SASL_OK) goto cleanup;
|
||||
|
||||
snprintf(text->out_buf, maxsize, "%s %s", oparams->authid, in16);
|
||||
|
||||
*clientout = text->out_buf;
|
||||
*clientoutlen = (unsigned) strlen(*clientout);
|
||||
|
||||
/* set oparams */
|
||||
oparams->doneflag = 1;
|
||||
oparams->mech_ssf = 0;
|
||||
oparams->maxoutbuf = 0;
|
||||
oparams->encode_context = NULL;
|
||||
oparams->encode = NULL;
|
||||
oparams->decode_context = NULL;
|
||||
oparams->decode = NULL;
|
||||
oparams->param_version = 0;
|
||||
|
||||
result = SASL_OK;
|
||||
|
||||
cleanup:
|
||||
/* get rid of private information */
|
||||
if (in16) _plug_free_string(params->utils, &in16);
|
||||
|
||||
/* get rid of all sensitive info */
|
||||
if (free_password) _plug_free_secret(params-> utils, &password);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void crammd5_client_mech_dispose(void *conn_context,
|
||||
const sasl_utils_t *utils)
|
||||
{
|
||||
client_context_t *text = (client_context_t *) conn_context;
|
||||
|
||||
if (!text) return;
|
||||
|
||||
if (text->out_buf) utils->free(text->out_buf);
|
||||
|
||||
utils->free(text);
|
||||
}
|
||||
|
||||
static sasl_client_plug_t crammd5_client_plugins[] =
|
||||
{
|
||||
{
|
||||
"CRAM-MD5", /* mech_name */
|
||||
0, /* max_ssf */
|
||||
SASL_SEC_NOPLAINTEXT
|
||||
| SASL_SEC_NOANONYMOUS, /* security_flags */
|
||||
SASL_FEAT_SERVER_FIRST, /* features */
|
||||
NULL, /* required_prompts */
|
||||
NULL, /* glob_context */
|
||||
&crammd5_client_mech_new, /* mech_new */
|
||||
&crammd5_client_mech_step, /* mech_step */
|
||||
&crammd5_client_mech_dispose, /* mech_dispose */
|
||||
NULL, /* mech_free */
|
||||
NULL, /* idle */
|
||||
NULL, /* spare */
|
||||
NULL /* spare */
|
||||
}
|
||||
};
|
||||
|
||||
int crammd5_client_plug_init(const sasl_utils_t *utils,
|
||||
int maxversion,
|
||||
int *out_version,
|
||||
sasl_client_plug_t **pluglist,
|
||||
int *plugcount)
|
||||
{
|
||||
if (maxversion < SASL_CLIENT_PLUG_VERSION) {
|
||||
SETERROR( utils, "CRAM version mismatch");
|
||||
return SASL_BADVERS;
|
||||
}
|
||||
|
||||
*out_version = SASL_CLIENT_PLUG_VERSION;
|
||||
*pluglist = crammd5_client_plugins;
|
||||
*plugcount = 1;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_crammd5_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_CLIENT_PLUG_INIT( crammd5 )
|
||||
SASL_SERVER_PLUG_INIT( crammd5 )
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_digestmd5_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_CLIENT_PLUG_INIT( digestmd5 )
|
||||
SASL_SERVER_PLUG_INIT( digestmd5 )
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_gs2_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_CLIENT_PLUG_INIT( gs2 )
|
||||
SASL_SERVER_PLUG_INIT( gs2 )
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
* Copyright (c) 2011, PADL Software Pty Ltd.
|
||||
* 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. Neither the name of PADL Software nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS 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 PADL SOFTWARE OR CONTRIBUTORS 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.
|
||||
*/
|
||||
/*
|
||||
* Copyright 1993 by OpenVision Technologies, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appears in all copies and
|
||||
* that both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of OpenVision not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. OpenVision makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gs2_token.h"
|
||||
|
||||
/*
|
||||
* $Id: gs2_token.c,v 1.2 2011/05/23 14:45:40 mel Exp $
|
||||
*/
|
||||
|
||||
#ifndef HAVE_GSS_ENCAPSULATE_TOKEN
|
||||
/* XXXX this code currently makes the assumption that a mech oid will
|
||||
never be longer than 127 bytes. This assumption is not inherent in
|
||||
the interfaces, so the code can be fixed if the OSI namespace
|
||||
balloons unexpectedly. */
|
||||
|
||||
/*
|
||||
* Each token looks like this:
|
||||
* 0x60 tag for APPLICATION 0, SEQUENCE
|
||||
* (constructed, definite-length)
|
||||
* <length> possible multiple bytes, need to parse/generate
|
||||
* 0x06 tag for OBJECT IDENTIFIER
|
||||
* <moid_length> compile-time constant string (assume 1 byte)
|
||||
* <moid_bytes> compile-time constant string
|
||||
* <inner_bytes> the ANY containing the application token
|
||||
* bytes 0,1 are the token type
|
||||
* bytes 2,n are the token data
|
||||
*
|
||||
* Note that the token type field is a feature of RFC 1964 mechanisms and
|
||||
* is not used by other GSSAPI mechanisms. As such, a token type of -1
|
||||
* is interpreted to mean that no token type should be expected or
|
||||
* generated.
|
||||
*
|
||||
* For the purposes of this abstraction, the token "header" consists of
|
||||
* the sequence tag and length octets, the mech OID DER encoding, and the
|
||||
* first two inner bytes, which indicate the token type. The token
|
||||
* "body" consists of everything else.
|
||||
*/
|
||||
|
||||
static size_t
|
||||
der_length_size(size_t length)
|
||||
{
|
||||
if (length < (1<<7))
|
||||
return 1;
|
||||
else if (length < (1<<8))
|
||||
return 2;
|
||||
#if INT_MAX == 0x7fff
|
||||
else
|
||||
return 3;
|
||||
#else
|
||||
else if (length < (1<<16))
|
||||
return 3;
|
||||
else if (length < (1<<24))
|
||||
return 4;
|
||||
else
|
||||
return 5;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
der_write_length(unsigned char **buf, size_t length)
|
||||
{
|
||||
if (length < (1<<7)) {
|
||||
*(*buf)++ = (unsigned char)length;
|
||||
} else {
|
||||
*(*buf)++ = (unsigned char)(der_length_size(length)+127);
|
||||
#if INT_MAX > 0x7fff
|
||||
if (length >= (1<<24))
|
||||
*(*buf)++ = (unsigned char)(length>>24);
|
||||
if (length >= (1<<16))
|
||||
*(*buf)++ = (unsigned char)((length>>16)&0xff);
|
||||
#endif
|
||||
if (length >= (1<<8))
|
||||
*(*buf)++ = (unsigned char)((length>>8)&0xff);
|
||||
*(*buf)++ = (unsigned char)(length&0xff);
|
||||
}
|
||||
}
|
||||
|
||||
/* returns the length of a token, given the mech oid and the body size */
|
||||
|
||||
static size_t
|
||||
token_size(const gss_OID_desc *mech, size_t body_size)
|
||||
{
|
||||
/* set body_size to sequence contents size */
|
||||
body_size += 2 + (size_t) mech->length; /* NEED overflow check */
|
||||
return 1 + der_length_size(body_size) + body_size;
|
||||
}
|
||||
|
||||
/* fills in a buffer with the token header. The buffer is assumed to
|
||||
be the right size. buf is advanced past the token header */
|
||||
|
||||
static void
|
||||
make_token_header(
|
||||
const gss_OID_desc *mech,
|
||||
size_t body_size,
|
||||
unsigned char **buf)
|
||||
{
|
||||
*(*buf)++ = 0x60;
|
||||
der_write_length(buf, 2 + mech->length + body_size);
|
||||
*(*buf)++ = 0x06;
|
||||
*(*buf)++ = (unsigned char)mech->length;
|
||||
memcpy(*buf, mech->elements, mech->length);
|
||||
*buf += mech->length;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
gs2_encapsulate_token(const gss_buffer_t input_token,
|
||||
const gss_OID token_oid,
|
||||
gss_buffer_t output_token)
|
||||
{
|
||||
size_t tokenSize;
|
||||
unsigned char *buf;
|
||||
|
||||
if (input_token == GSS_C_NO_BUFFER || token_oid == GSS_C_NO_OID)
|
||||
return GSS_S_CALL_INACCESSIBLE_READ;
|
||||
|
||||
if (output_token == GSS_C_NO_BUFFER)
|
||||
return GSS_S_CALL_INACCESSIBLE_WRITE;
|
||||
|
||||
tokenSize = token_size(token_oid, input_token->length);
|
||||
|
||||
output_token->value = malloc(tokenSize);
|
||||
if (output_token->value == NULL)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
buf = output_token->value;
|
||||
|
||||
make_token_header(token_oid, input_token->length, &buf);
|
||||
memcpy(buf, input_token->value, input_token->length);
|
||||
output_token->length = tokenSize;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_GSS_DECAPSULATE_TOKEN
|
||||
/* returns decoded length, or < 0 on failure. Advances buf and
|
||||
decrements bufsize */
|
||||
|
||||
static int
|
||||
der_read_length(unsigned char **buf, ssize_t *bufsize)
|
||||
{
|
||||
unsigned char sf;
|
||||
int ret;
|
||||
|
||||
if (*bufsize < 1)
|
||||
return -1;
|
||||
|
||||
sf = *(*buf)++;
|
||||
(*bufsize)--;
|
||||
if (sf & 0x80) {
|
||||
if ((sf &= 0x7f) > ((*bufsize)-1))
|
||||
return -1;
|
||||
if (sf > sizeof(int))
|
||||
return -1;
|
||||
ret = 0;
|
||||
for (; sf; sf--) {
|
||||
ret = (ret<<8) + (*(*buf)++);
|
||||
(*bufsize)--;
|
||||
}
|
||||
} else {
|
||||
ret = sf;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a buffer containing a token, reads and verifies the token,
|
||||
* leaving buf advanced past the token header, and setting body_size
|
||||
* to the number of remaining bytes. Returns 0 on success,
|
||||
* G_BAD_TOK_HEADER for a variety of errors, and G_WRONG_MECH if the
|
||||
* mechanism in the token does not match the mech argument. buf and
|
||||
* *body_size are left unmodified on error.
|
||||
*/
|
||||
|
||||
static OM_uint32
|
||||
verify_token_header(OM_uint32 *minor,
|
||||
const gss_OID mech,
|
||||
size_t *body_size,
|
||||
unsigned char **buf_in,
|
||||
size_t toksize_in)
|
||||
{
|
||||
unsigned char *buf = *buf_in;
|
||||
ssize_t seqsize;
|
||||
gss_OID_desc toid;
|
||||
ssize_t toksize = (ssize_t)toksize_in;
|
||||
|
||||
*minor = 0;
|
||||
|
||||
if ((toksize -= 1) < 0)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
if (*buf++ != 0x60)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
seqsize = der_read_length(&buf, &toksize);
|
||||
if (seqsize < 0)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
if (seqsize != toksize)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
if ((toksize -= 1) < 0)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
if (*buf++ != 0x06)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
if ((toksize -= 1) < 0)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
toid.length = *buf++;
|
||||
|
||||
if ((toksize -= toid.length) < 0)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
toid.elements = buf;
|
||||
buf += toid.length;
|
||||
|
||||
if (!gss_oid_equal(&toid, mech))
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
*buf_in = buf;
|
||||
*body_size = toksize;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
|
||||
OM_uint32
|
||||
gs2_decapsulate_token(const gss_buffer_t input_token,
|
||||
const gss_OID token_oid,
|
||||
gss_buffer_t output_token)
|
||||
{
|
||||
OM_uint32 major, minor;
|
||||
size_t body_size = 0;
|
||||
unsigned char *buf_in;
|
||||
|
||||
if (input_token == GSS_C_NO_BUFFER || token_oid == GSS_C_NO_OID)
|
||||
return GSS_S_CALL_INACCESSIBLE_READ;
|
||||
|
||||
if (output_token == GSS_C_NO_BUFFER)
|
||||
return GSS_S_CALL_INACCESSIBLE_WRITE;
|
||||
|
||||
buf_in = input_token->value;
|
||||
|
||||
major = verify_token_header(&minor, token_oid, &body_size, &buf_in,
|
||||
input_token->length);
|
||||
if (minor != 0)
|
||||
return GSS_S_DEFECTIVE_TOKEN;
|
||||
|
||||
output_token->value = malloc(body_size);
|
||||
if (output_token->value == NULL)
|
||||
return GSS_S_FAILURE;
|
||||
|
||||
memcpy(output_token->value, buf_in, body_size);
|
||||
output_token->length = body_size;
|
||||
|
||||
return GSS_S_COMPLETE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GSS_OID_EQUAL
|
||||
int
|
||||
gs2_oid_equal(const gss_OID o1, const gss_OID o2)
|
||||
{
|
||||
return o1->length == o2->length &&
|
||||
(memcmp(o1->elements, o2->elements, o1->length) == 0);
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 1993 by OpenVision Technologies, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, distribute, and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appears in all copies and
|
||||
* that both that copyright notice and this permission notice appear in
|
||||
* supporting documentation, and that the name of OpenVision not be used
|
||||
* in advertising or publicity pertaining to distribution of the software
|
||||
* without specific, written prior permission. OpenVision makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
* OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
* EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _GS2_TOKEN_H_
|
||||
#define _GS2_TOKEN_H_ 1
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <gssapi/gssapi.h>
|
||||
|
||||
#ifndef KRB5_HEIMDAL
|
||||
#ifdef HAVE_GSSAPI_GSSAPI_EXT_H
|
||||
#include <gssapi/gssapi_ext.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GSS_DECAPSULATE_TOKEN
|
||||
OM_uint32
|
||||
gs2_decapsulate_token(const gss_buffer_t input_token,
|
||||
const gss_OID token_oid,
|
||||
gss_buffer_t output_token);
|
||||
#define gss_decapsulate_token gs2_decapsulate_token
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GSS_ENCAPSULATE_TOKEN
|
||||
OM_uint32
|
||||
gs2_encapsulate_token(const gss_buffer_t input_token,
|
||||
const gss_OID token_oid,
|
||||
gss_buffer_t output_token);
|
||||
#define gss_encapsulate_token gs2_encapsulate_token
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GSS_OID_EQUAL
|
||||
int
|
||||
gs2_oid_equal(const gss_OID o1, const gss_OID o2);
|
||||
#define gss_oid_equal gs2_oid_equal
|
||||
#endif
|
||||
|
||||
#endif /* _GS2_TOKEN_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_gssapiv2_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_CLIENT_PLUG_INIT( gssapiv2 )
|
||||
SASL_SERVER_PLUG_INIT( gssapiv2 )
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_kerberos4_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_CLIENT_PLUG_INIT( kerberos4 )
|
||||
SASL_SERVER_PLUG_INIT( kerberos4 )
|
||||
|
||||
@@ -0,0 +1,569 @@
|
||||
/* $OpenLDAP: pkg/ldap/contrib/ldapsasl/ldapdb.c,v 1.1.2.7 2003/11/29 22:10:03 hyc Exp $ */
|
||||
/* SASL LDAP auxprop+canonuser implementation
|
||||
* Copyright (C) 2002-2007 Howard Chu, All rights reserved. <hyc@symas.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted only as authorized by the OpenLDAP
|
||||
* Public License.
|
||||
*
|
||||
* A copy of this license is available in the file LICENSE in the
|
||||
* top-level directory of the distribution or, alternatively, at
|
||||
* <http://www.OpenLDAP.org/license.html>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "sasl.h"
|
||||
#include "saslutil.h"
|
||||
#include "saslplug.h"
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#include <ldap.h>
|
||||
|
||||
static char ldapdb[] = "ldapdb";
|
||||
|
||||
typedef struct ldapctx {
|
||||
int inited; /* Have we already read the config? */
|
||||
const char *uri; /* URI of LDAP server */
|
||||
struct berval id; /* SASL authcid to bind as */
|
||||
struct berval pw; /* password for bind */
|
||||
struct berval mech; /* SASL mech */
|
||||
int use_tls; /* Issue StartTLS request? */
|
||||
struct berval canon; /* Use attr in user entry for canonical name */
|
||||
} ldapctx;
|
||||
|
||||
static ldapctx ldapdb_ctx;
|
||||
|
||||
static int ldapdb_interact(LDAP *ld, unsigned flags __attribute__((unused)),
|
||||
void *def, void *inter)
|
||||
{
|
||||
sasl_interact_t *in = inter;
|
||||
ldapctx *ctx = def;
|
||||
struct berval p;
|
||||
|
||||
for (;in->id != SASL_CB_LIST_END;in++)
|
||||
{
|
||||
p.bv_val = NULL;
|
||||
switch(in->id)
|
||||
{
|
||||
case SASL_CB_GETREALM:
|
||||
ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &p.bv_val);
|
||||
if (p.bv_val) p.bv_len = strlen(p.bv_val);
|
||||
break;
|
||||
case SASL_CB_AUTHNAME:
|
||||
p = ctx->id;
|
||||
break;
|
||||
case SASL_CB_PASS:
|
||||
p = ctx->pw;
|
||||
break;
|
||||
}
|
||||
if (p.bv_val)
|
||||
{
|
||||
in->result = p.bv_val;
|
||||
in->len = p.bv_len;
|
||||
}
|
||||
}
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct connparm {
|
||||
LDAP *ld;
|
||||
LDAPControl c;
|
||||
LDAPControl *ctrl[2];
|
||||
struct berval *dn;
|
||||
} connparm;
|
||||
|
||||
static int ldapdb_connect(ldapctx *ctx, sasl_server_params_t *sparams,
|
||||
const char *user, unsigned ulen, connparm *cp)
|
||||
{
|
||||
int i;
|
||||
char *authzid;
|
||||
|
||||
if((i=ldap_initialize(&cp->ld, ctx->uri))) {
|
||||
return i;
|
||||
}
|
||||
|
||||
authzid = sparams->utils->malloc(ulen + sizeof("u:"));
|
||||
if (!authzid) {
|
||||
return LDAP_NO_MEMORY;
|
||||
}
|
||||
strcpy(authzid, "u:");
|
||||
strcpy(authzid+2, user);
|
||||
cp->c.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
|
||||
cp->c.ldctl_value.bv_val = authzid;
|
||||
cp->c.ldctl_value.bv_len = ulen + 2;
|
||||
cp->c.ldctl_iscritical = 1;
|
||||
|
||||
i = LDAP_VERSION3;
|
||||
ldap_set_option(cp->ld, LDAP_OPT_PROTOCOL_VERSION, &i);
|
||||
|
||||
/* If TLS is set and it fails, continue or bail out as requested */
|
||||
if (ctx->use_tls && (i=ldap_start_tls_s(cp->ld, NULL, NULL)) != LDAP_SUCCESS
|
||||
&& ctx->use_tls > 1) {
|
||||
sparams->utils->free(authzid);
|
||||
return i;
|
||||
}
|
||||
|
||||
i = ldap_sasl_interactive_bind_s(cp->ld, NULL, ctx->mech.bv_val, NULL,
|
||||
NULL, LDAP_SASL_QUIET, ldapdb_interact, ctx);
|
||||
if (i != LDAP_SUCCESS) {
|
||||
sparams->utils->free(authzid);
|
||||
return i;
|
||||
}
|
||||
|
||||
cp->ctrl[0] = &cp->c;
|
||||
cp->ctrl[1] = NULL;
|
||||
i = ldap_whoami_s(cp->ld, &cp->dn, cp->ctrl, NULL);
|
||||
if (i == LDAP_SUCCESS && cp->dn) {
|
||||
if (!cp->dn->bv_val || strncmp(cp->dn->bv_val, "dn:", 3)) {
|
||||
ber_bvfree(cp->dn);
|
||||
cp->dn = NULL;
|
||||
i = LDAP_INVALID_SYNTAX;
|
||||
} else {
|
||||
cp->c.ldctl_value = *(cp->dn);
|
||||
}
|
||||
}
|
||||
sparams->utils->free(authzid);
|
||||
return i;
|
||||
}
|
||||
|
||||
static int ldapdb_auxprop_lookup(void *glob_context,
|
||||
sasl_server_params_t *sparams,
|
||||
unsigned flags,
|
||||
const char *user,
|
||||
unsigned ulen)
|
||||
{
|
||||
ldapctx *ctx = glob_context;
|
||||
connparm cp;
|
||||
int ret, i, n, *aindx;
|
||||
int result;
|
||||
int j;
|
||||
const struct propval *pr;
|
||||
struct berval **bvals;
|
||||
LDAPMessage *msg, *res;
|
||||
char **attrs = NULL;
|
||||
|
||||
if(!ctx || !sparams || !user) return SASL_BADPARAM;
|
||||
|
||||
pr = sparams->utils->prop_get(sparams->propctx);
|
||||
if (!pr) return SASL_FAIL;
|
||||
|
||||
/* count how many attrs to fetch */
|
||||
for(i = 0, n = 0; pr[i].name; i++) {
|
||||
if(pr[i].name[0] == '*' && (flags & SASL_AUXPROP_AUTHZID))
|
||||
continue;
|
||||
if(pr[i].values && !(flags & SASL_AUXPROP_OVERRIDE))
|
||||
continue;
|
||||
n++;
|
||||
}
|
||||
|
||||
/* nothing to do, bail out */
|
||||
if (!n) return SASL_OK;
|
||||
|
||||
/* alloc an array of attr names for search, and index to the props */
|
||||
attrs = sparams->utils->malloc((n+1)*sizeof(char *)*2);
|
||||
if (!attrs) {
|
||||
result = SASL_NOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
aindx = (int *)(attrs + n + 1);
|
||||
|
||||
/* copy attr list */
|
||||
for (i=0, n=0; pr[i].name; i++) {
|
||||
if(pr[i].name[0] == '*' && (flags & SASL_AUXPROP_AUTHZID))
|
||||
continue;
|
||||
if(pr[i].values && !(flags & SASL_AUXPROP_OVERRIDE))
|
||||
continue;
|
||||
attrs[n] = (char *)pr[i].name;
|
||||
if (pr[i].name[0] == '*') attrs[n]++;
|
||||
aindx[n] = i;
|
||||
n++;
|
||||
}
|
||||
attrs[n] = NULL;
|
||||
|
||||
if ((ret = ldapdb_connect(ctx, sparams, user, ulen, &cp)) != LDAP_SUCCESS) {
|
||||
goto process_ldap_error;
|
||||
}
|
||||
|
||||
ret = ldap_search_ext_s(cp.ld, cp.dn->bv_val+3, LDAP_SCOPE_BASE,
|
||||
"(objectclass=*)", attrs, 0, cp.ctrl, NULL, NULL, 1, &res);
|
||||
ber_bvfree(cp.dn);
|
||||
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
goto process_ldap_error;
|
||||
}
|
||||
|
||||
/* Assume no user by default */
|
||||
ret = LDAP_NO_SUCH_OBJECT;
|
||||
|
||||
for (msg = ldap_first_message(cp.ld, res);
|
||||
msg;
|
||||
msg = ldap_next_message(cp.ld, msg)) {
|
||||
if (ldap_msgtype(msg) != LDAP_RES_SEARCH_ENTRY) continue;
|
||||
|
||||
/* Presence of a search result response indicates that the user exists */
|
||||
ret = LDAP_SUCCESS;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
bvals = ldap_get_values_len(cp.ld, msg, attrs[i]);
|
||||
if (!bvals) continue;
|
||||
|
||||
if (pr[aindx[i]].values) {
|
||||
sparams->utils->prop_erase(sparams->propctx, pr[aindx[i]].name);
|
||||
}
|
||||
|
||||
for ( j = 0; bvals[j] != NULL; j++ ) {
|
||||
sparams->utils->prop_set(sparams->propctx,
|
||||
pr[aindx[i]].name,
|
||||
bvals[j]->bv_val,
|
||||
bvals[j]->bv_len);
|
||||
}
|
||||
ber_bvecfree(bvals);
|
||||
}
|
||||
}
|
||||
ldap_msgfree(res);
|
||||
|
||||
process_ldap_error:
|
||||
switch (ret) {
|
||||
case LDAP_SUCCESS:
|
||||
result = SASL_OK;
|
||||
break;
|
||||
|
||||
case LDAP_NO_SUCH_OBJECT:
|
||||
result = SASL_NOUSER;
|
||||
break;
|
||||
|
||||
case LDAP_NO_MEMORY:
|
||||
result = SASL_NOMEM;
|
||||
break;
|
||||
|
||||
case LDAP_SERVER_DOWN:
|
||||
case LDAP_BUSY:
|
||||
case LDAP_UNAVAILABLE:
|
||||
case LDAP_CONNECT_ERROR:
|
||||
result = SASL_UNAVAIL;
|
||||
break;
|
||||
|
||||
#if defined(LDAP_PROXY_AUTHZ_FAILURE)
|
||||
case LDAP_PROXY_AUTHZ_FAILURE:
|
||||
#endif
|
||||
case LDAP_INAPPROPRIATE_AUTH:
|
||||
case LDAP_INVALID_CREDENTIALS:
|
||||
case LDAP_INSUFFICIENT_ACCESS:
|
||||
result = SASL_BADAUTH;
|
||||
break;
|
||||
|
||||
default:
|
||||
result = SASL_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
if(attrs) sparams->utils->free(attrs);
|
||||
if(cp.ld) ldap_unbind_ext(cp.ld, NULL, NULL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int ldapdb_auxprop_store(void *glob_context,
|
||||
sasl_server_params_t *sparams,
|
||||
struct propctx *prctx,
|
||||
const char *user,
|
||||
unsigned ulen)
|
||||
{
|
||||
ldapctx *ctx = glob_context;
|
||||
connparm cp;
|
||||
const struct propval *pr;
|
||||
int i, n;
|
||||
LDAPMod **mods;
|
||||
|
||||
/* just checking if we are enabled */
|
||||
if (!prctx) return SASL_OK;
|
||||
|
||||
if (!sparams || !user) return SASL_BADPARAM;
|
||||
|
||||
pr = sparams->utils->prop_get(prctx);
|
||||
if (!pr) return SASL_BADPARAM;
|
||||
|
||||
for (n=0; pr[n].name; n++);
|
||||
if (!n) return SASL_BADPARAM;
|
||||
|
||||
mods = sparams->utils->malloc((n+1) * sizeof(LDAPMod*) + n * sizeof(LDAPMod));
|
||||
if (!mods) return SASL_NOMEM;
|
||||
|
||||
if((i=ldapdb_connect(ctx, sparams, user, ulen, &cp)) == 0) {
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
mods[i] = (LDAPMod *)((char *)(mods+n+1) + i * sizeof(LDAPMod));
|
||||
mods[i]->mod_op = LDAP_MOD_REPLACE;
|
||||
mods[i]->mod_type = (char *)pr[i].name;
|
||||
mods[i]->mod_values = (char **)pr[i].values;
|
||||
}
|
||||
mods[i] = NULL;
|
||||
|
||||
i = ldap_modify_ext_s(cp.ld, cp.dn->bv_val+3, mods, cp.ctrl, NULL);
|
||||
ber_bvfree(cp.dn);
|
||||
}
|
||||
|
||||
sparams->utils->free(mods);
|
||||
|
||||
if (i) {
|
||||
sparams->utils->seterror(sparams->utils->conn, 0,
|
||||
ldap_err2string(i));
|
||||
if (i == LDAP_NO_MEMORY) i = SASL_NOMEM;
|
||||
else i = SASL_FAIL;
|
||||
}
|
||||
if(cp.ld) ldap_unbind_ext(cp.ld, NULL, NULL);
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
ldapdb_canon_server(void *glob_context,
|
||||
sasl_server_params_t *sparams,
|
||||
const char *user,
|
||||
unsigned ulen,
|
||||
unsigned flags,
|
||||
char *out,
|
||||
unsigned out_max,
|
||||
unsigned *out_ulen)
|
||||
{
|
||||
ldapctx *ctx = glob_context;
|
||||
connparm cp;
|
||||
struct berval **bvals;
|
||||
LDAPMessage *msg, *res;
|
||||
char *rdn, *attrs[2];
|
||||
unsigned len;
|
||||
int ret;
|
||||
|
||||
if(!ctx || !sparams || !user) return SASL_BADPARAM;
|
||||
|
||||
/* If no canon attribute was configured, we can't do anything */
|
||||
if(!ctx->canon.bv_val) return SASL_BADPARAM;
|
||||
|
||||
/* Trim whitespace */
|
||||
while(isspace(*(unsigned char *)user)) {
|
||||
user++;
|
||||
ulen--;
|
||||
}
|
||||
while(isspace((unsigned char)user[ulen-1])) {
|
||||
ulen--;
|
||||
}
|
||||
|
||||
if (!ulen) {
|
||||
sparams->utils->seterror(sparams->utils->conn, 0,
|
||||
"All-whitespace username.");
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
ret = ldapdb_connect(ctx, sparams, user, ulen, &cp);
|
||||
if ( ret ) goto done;
|
||||
|
||||
/* See if the RDN uses the canon attr. If so, just use the RDN
|
||||
* value, we don't need to do a search.
|
||||
*/
|
||||
rdn = cp.dn->bv_val+3;
|
||||
if (!strncasecmp(ctx->canon.bv_val, rdn, ctx->canon.bv_len) &&
|
||||
rdn[ctx->canon.bv_len] == '=') {
|
||||
char *comma;
|
||||
rdn += ctx->canon.bv_len + 1;
|
||||
comma = strchr(rdn, ',');
|
||||
if ( comma )
|
||||
len = comma - rdn;
|
||||
else
|
||||
len = cp.dn->bv_len - (rdn - cp.dn->bv_val);
|
||||
if ( len > out_max )
|
||||
len = out_max;
|
||||
memcpy(out, rdn, len);
|
||||
out[len] = '\0';
|
||||
*out_ulen = len;
|
||||
ret = SASL_OK;
|
||||
ber_bvfree(cp.dn);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Have to read the user's entry */
|
||||
attrs[0] = ctx->canon.bv_val;
|
||||
attrs[1] = NULL;
|
||||
ret = ldap_search_ext_s(cp.ld, cp.dn->bv_val+3, LDAP_SCOPE_BASE,
|
||||
"(objectclass=*)", attrs, 0, cp.ctrl, NULL, NULL, 1, &res);
|
||||
ber_bvfree(cp.dn);
|
||||
|
||||
if (ret != LDAP_SUCCESS) goto done;
|
||||
|
||||
for(msg=ldap_first_message(cp.ld, res); msg; msg=ldap_next_message(cp.ld, msg))
|
||||
{
|
||||
if (ldap_msgtype(msg) != LDAP_RES_SEARCH_ENTRY) continue;
|
||||
bvals = ldap_get_values_len(cp.ld, msg, attrs[0]);
|
||||
if (!bvals) continue;
|
||||
len = bvals[0]->bv_len;
|
||||
if ( len > out_max )
|
||||
len = out_max;
|
||||
memcpy(out, bvals[0]->bv_val, len);
|
||||
*out_ulen = len;
|
||||
ber_bvecfree(bvals);
|
||||
}
|
||||
ldap_msgfree(res);
|
||||
|
||||
done:
|
||||
if(cp.ld) ldap_unbind_ext(cp.ld, NULL, NULL);
|
||||
if (ret) {
|
||||
sparams->utils->seterror(sparams->utils->conn, 0,
|
||||
ldap_err2string(ret));
|
||||
if (ret == LDAP_NO_MEMORY) ret = SASL_NOMEM;
|
||||
else ret = SASL_FAIL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
ldapdb_canon_client(void *glob_context,
|
||||
sasl_client_params_t *cparams,
|
||||
const char *user,
|
||||
unsigned ulen,
|
||||
unsigned flags,
|
||||
char *out,
|
||||
unsigned out_max,
|
||||
unsigned *out_ulen)
|
||||
{
|
||||
if(!cparams || !user) return SASL_BADPARAM;
|
||||
|
||||
/* Trim whitespace */
|
||||
while(isspace(*(unsigned char *)user)) {
|
||||
user++;
|
||||
ulen--;
|
||||
}
|
||||
while(isspace((unsigned char)user[ulen-1])) {
|
||||
ulen--;
|
||||
}
|
||||
|
||||
if (!ulen) {
|
||||
cparams->utils->seterror(cparams->utils->conn, 0,
|
||||
"All-whitespace username.");
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
if (ulen > out_max) return SASL_BUFOVER;
|
||||
|
||||
memcpy(out, user, ulen);
|
||||
out[ulen] = '\0';
|
||||
*out_ulen = ulen;
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
ldapdb_config(const sasl_utils_t *utils)
|
||||
{
|
||||
ldapctx *p = &ldapdb_ctx;
|
||||
const char *s;
|
||||
unsigned len;
|
||||
|
||||
if(p->inited) return SASL_OK;
|
||||
|
||||
utils->getopt(utils->getopt_context, ldapdb, "ldapdb_uri", &p->uri, NULL);
|
||||
if(!p->uri) return SASL_BADPARAM;
|
||||
|
||||
utils->getopt(utils->getopt_context, ldapdb, "ldapdb_id",
|
||||
(const char **)&p->id.bv_val, &len);
|
||||
p->id.bv_len = len;
|
||||
utils->getopt(utils->getopt_context, ldapdb, "ldapdb_pw",
|
||||
(const char **)&p->pw.bv_val, &len);
|
||||
p->pw.bv_len = len;
|
||||
utils->getopt(utils->getopt_context, ldapdb, "ldapdb_mech",
|
||||
(const char **)&p->mech.bv_val, &len);
|
||||
p->mech.bv_len = len;
|
||||
utils->getopt(utils->getopt_context, ldapdb, "ldapdb_starttls", &s, NULL);
|
||||
if (s)
|
||||
{
|
||||
if (!strcasecmp(s, "demand")) p->use_tls = 2;
|
||||
else if (!strcasecmp(s, "try")) p->use_tls = 1;
|
||||
}
|
||||
utils->getopt(utils->getopt_context, ldapdb, "ldapdb_rc", &s, &len);
|
||||
if (s)
|
||||
{
|
||||
char *str = utils->malloc(sizeof("LDAPRC=")+len);
|
||||
if (!str) return SASL_NOMEM;
|
||||
strcpy( str, "LDAPRC=" );
|
||||
strcpy( str + sizeof("LDAPRC=")-1, s );
|
||||
if (putenv(str))
|
||||
{
|
||||
utils->free(str);
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
}
|
||||
utils->getopt(utils->getopt_context, ldapdb, "ldapdb_canon_attr",
|
||||
(const char **)&p->canon.bv_val, &len);
|
||||
p->canon.bv_len = len;
|
||||
p->inited = 1;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static sasl_auxprop_plug_t ldapdb_auxprop_plugin = {
|
||||
0, /* Features */
|
||||
0, /* spare */
|
||||
&ldapdb_ctx, /* glob_context */
|
||||
NULL, /* auxprop_free */
|
||||
ldapdb_auxprop_lookup, /* auxprop_lookup */
|
||||
ldapdb, /* name */
|
||||
ldapdb_auxprop_store /* auxprop store */
|
||||
};
|
||||
|
||||
int ldapdb_auxprop_plug_init(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_auxprop_plug_t **plug,
|
||||
const char *plugname __attribute__((unused)))
|
||||
{
|
||||
int rc;
|
||||
|
||||
if(!out_version || !plug) return SASL_BADPARAM;
|
||||
|
||||
if(max_version < SASL_AUXPROP_PLUG_VERSION) return SASL_BADVERS;
|
||||
|
||||
rc = ldapdb_config(utils);
|
||||
|
||||
*out_version = SASL_AUXPROP_PLUG_VERSION;
|
||||
|
||||
*plug = &ldapdb_auxprop_plugin;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static sasl_canonuser_plug_t ldapdb_canonuser_plugin = {
|
||||
0, /* features */
|
||||
0, /* spare */
|
||||
&ldapdb_ctx, /* glob_context */
|
||||
ldapdb, /* name */
|
||||
NULL, /* canon_user_free */
|
||||
ldapdb_canon_server, /* canon_user_server */
|
||||
ldapdb_canon_client, /* canon_user_client */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
int ldapdb_canonuser_plug_init(const sasl_utils_t *utils,
|
||||
int max_version,
|
||||
int *out_version,
|
||||
sasl_canonuser_plug_t **plug,
|
||||
const char *plugname __attribute__((unused)))
|
||||
{
|
||||
int rc;
|
||||
|
||||
if(!out_version || !plug) return SASL_BADPARAM;
|
||||
|
||||
if(max_version < SASL_CANONUSER_PLUG_VERSION) return SASL_BADVERS;
|
||||
|
||||
rc = ldapdb_config(utils);
|
||||
|
||||
*out_version = SASL_CANONUSER_PLUG_VERSION;
|
||||
|
||||
*plug = &ldapdb_canonuser_plugin;
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_AUXPROP_PLUG_INIT( ldapdb )
|
||||
|
||||
SASL_CANONUSER_PLUG_INIT( ldapdb )
|
||||
@@ -0,0 +1,496 @@
|
||||
/* Login SASL plugin
|
||||
* Rob Siemborski (SASLv2 Conversion)
|
||||
* contributed by Rainer Schoepf <schoepf@uni-mainz.de>
|
||||
* based on PLAIN, by Tim Martin <tmartin@andrew.cmu.edu>
|
||||
* $Id: login.c,v 1.31 2010/11/30 11:41:47 mel Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
/***************************** Common Section *****************************/
|
||||
|
||||
static const char plugin_id[] = "$Id: login.c,v 1.31 2010/11/30 11:41:47 mel Exp $";
|
||||
|
||||
/***************************** Server Section *****************************/
|
||||
|
||||
typedef struct context {
|
||||
int state;
|
||||
|
||||
char *username;
|
||||
unsigned username_len;
|
||||
} server_context_t;
|
||||
|
||||
static int login_server_mech_new(void *glob_context __attribute__((unused)),
|
||||
sasl_server_params_t *sparams,
|
||||
const char *challenge __attribute__((unused)),
|
||||
unsigned challen __attribute__((unused)),
|
||||
void **conn_context)
|
||||
{
|
||||
server_context_t *text;
|
||||
|
||||
/* holds state are in */
|
||||
text = sparams->utils->malloc(sizeof(server_context_t));
|
||||
if (text == NULL) {
|
||||
MEMERROR( sparams->utils );
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
memset(text, 0, sizeof(server_context_t));
|
||||
|
||||
text->state = 1;
|
||||
|
||||
*conn_context = text;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
#define USERNAME_CHALLENGE "Username:"
|
||||
#define PASSWORD_CHALLENGE "Password:"
|
||||
|
||||
static int login_server_mech_step(void *conn_context,
|
||||
sasl_server_params_t *params,
|
||||
const char *clientin,
|
||||
unsigned clientinlen,
|
||||
const char **serverout,
|
||||
unsigned *serveroutlen,
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
server_context_t *text = (server_context_t *) conn_context;
|
||||
|
||||
*serverout = NULL;
|
||||
*serveroutlen = 0;
|
||||
|
||||
if (text == NULL) {
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
switch (text->state) {
|
||||
|
||||
case 1:
|
||||
text->state = 2;
|
||||
|
||||
/* Check inlen, (possibly we have already the user name) */
|
||||
/* In this case fall through to state 2 */
|
||||
if (clientinlen == 0) {
|
||||
/* demand username */
|
||||
|
||||
*serveroutlen = (unsigned) strlen(USERNAME_CHALLENGE);
|
||||
*serverout = USERNAME_CHALLENGE;
|
||||
|
||||
return SASL_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
case 2:
|
||||
/* Catch really long usernames */
|
||||
if (clientinlen > 1024) {
|
||||
SETERROR(params->utils, "username too long (>1024 characters)");
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
/* get username */
|
||||
text->username =
|
||||
params->utils->malloc(sizeof(sasl_secret_t) + clientinlen + 1);
|
||||
if (!text->username) {
|
||||
MEMERROR( params->utils );
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
strncpy(text->username, clientin, clientinlen);
|
||||
text->username_len = clientinlen;
|
||||
text->username[clientinlen] = '\0';
|
||||
|
||||
/* demand password */
|
||||
*serveroutlen = (unsigned) strlen(PASSWORD_CHALLENGE);
|
||||
*serverout = PASSWORD_CHALLENGE;
|
||||
|
||||
text->state = 3;
|
||||
|
||||
return SASL_CONTINUE;
|
||||
|
||||
|
||||
case 3: {
|
||||
sasl_secret_t *password;
|
||||
int result;
|
||||
|
||||
/* Catch really long passwords */
|
||||
if (clientinlen > 1024) {
|
||||
SETERROR(params->utils,
|
||||
"clientinlen is > 1024 characters in LOGIN plugin");
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
/* get password */
|
||||
password =
|
||||
params->utils->malloc(sizeof(sasl_secret_t) + clientinlen + 1);
|
||||
if (!password) {
|
||||
MEMERROR(params->utils);
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
strncpy((char *) password->data, clientin, clientinlen);
|
||||
password->data[clientinlen] = '\0';
|
||||
password->len = clientinlen;
|
||||
|
||||
/* canonicalize username first, so that password verification is
|
||||
* done against the canonical id */
|
||||
result = params->canon_user(params->utils->conn,
|
||||
text->username,
|
||||
text->username_len,
|
||||
SASL_CU_AUTHID | SASL_CU_AUTHZID | SASL_CU_EXTERNALLY_VERIFIED,
|
||||
oparams);
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
/* verify_password - return sasl_ok on success */
|
||||
result = params->utils->checkpass(params->utils->conn,
|
||||
oparams->authid, oparams->alen,
|
||||
(char *) password->data, password->len);
|
||||
|
||||
if (result != SASL_OK) {
|
||||
_plug_free_secret(params->utils, &password);
|
||||
return result;
|
||||
}
|
||||
|
||||
_plug_free_secret(params->utils, &password);
|
||||
|
||||
*serverout = NULL;
|
||||
*serveroutlen = 0;
|
||||
|
||||
oparams->doneflag = 1;
|
||||
oparams->mech_ssf = 0;
|
||||
oparams->maxoutbuf = 0;
|
||||
oparams->encode_context = NULL;
|
||||
oparams->encode = NULL;
|
||||
oparams->decode_context = NULL;
|
||||
oparams->decode = NULL;
|
||||
oparams->param_version = 0;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
params->utils->log(NULL, SASL_LOG_ERR,
|
||||
"Invalid LOGIN server step %d\n", text->state);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
return SASL_FAIL; /* should never get here */
|
||||
}
|
||||
|
||||
static void login_server_mech_dispose(void *conn_context,
|
||||
const sasl_utils_t *utils)
|
||||
{
|
||||
server_context_t *text = (server_context_t *) conn_context;
|
||||
|
||||
if (!text) return;
|
||||
|
||||
if (text->username) utils->free(text->username);
|
||||
|
||||
utils->free(text);
|
||||
}
|
||||
|
||||
static sasl_server_plug_t login_server_plugins[] =
|
||||
{
|
||||
{
|
||||
"LOGIN", /* mech_name */
|
||||
0, /* max_ssf */
|
||||
SASL_SEC_NOANONYMOUS
|
||||
| SASL_SEC_PASS_CREDENTIALS, /* security_flags */
|
||||
0, /* features */
|
||||
NULL, /* glob_context */
|
||||
&login_server_mech_new, /* mech_new */
|
||||
&login_server_mech_step, /* mech_step */
|
||||
&login_server_mech_dispose, /* mech_dispose */
|
||||
NULL, /* mech_free */
|
||||
NULL, /* setpass */
|
||||
NULL, /* user_query */
|
||||
NULL, /* idle */
|
||||
NULL, /* mech_avail */
|
||||
NULL /* spare */
|
||||
}
|
||||
};
|
||||
|
||||
int login_server_plug_init(sasl_utils_t *utils,
|
||||
int maxversion,
|
||||
int *out_version,
|
||||
sasl_server_plug_t **pluglist,
|
||||
int *plugcount)
|
||||
{
|
||||
if (maxversion < SASL_SERVER_PLUG_VERSION) {
|
||||
SETERROR(utils, "LOGIN version mismatch");
|
||||
return SASL_BADVERS;
|
||||
}
|
||||
|
||||
*out_version = SASL_SERVER_PLUG_VERSION;
|
||||
*pluglist = login_server_plugins;
|
||||
*plugcount = 1;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
/***************************** Client Section *****************************/
|
||||
|
||||
typedef struct client_context {
|
||||
int state;
|
||||
|
||||
sasl_secret_t *password;
|
||||
unsigned int free_password; /* set if we need to free password */
|
||||
} client_context_t;
|
||||
|
||||
static int login_client_mech_new(void *glob_context __attribute__((unused)),
|
||||
sasl_client_params_t *params,
|
||||
void **conn_context)
|
||||
{
|
||||
client_context_t *text;
|
||||
|
||||
/* holds state are in */
|
||||
text = params->utils->malloc(sizeof(client_context_t));
|
||||
if (text == NULL) {
|
||||
MEMERROR(params->utils);
|
||||
return SASL_NOMEM;
|
||||
}
|
||||
|
||||
memset(text, 0, sizeof(client_context_t));
|
||||
|
||||
text->state = 1;
|
||||
|
||||
*conn_context = text;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
|
||||
static int login_client_mech_step(void *conn_context,
|
||||
sasl_client_params_t *params,
|
||||
const char *serverin __attribute__((unused)),
|
||||
unsigned serverinlen __attribute__((unused)),
|
||||
sasl_interact_t **prompt_need,
|
||||
const char **clientout,
|
||||
unsigned *clientoutlen,
|
||||
sasl_out_params_t *oparams)
|
||||
{
|
||||
client_context_t *text = (client_context_t *) conn_context;
|
||||
|
||||
*clientout = NULL;
|
||||
*clientoutlen = 0;
|
||||
|
||||
switch (text->state) {
|
||||
|
||||
case 1: {
|
||||
const char *user = NULL;
|
||||
int auth_result = SASL_OK;
|
||||
int pass_result = SASL_OK;
|
||||
int result;
|
||||
|
||||
/* check if sec layer strong enough */
|
||||
if (params->props.min_ssf > params->external_ssf) {
|
||||
SETERROR( params->utils, "SSF requested of LOGIN plugin");
|
||||
return SASL_TOOWEAK;
|
||||
}
|
||||
|
||||
/* try to get the userid */
|
||||
/* Note: we want to grab the authname and not the userid, which is
|
||||
* who we AUTHORIZE as, and will be the same as the authname
|
||||
* for the LOGIN mech.
|
||||
*/
|
||||
if (oparams->user == NULL) {
|
||||
auth_result = _plug_get_authid(params->utils, &user, prompt_need);
|
||||
|
||||
if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT))
|
||||
return auth_result;
|
||||
}
|
||||
|
||||
/* try to get the password */
|
||||
if (text->password == NULL) {
|
||||
pass_result = _plug_get_password(params->utils, &text->password,
|
||||
&text->free_password, prompt_need);
|
||||
|
||||
if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT))
|
||||
return pass_result;
|
||||
}
|
||||
|
||||
/* free prompts we got */
|
||||
if (prompt_need && *prompt_need) {
|
||||
params->utils->free(*prompt_need);
|
||||
*prompt_need = NULL;
|
||||
}
|
||||
|
||||
/* if there are prompts not filled in */
|
||||
if ((auth_result == SASL_INTERACT) || (pass_result == SASL_INTERACT)) {
|
||||
/* make the prompt list */
|
||||
result =
|
||||
_plug_make_prompts(params->utils, prompt_need,
|
||||
NULL, NULL,
|
||||
auth_result == SASL_INTERACT ?
|
||||
"Please enter your authentication name" : NULL,
|
||||
NULL,
|
||||
pass_result == SASL_INTERACT ?
|
||||
"Please enter your password" : NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
return SASL_INTERACT;
|
||||
}
|
||||
|
||||
if (!text->password) {
|
||||
PARAMERROR(params->utils);
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
result = params->canon_user(params->utils->conn, user, 0,
|
||||
SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
|
||||
if (result != SASL_OK) return result;
|
||||
|
||||
/* server should have sent request for username - we ignore it */
|
||||
if (!serverin) {
|
||||
SETERROR( params->utils,
|
||||
"Server didn't issue challenge for USERNAME");
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
if (!clientout) {
|
||||
PARAMERROR( params->utils );
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
if (clientoutlen) *clientoutlen = oparams->alen;
|
||||
*clientout = oparams->authid;
|
||||
|
||||
text->state = 2;
|
||||
|
||||
return SASL_CONTINUE;
|
||||
}
|
||||
|
||||
case 2:
|
||||
/* server should have sent request for password - we ignore it */
|
||||
if (!serverin) {
|
||||
SETERROR( params->utils,
|
||||
"Server didn't issue challenge for PASSWORD");
|
||||
return SASL_BADPROT;
|
||||
}
|
||||
|
||||
if (!clientout) {
|
||||
PARAMERROR(params->utils);
|
||||
return SASL_BADPARAM;
|
||||
}
|
||||
|
||||
if (clientoutlen) *clientoutlen = text->password->len;
|
||||
*clientout = (char *) text->password->data;
|
||||
|
||||
/* set oparams */
|
||||
oparams->doneflag = 1;
|
||||
oparams->mech_ssf = 0;
|
||||
oparams->maxoutbuf = 0;
|
||||
oparams->encode_context = NULL;
|
||||
oparams->encode = NULL;
|
||||
oparams->decode_context = NULL;
|
||||
oparams->decode = NULL;
|
||||
oparams->param_version = 0;
|
||||
|
||||
return SASL_OK;
|
||||
|
||||
default:
|
||||
params->utils->log(NULL, SASL_LOG_ERR,
|
||||
"Invalid LOGIN client step %d\n", text->state);
|
||||
return SASL_FAIL;
|
||||
}
|
||||
|
||||
return SASL_FAIL; /* should never get here */
|
||||
}
|
||||
|
||||
static void login_client_mech_dispose(void *conn_context,
|
||||
const sasl_utils_t *utils)
|
||||
{
|
||||
client_context_t *text = (client_context_t *) conn_context;
|
||||
|
||||
if (!text) return;
|
||||
|
||||
/* free sensitive info */
|
||||
if (text->free_password) _plug_free_secret(utils, &(text->password));
|
||||
|
||||
utils->free(text);
|
||||
}
|
||||
|
||||
static sasl_client_plug_t login_client_plugins[] =
|
||||
{
|
||||
{
|
||||
"LOGIN", /* mech_name */
|
||||
0, /* max_ssf */
|
||||
SASL_SEC_NOANONYMOUS
|
||||
| SASL_SEC_PASS_CREDENTIALS, /* security_flags */
|
||||
SASL_FEAT_SERVER_FIRST, /* features */
|
||||
NULL, /* required_prompts */
|
||||
NULL, /* glob_context */
|
||||
&login_client_mech_new, /* mech_new */
|
||||
&login_client_mech_step, /* mech_step */
|
||||
&login_client_mech_dispose, /* mech_dispose */
|
||||
NULL, /* mech_free */
|
||||
NULL, /* idle */
|
||||
NULL, /* spare */
|
||||
NULL /* spare */
|
||||
}
|
||||
};
|
||||
|
||||
int login_client_plug_init(sasl_utils_t *utils,
|
||||
int maxversion,
|
||||
int *out_version,
|
||||
sasl_client_plug_t **pluglist,
|
||||
int *plugcount)
|
||||
{
|
||||
if (maxversion < SASL_CLIENT_PLUG_VERSION) {
|
||||
SETERROR(utils, "Version mismatch in LOGIN");
|
||||
return SASL_BADVERS;
|
||||
}
|
||||
|
||||
*out_version = SASL_CLIENT_PLUG_VERSION;
|
||||
*pluglist = login_client_plugins;
|
||||
*plugcount = 1;
|
||||
|
||||
return SASL_OK;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_login_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_CLIENT_PLUG_INIT( login )
|
||||
SASL_SERVER_PLUG_INIT( login )
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# mechanism plugins
|
||||
for mech in anonymous crammd5 digestmd5 scram gssapiv2 kerberos4 login ntlm otp passdss plain srp gs2; do
|
||||
|
||||
echo "
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include \"plugin_common.h\"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_${mech}_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_CLIENT_PLUG_INIT( $mech )
|
||||
SASL_SERVER_PLUG_INIT( $mech )
|
||||
" > ${mech}_init.c
|
||||
done
|
||||
|
||||
# auxprop plugins
|
||||
for auxprop in sasldb sql ldapdb; do
|
||||
|
||||
echo "
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include \"plugin_common.h\"
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_AUXPROP_PLUG_INIT( $auxprop )
|
||||
" > ${auxprop}_init.c
|
||||
done
|
||||
|
||||
# ldapdb is also a canon_user plugin
|
||||
echo "SASL_CANONUSER_PLUG_INIT( ldapdb )" >> ldapdb_init.c
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_ntlm_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_CLIENT_PLUG_INIT( ntlm )
|
||||
SASL_SERVER_PLUG_INIT( ntlm )
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,311 @@
|
||||
/* OTP SASL plugin
|
||||
* Ken Murchison
|
||||
* $Id: otp.h,v 1.2 2003/02/13 19:56:04 rjs3 Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 1998-2003 Carnegie Mellon University. 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 name "Carnegie Mellon University" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For permission or any other legal
|
||||
* details, please contact
|
||||
* Office of Technology Transfer
|
||||
* Carnegie Mellon University
|
||||
* 5000 Forbes Avenue
|
||||
* Pittsburgh, PA 15213-3890
|
||||
* (412) 268-4387, fax: (412) 268-7395
|
||||
* tech-transfer@andrew.cmu.edu
|
||||
*
|
||||
* 4. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by Computing Services
|
||||
* at Carnegie Mellon University (http://www.cmu.edu/computing/)."
|
||||
*
|
||||
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _OTP_H_
|
||||
#define _OTP_H_
|
||||
|
||||
/* Standard dictionary from RFC2289 */
|
||||
#define OTP_STD_DICT_SIZE 2048
|
||||
#define OTP_4LETTER_OFFSET 571
|
||||
|
||||
static const char *otp_std_dict[OTP_STD_DICT_SIZE] =
|
||||
{ "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD",
|
||||
"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY",
|
||||
"AN", "ANA", "AND", "ANN", "ANT", "ANY", "APE", "APS",
|
||||
"APT", "ARC", "ARE", "ARK", "ARM", "ART", "AS", "ASH",
|
||||
"ASK", "AT", "ATE", "AUG", "AUK", "AVE", "AWE", "AWK",
|
||||
"AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM",
|
||||
"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG",
|
||||
"BEN", "BET", "BEY", "BIB", "BID", "BIG", "BIN", "BIT",
|
||||
"BOB", "BOG", "BON", "BOO", "BOP", "BOW", "BOY", "BUB",
|
||||
"BUD", "BUG", "BUM", "BUN", "BUS", "BUT", "BUY", "BY",
|
||||
"BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT",
|
||||
"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT",
|
||||
"COW", "COY", "CRY", "CUB", "CUE", "CUP", "CUR", "CUT",
|
||||
"DAB", "DAD", "DAM", "DAN", "DAR", "DAY", "DEE", "DEL",
|
||||
"DEN", "DES", "DEW", "DID", "DIE", "DIG", "DIN", "DIP",
|
||||
"DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB",
|
||||
"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL",
|
||||
"EGG", "EGO", "ELI", "ELK", "ELM", "ELY", "EM", "END",
|
||||
"EST", "ETC", "EVA", "EVE", "EWE", "EYE", "FAD", "FAN",
|
||||
"FAR", "FAT", "FAY", "FED", "FEE", "FEW", "FIB", "FIG",
|
||||
"FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR",
|
||||
"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL",
|
||||
"GAM", "GAP", "GAS", "GAY", "GEE", "GEL", "GEM", "GET",
|
||||
"GIG", "GIL", "GIN", "GO", "GOT", "GUM", "GUN", "GUS",
|
||||
"GUT", "GUY", "GYM", "GYP", "HA", "HAD", "HAL", "HAM",
|
||||
"HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM",
|
||||
"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP",
|
||||
"HIS", "HIT", "HO", "HOB", "HOC", "HOE", "HOG", "HOP",
|
||||
"HOT", "HOW", "HUB", "HUE", "HUG", "HUH", "HUM", "HUT",
|
||||
"I", "ICY", "IDA", "IF", "IKE", "ILL", "INK", "INN",
|
||||
"IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT",
|
||||
"ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW",
|
||||
"JAY", "JET", "JIG", "JIM", "JO", "JOB", "JOE", "JOG",
|
||||
"JOT", "JOY", "JUG", "JUT", "KAY", "KEG", "KEN", "KEY",
|
||||
"KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC", "LAD",
|
||||
"LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE",
|
||||
"LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN",
|
||||
"LIP", "LIT", "LO", "LOB", "LOG", "LOP", "LOS", "LOT",
|
||||
"LOU", "LOW", "LOY", "LUG", "LYE", "MA", "MAC", "MAD",
|
||||
"MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY", "ME",
|
||||
"MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT",
|
||||
"MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW",
|
||||
"MUD", "MUG", "MUM", "MY", "NAB", "NAG", "NAN", "NAP",
|
||||
"NAT", "NAY", "NE", "NED", "NEE", "NET", "NEW", "NIB",
|
||||
"NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON", "NOR",
|
||||
"NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF",
|
||||
"OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT",
|
||||
"OH", "OIL", "OK", "OLD", "ON", "ONE", "OR", "ORB",
|
||||
"ORE", "ORR", "OS", "OTT", "OUR", "OUT", "OVA", "OW",
|
||||
"OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL", "PAM",
|
||||
"PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG",
|
||||
"PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE",
|
||||
"PIN", "PIT", "PLY", "PO", "POD", "POE", "POP", "POT",
|
||||
"POW", "PRO", "PRY", "PUB", "PUG", "PUN", "PUP", "PUT",
|
||||
"QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW", "RAY",
|
||||
"REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM",
|
||||
"RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW",
|
||||
"ROY", "RUB", "RUE", "RUG", "RUM", "RUN", "RYE", "SAC",
|
||||
"SAD", "SAG", "SAL", "SAM", "SAN", "SAP", "SAT", "SAW",
|
||||
"SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW", "SHE",
|
||||
"SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY",
|
||||
"SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY",
|
||||
"SPA", "SPY", "SUB", "SUD", "SUE", "SUM", "SUN", "SUP",
|
||||
"TAB", "TAD", "TAG", "TAN", "TAP", "TAR", "TEA", "TED",
|
||||
"TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM", "TIN",
|
||||
"TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP",
|
||||
"TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO",
|
||||
"UN", "UP", "US", "USE", "VAN", "VAT", "VET", "VIE",
|
||||
"WAD", "WAG", "WAR", "WAS", "WAY", "WE", "WEB", "WED",
|
||||
"WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK", "WON",
|
||||
"WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE",
|
||||
"YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE",
|
||||
"ABUT", "ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM",
|
||||
"ADDS", "ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA",
|
||||
"AIDE", "AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA",
|
||||
"ALIA", "ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA",
|
||||
"AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY",
|
||||
"ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH",
|
||||
"AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS",
|
||||
"ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON",
|
||||
"AVOW", "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE",
|
||||
"BAIL", "BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL",
|
||||
"BALM", "BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE",
|
||||
"BARK", "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE",
|
||||
"BATH", "BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR",
|
||||
"BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER", "BEET", "BELA",
|
||||
"BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT", "BESS",
|
||||
"BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE",
|
||||
"BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB",
|
||||
"BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE",
|
||||
"BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY",
|
||||
"BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT", "BOMB", "BONA",
|
||||
"BOND", "BONE", "BONG", "BONN", "BONY", "BOOK", "BOOM", "BOON",
|
||||
"BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS", "BOTH", "BOUT",
|
||||
"BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN", "BRAY", "BRED",
|
||||
"BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF", "BULB",
|
||||
"BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN",
|
||||
"BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE",
|
||||
"CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM",
|
||||
"CAME", "CANE", "CANT", "CARD", "CARE", "CARL", "CARR", "CART",
|
||||
"CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL", "CELL", "CENT",
|
||||
"CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF", "CHEN", "CHEW",
|
||||
"CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG", "CHUM", "CITE",
|
||||
"CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY", "CLOD", "CLOG",
|
||||
"CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK", "COCO",
|
||||
"CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA",
|
||||
"COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON",
|
||||
"COOT", "CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL",
|
||||
"CRAB", "CRAG", "CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD",
|
||||
"CUBA", "CUBE", "CUFF", "CULL", "CULT", "CUNY", "CURB", "CURD",
|
||||
"CURE", "CURL", "CURT", "CUTS", "DADE", "DALE", "DAME", "DANA",
|
||||
"DANE", "DANG", "DANK", "DARE", "DARK", "DARN", "DART", "DASH",
|
||||
"DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS", "DEAD", "DEAF",
|
||||
"DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM", "DEER",
|
||||
"DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE",
|
||||
"DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT",
|
||||
"DISC", "DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL",
|
||||
"DOLT", "DOME", "DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE",
|
||||
"DOUG", "DOUR", "DOVE", "DOWN", "DRAB", "DRAG", "DRAM", "DRAW",
|
||||
"DREW", "DRUB", "DRUG", "DRUM", "DUAL", "DUCK", "DUCT", "DUEL",
|
||||
"DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK", "DUSK", "DUST",
|
||||
"DUTY", "EACH", "EARL", "EARN", "EASE", "EAST", "EASY", "EBEN",
|
||||
"ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA", "EGAN",
|
||||
"ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS",
|
||||
"ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT",
|
||||
"FADE", "FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG",
|
||||
"FARM", "FAST", "FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL",
|
||||
"FEET", "FELL", "FELT", "FEND", "FERN", "FEST", "FEUD", "FIEF",
|
||||
"FIGS", "FILE", "FILL", "FILM", "FIND", "FINE", "FINK", "FIRE",
|
||||
"FIRM", "FISH", "FISK", "FIST", "FITS", "FIVE", "FLAG", "FLAK",
|
||||
"FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW", "FLIT", "FLOC",
|
||||
"FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY", "FOIL",
|
||||
"FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD",
|
||||
"FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL",
|
||||
"FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM",
|
||||
"FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS",
|
||||
"GAFF", "GAGE", "GAIL", "GAIN", "GAIT", "GALA", "GALE", "GALL",
|
||||
"GALT", "GAME", "GANG", "GARB", "GARY", "GASH", "GATE", "GAUL",
|
||||
"GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GENE", "GENT", "GERM",
|
||||
"GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT", "GINA", "GIRD",
|
||||
"GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB", "GLOB",
|
||||
"GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT",
|
||||
"GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF",
|
||||
"GORE", "GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY",
|
||||
"GREG", "GREW", "GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW",
|
||||
"GRUB", "GULF", "GULL", "GUNK", "GURU", "GUSH", "GUST", "GWEN",
|
||||
"GWYN", "HAAG", "HAAS", "HACK", "HAIL", "HAIR", "HALE", "HALF",
|
||||
"HALL", "HALO", "HALT", "HAND", "HANG", "HANK", "HANS", "HARD",
|
||||
"HARK", "HARM", "HART", "HASH", "HAST", "HATE", "HATH", "HAUL",
|
||||
"HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT", "HEBE",
|
||||
"HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB",
|
||||
"HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE",
|
||||
"HIGH", "HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS",
|
||||
"HIVE", "HOBO", "HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT",
|
||||
"HOME", "HONE", "HONK", "HOOD", "HOOF", "HOOK", "HOOT", "HORN",
|
||||
"HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL", "HOYT", "HUCK",
|
||||
"HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK", "HULL", "HUNK",
|
||||
"HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE", "HYMN", "IBIS",
|
||||
"ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO", "IONS",
|
||||
"IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM",
|
||||
"IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN",
|
||||
"JEFF", "JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE",
|
||||
"JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE",
|
||||
"JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY", "JUJU", "JUKE",
|
||||
"JULY", "JUNE", "JUNK", "JUNO", "JURY", "JUST", "JUTE", "KAHN",
|
||||
"KALE", "KANE", "KANT", "KARL", "KATE", "KEEL", "KEEN", "KENO",
|
||||
"KENT", "KERN", "KERR", "KEYS", "KICK", "KILL", "KIND", "KING",
|
||||
"KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT", "KNOB",
|
||||
"KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE",
|
||||
"LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE",
|
||||
"LAMB", "LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS",
|
||||
"LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD",
|
||||
"LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER", "LEFT", "LEND",
|
||||
"LENS", "LENT", "LEON", "LESK", "LESS", "LEST", "LETS", "LIAR",
|
||||
"LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU", "LIFE", "LIFT",
|
||||
"LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB", "LIME", "LIND",
|
||||
"LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE", "LOAD",
|
||||
"LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA",
|
||||
"LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE",
|
||||
"LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE",
|
||||
"LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH",
|
||||
"LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE", "MADE", "MAGI",
|
||||
"MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI", "MALL", "MALT",
|
||||
"MANA", "MANN", "MANY", "MARC", "MARE", "MARK", "MARS", "MART",
|
||||
"MARY", "MASH", "MASK", "MASS", "MAST", "MATE", "MATH", "MAUL",
|
||||
"MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET", "MELD",
|
||||
"MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE",
|
||||
"MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND",
|
||||
"MINE", "MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE",
|
||||
"MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL",
|
||||
"MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON", "MOOR", "MOOT",
|
||||
"MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH", "MOVE", "MUCH",
|
||||
"MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK", "MUSH", "MUST",
|
||||
"MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL", "NAIR", "NAME",
|
||||
"NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT", "NECK",
|
||||
"NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS",
|
||||
"NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH",
|
||||
"NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE",
|
||||
"NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY",
|
||||
"OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY", "OLAF", "OLDY",
|
||||
"OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE", "ONES", "ONLY",
|
||||
"ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS", "OTTO", "OUCH",
|
||||
"OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY", "OWNS", "QUAD",
|
||||
"QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE", "RAID",
|
||||
"RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE",
|
||||
"RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED",
|
||||
"REEF", "REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT",
|
||||
"REST", "RICE", "RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME",
|
||||
"RING", "RINK", "RISE", "RISK", "RITE", "ROAD", "ROAM", "ROAR",
|
||||
"ROBE", "ROCK", "RODE", "ROIL", "ROLL", "ROME", "ROOD", "ROOF",
|
||||
"ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROSS", "ROSY", "ROTH",
|
||||
"ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY", "RUDE", "RUDY",
|
||||
"RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH", "RUSK",
|
||||
"RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL",
|
||||
"SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK",
|
||||
"SARA", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT",
|
||||
"SEAL", "SEAM", "SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN",
|
||||
"SEES", "SELF", "SELL", "SEND", "SENT", "SETS", "SEWN", "SHAG",
|
||||
"SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN", "SHOD", "SHOE",
|
||||
"SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE", "SIFT", "SIGH",
|
||||
"SIGN", "SILK", "SILL", "SILO", "SILT", "SINE", "SING", "SINK",
|
||||
"SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID", "SKIM",
|
||||
"SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW",
|
||||
"SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG",
|
||||
"SLUM", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB",
|
||||
"SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL",
|
||||
"SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE", "SORT", "SOUL",
|
||||
"SOUR", "SOWN", "STAB", "STAG", "STAN", "STAR", "STAY", "STEM",
|
||||
"STEW", "STIR", "STOW", "STUB", "STUN", "SUCH", "SUDS", "SUIT",
|
||||
"SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF", "SWAB", "SWAG",
|
||||
"SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK", "TACT",
|
||||
"TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE",
|
||||
"TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET",
|
||||
"TELL", "TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN",
|
||||
"THAT", "THEE", "THEM", "THEN", "THEY", "THIN", "THIS", "THUD",
|
||||
"THUG", "TICK", "TIDE", "TIDY", "TIED", "TIER", "TILE", "TILL",
|
||||
"TILT", "TIME", "TINA", "TINE", "TINT", "TINY", "TIRE", "TOAD",
|
||||
"TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TONG", "TONY", "TOOK",
|
||||
"TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR", "TOUT", "TOWN",
|
||||
"TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM", "TRIO",
|
||||
"TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT",
|
||||
"TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN",
|
||||
"TWIT", "ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH",
|
||||
"VAIL", "VAIN", "VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA",
|
||||
"VEIL", "VEIN", "VEND", "VENT", "VERB", "VERY", "VETO", "VICE",
|
||||
"VIEW", "VINE", "VISE", "VOID", "VOLT", "VOTE", "WACK", "WADE",
|
||||
"WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK", "WALL", "WALT",
|
||||
"WAND", "WANE", "WANG", "WANT", "WARD", "WARM", "WARN", "WART",
|
||||
"WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS", "WEAK",
|
||||
"WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL",
|
||||
"WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE",
|
||||
"WHEN", "WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL",
|
||||
"WIND", "WINE", "WING", "WINK", "WINO", "WIRE", "WISE", "WISH",
|
||||
"WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD", "WORE", "WORK",
|
||||
"WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE", "YANG", "YANK",
|
||||
"YARD", "YARN", "YAWL", "YAWN", "YEAH", "YEAR", "YELL", "YOGA",
|
||||
"YOKE" };
|
||||
|
||||
#endif /* _OTP_H_ */
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_otp_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_CLIENT_PLUG_INIT( otp )
|
||||
SASL_SERVER_PLUG_INIT( otp )
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#ifndef macintosh
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sasl.h>
|
||||
#include <saslplug.h>
|
||||
#include <saslutil.h>
|
||||
|
||||
#include "plugin_common.h"
|
||||
|
||||
#ifdef macintosh
|
||||
#include <sasl_passdss_plugin_decl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
BOOL APIENTRY DllMain( HANDLE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SASL_CLIENT_PLUG_INIT( passdss )
|
||||
SASL_SERVER_PLUG_INIT( passdss )
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user