├── .gitignore ├── .gitmodules ├── COPYING ├── README.md ├── etc ├── 99-enigma.rules ├── Equation-1.png ├── Equation-2.png ├── Equation-3.png ├── Equation-4.png ├── Equation-5.png ├── Equation-6.png ├── Equation-7.png ├── Equation-8.png ├── brute-force.md ├── dev-enigma-compat-explained.png ├── disaster-girl-build-remarks.jpg ├── enigmactl-sh-sample.gif ├── enigmactl.sh └── logo.png └── src ├── .ivk ├── Forgefile.hsl ├── dev_ctx ├── dev_ctx.c └── dev_ctx.h ├── ebuf ├── ebuf.c └── ebuf.h ├── eel ├── eel.c ├── eel.h └── types.h ├── enigmactl ├── enigmactl.h └── user │ ├── .ivk │ ├── Forgefile.hsl │ ├── doc │ └── man │ │ └── enigmactl.1 │ ├── main.c │ ├── option.c │ ├── option.h │ ├── setloader.c │ ├── setloader.h │ └── test │ ├── .ivk │ ├── Forgefile.hsl │ └── main.c ├── fops_impl ├── freebsd │ ├── dev_close.c │ ├── dev_close.h │ ├── dev_ioctl.c │ ├── dev_ioctl.h │ ├── dev_open.c │ ├── dev_open.h │ ├── dev_read.c │ ├── dev_read.h │ ├── dev_write.c │ └── dev_write.h └── linux │ ├── dev_ioctl.c │ ├── dev_ioctl.h │ ├── dev_open.c │ ├── dev_open.h │ ├── dev_read.c │ ├── dev_read.h │ ├── dev_release.c │ ├── dev_release.h │ ├── dev_write.c │ └── dev_write.h ├── installer.hsl ├── mkclean.hsl ├── mod.c ├── mod_info.h ├── mod_traps ├── freebsd │ ├── mod_exit.c │ ├── mod_exit.h │ ├── mod_init.c │ ├── mod_init.h │ ├── mod_quiesce.c │ └── mod_quiesce.h └── linux │ ├── mod_exit.c │ ├── mod_exit.h │ ├── mod_init.c │ └── mod_init.h ├── run_test.hsl ├── test ├── .ivk ├── Forgefile.hsl └── main.c └── toolsets.hsl /.gitignore: -------------------------------------------------------------------------------- 1 | *.cmd 2 | src/.tmp_versions/* 3 | *.ko 4 | *.mod.* 5 | *.o 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/test/cutest"] 2 | path = src/test/cutest 3 | url = https://github.com/rafael-santiago/cutest 4 | [submodule "src/enigmactl/user/eel"] 5 | path = src/enigmactl/user/eel 6 | url = https://github.com/rafael-santiago/eel 7 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/README.md -------------------------------------------------------------------------------- /etc/99-enigma.rules: -------------------------------------------------------------------------------- 1 | KERNEL=="enigma", NAME="enigma", MODE="0666" 2 | -------------------------------------------------------------------------------- /etc/Equation-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/Equation-1.png -------------------------------------------------------------------------------- /etc/Equation-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/Equation-2.png -------------------------------------------------------------------------------- /etc/Equation-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/Equation-3.png -------------------------------------------------------------------------------- /etc/Equation-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/Equation-4.png -------------------------------------------------------------------------------- /etc/Equation-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/Equation-5.png -------------------------------------------------------------------------------- /etc/Equation-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/Equation-6.png -------------------------------------------------------------------------------- /etc/Equation-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/Equation-7.png -------------------------------------------------------------------------------- /etc/Equation-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/Equation-8.png -------------------------------------------------------------------------------- /etc/brute-force.md: -------------------------------------------------------------------------------- 1 | # How long does it take to attack Enigma by brute force? 2 | 3 | Let's quantify the total of possible settings that should be tested on a brute force attack against the Enigma. 4 | 5 | The machine is configured with three rotors in any of three "slots", so the Equation 1 denotes the possible arrangements. 6 | 7 | ![Equation-1](https://github.com/rafael-santiago/dev-enigma/blob/master/etc/Equation-1.png) 8 | 9 | Each of the three rotors also can assume twenty-six initial positions. Equation 2 denotes the total of possible positions of each rotor. 10 | 11 | ![Equation-2](https://github.com/rafael-santiago/dev-enigma/blob/master/etc/Equation-2.png) 12 | 13 | Due to the twenty-six shift levels offered by the rings, the Equation 2 should be updated to Equation (3). 14 | 15 | ![Equation-3](https://github.com/rafael-santiago/dev-enigma/blob/master/etc/Equation-3.png) 16 | 17 | With the plug-board ten letters can be swapped, the Equation 4 denotes the swaps possibilities. 18 | 19 | ![Equation-4](https://github.com/rafael-santiago/dev-enigma/blob/master/etc/Equation-4.png) 20 | 21 | Three rotors are used during the encryption but they are chose from a set of eight rotors, the Equation 5 denotes it. 22 | 23 | ![Equation-5](https://github.com/rafael-santiago/dev-enigma/blob/master/etc/Equation-5.png) 24 | 25 | The Equation (1) and (5) can be combined as shown in Equation (6). 26 | 27 | ![Equation-6](https://github.com/rafael-santiago/dev-enigma/blob/master/etc/Equation-6.png) 28 | 29 | Finally, the two possible reflectors possibilities follows denoted by Equation (7) 30 | 31 | ![Equation-7](https://github.com/rafael-santiago/dev-enigma/blob/master/etc/Equation-7.png) 32 | 33 | The final security offered by a cryptosystem that is a composite of two or more cryptosystems is the product of the isolated security offered 34 | by each one. Thus, the Equation 8 denotes the final security offered by the Enigma cipher. 35 | 36 | ![Equation-8](https://github.com/rafael-santiago/dev-enigma/blob/master/etc/Equation-8.png) 37 | 38 | The Equation (8) expresses the search space of a brute force attack against Enigma. This is the maximum number of unique possible settings 39 | offered by this machine. 40 | -------------------------------------------------------------------------------- /etc/dev-enigma-compat-explained.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/dev-enigma-compat-explained.png -------------------------------------------------------------------------------- /etc/disaster-girl-build-remarks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/disaster-girl-build-remarks.jpg -------------------------------------------------------------------------------- /etc/enigmactl-sh-sample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/enigmactl-sh-sample.gif -------------------------------------------------------------------------------- /etc/enigmactl.sh: -------------------------------------------------------------------------------- 1 | # ---GLUE YOUR SHEEBANG HERE--- 2 | # 3 | # Copyright (C) 2016 by Rafael Santiago 4 | # 5 | # This is free software. You can redistribute it and/or modify under 6 | # the terms of the GNU General Public License version 2. 7 | # 8 | # 9 | 10 | backtitle="/dev/enigma Setup" 11 | 12 | l_rotor="i" 13 | m_rotor="ii" 14 | r_rotor="iii" 15 | l_rotor_at="a" 16 | m_rotor_at="a" 17 | r_rotor_at="z" 18 | reflector="c" 19 | l_ring="1" 20 | m_ring="1" 21 | r_ring="1" 22 | plugboard="" 23 | 24 | l_rotor=$(dialog --stdout --backtitle "$backtitle" --radiolist "Select the left rotor:" 0 0 0 i "" on ii "" off iii "" off iv "" off v "" off vi "" off vii "" off viii "" off) 25 | 26 | function abort() { 27 | echo "INFO: Aborted by the user." 28 | exit 1 29 | } 30 | 31 | if [ -z $l_rotor ]; then 32 | abort 33 | fi 34 | 35 | m_rotor=$(dialog --stdout --backtitle "$backtitle" --radiolist "Select the middle rotor:" 0 0 0 i "" off ii "" on iii "" off iv "" off v "" off vi "" off vii "" off viii "" off) 36 | 37 | if [ -z $m_rotor ]; then 38 | abort 39 | fi 40 | 41 | r_rotor=$(dialog --stdout --backtitle "$backtitle" --radiolist "Select the right rotor:" 0 0 0 i "" off ii "" off iii "" on iv "" off v "" off vi "" off vii "" off viii "" off) 42 | 43 | if [ -z $r_rotor ]; then 44 | abort 45 | fi 46 | 47 | l_rotor_at=$(dialog --stdout --backtitle "$backtitle" --radiolist "The left rotor will begin at:" 0 0 0 A "" on B "" off C "" off D "" off E "" off F "" off G "" off H "" off I "" off J "" off K "" off L "" off M "" off N "" off O "" off P "" off Q "" off R "" off S "" off T "" off U "" off V "" off W "" off X "" off Y "" off Z "" off) 48 | 49 | if [ -z $l_rotor_at ]; then 50 | abort 51 | fi 52 | 53 | m_rotor_at=$(dialog --stdout --backtitle "$backtitle" --radiolist "The middle rotor will begin at:" 0 0 0 A "" on B "" off C "" off D "" off E "" off F "" off G "" off H "" off I "" off J "" off K "" off L "" off M "" off N "" off O "" off P "" off Q "" off R "" off S "" off T "" off U "" off V "" off W "" off X "" off Y "" off Z "" off) 54 | 55 | if [ -z $m_rotor_at ]; then 56 | abort 57 | fi 58 | 59 | r_rotor_at=$(dialog --stdout --backtitle "$backtitle" --radiolist "The right rotor will begin at:" 0 0 0 A "" on B "" off C "" off D "" off E "" off F "" off G "" off H "" off I "" off J "" off K "" off L "" off M "" off N "" off O "" off P "" off Q "" off R "" off S "" off T "" off U "" off V "" off W "" off X "" off Y "" off Z "" off) 60 | 61 | if [ -z $l_rotor_at ]; then 62 | abort 63 | fi 64 | 65 | reflector=$(dialog --stdout --backtitle "$backtitle" --radiolist "Select one reflector:" 0 0 0 B "" off C "" on) 66 | 67 | if [ -z $reflector ]; then 68 | abort 69 | fi 70 | 71 | dialog --backtitle "$backtitle" --yesno "Do you want to set the left ring at position 1?" 0 0 72 | 73 | if [ $? -eq 1 ]; then 74 | l_ring=$(dialog --stdout --backtitle "$backtitle" --radiolist "Select the new left ring position:" 0 0 0 "1" "" off "2" "" on "3" "" off "4" "" off "5" "" off "6" "" off "7" "" off "8" "" off "9" "" off "10" "" off "11" "" off "12" "" off "13" "" off "14" "" off "15" "" off "16" "" off "17" "" off "18" "" off "19" "" off "20" "" off "21" "" off "22" "" off "23" "" off "24" "" off "25" "" off "26" "" off) 75 | 76 | if [ -z $l_ring ]; then 77 | abort 78 | fi 79 | fi 80 | 81 | dialog --backtitle "$backtitle" --yesno "Do you want to set the middle ring at 1?" 0 0 82 | 83 | if [ $? -eq 1 ]; then 84 | m_ring=$(dialog --stdout --backtitle "$backtitle" --radiolist "Select the new middle ring position:" 0 0 0 "1" "" off "2" "" on "3" "" off "4" "" off "5" "" off "6" "" off "7" "" off "8" "" off "9" "" off "10" "" off "11" "" off "12" "" off "13" "" off "14" "" off "15" "" off "16" "" off "17" "" off "18" "" off "19" "" off "20" "" off "21" "" off "22" "" off "23" "" off "24" "" off "25" "" off "26" "" off) 85 | 86 | if [ -z $m_ring ]; then 87 | abort 88 | fi 89 | fi 90 | 91 | dialog --backtitle "$backtitle" --yesno "Do you want to set the right ring at 1?" 0 0 92 | 93 | if [ $? -eq 1 ]; then 94 | r_ring=$(dialog --stdout --backtitle "$backtitle" --radiolist "Select the new right ring position:" 0 0 0 "1" "" off "2" "" on "3" "" off "4" "" off "5" "" off "6" "" off "7" "" off "8" "" off "9" "" off "10" "" off "11" "" off "12" "" off "13" "" off "14" "" off "15" "" off "16" "" off "17" "" off "18" "" off "19" "" off "20" "" off "21" "" off "22" "" off "23" "" off "24" "" off "25" "" off "26" "" off) 95 | 96 | if [ -z $r_ring ]; then 97 | abort 98 | fi 99 | fi 100 | 101 | dialog --backtitle "$backtitle" --yesno "Do you want to let the plugboard without any swap?" 0 0 102 | 103 | if [ $? -eq 1 ]; then 104 | plugboard=$(dialog --stdout --backtitle "$backtitle" --inputbox "So type the plugboard swaps here (S1/S1',...,S10/S10'):" 0 100) 105 | fi 106 | 107 | if [ -z $plugboard ]; then 108 | enigmactl --set --l-rotor=$l_rotor --m-rotor=$m_rotor --r-rotor=$r_rotor --l-rotor-at=$l_rotor_at --m-rotor-at=$m_rotor_at --r-rotor-at=$r_rotor_at --reflector=$reflector --l-ring=$l_ring --m-ring=$m_ring --r-ring=$r_ring 109 | else 110 | enigmactl --set --l-rotor=$l_rotor --m-rotor=$m_rotor --r-rotor=$r_rotor --l-rotor-at=$l_rotor_at --m-rotor-at=$m_rotor_at --r-rotor-at=$r_rotor_at --reflector=$reflector --l-ring=$l_ring --m-ring=$m_ring --r-ring=$r_ring --plugboard=$plugboard 111 | fi 112 | 113 | -------------------------------------------------------------------------------- /etc/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafael-santiago/dev-enigma/9718568fac2b51ffa4295a332ed42c8b8a9e5a07/etc/logo.png -------------------------------------------------------------------------------- /src/.ivk: -------------------------------------------------------------------------------- 1 | --forgefiles=Forgefile.hsl --Forgefile-projects=dev-enigma 2 | -------------------------------------------------------------------------------- /src/Forgefile.hsl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 by Rafael Santiago 3 | # 4 | # This is free software. You can redistribute it and/or modify under 5 | # the terms of the GNU General Public License version 2. 6 | # 7 | # 8 | 9 | include toolsets.hsl 10 | include run_test.hsl 11 | include installer.hsl 12 | include mkclean.hsl 13 | 14 | var includes type list; 15 | var cflags type list; 16 | var libraries type list; 17 | var ldflags type list; 18 | 19 | var LKM_toolset type string; 20 | 21 | dev-enigma.preloading() { 22 | if (hefesto.sys.os_name() == "linux") { 23 | $LKM_toolset = "linux-lkm"; 24 | } else if (hefesto.sys.os_name() == "freebsd") { 25 | $LKM_toolset = "freebsd-kld"; 26 | } else { 27 | $LKM_toolset = "cry-baby-cry"; 28 | } 29 | } 30 | 31 | project dev-enigma : toolset $LKM_toolset : "mod.c", $includes, $cflags, $libraries, $ldflags, "enigma"; 32 | 33 | dev-enigma.prologue() { 34 | cleaner(); 35 | 36 | device_installer(); 37 | 38 | # INFO(Santiago): The KBuild runs relative to the kernel source tree, for this reason is important to 39 | # define the local include directories as full-paths. 40 | 41 | $includes.add_item(hefesto.sys.pwd()); 42 | $includes.add_item(hefesto.sys.make_path(hefesto.sys.pwd(), "eel")); 43 | $includes.add_item(hefesto.sys.make_path(hefesto.sys.pwd(), "ebuf")); 44 | $includes.add_item(hefesto.sys.make_path(hefesto.sys.pwd(), "dev_ctx")); 45 | $includes.add_item(hefesto.sys.make_path(hefesto.sys.pwd(), hefesto.sys.make_path("fops_impl", hefesto.sys.os_name()))); 46 | $includes.add_item(hefesto.sys.make_path(hefesto.sys.pwd(), hefesto.sys.make_path("mod_traps", hefesto.sys.os_name()))); 47 | $includes.add_item(hefesto.sys.make_path(hefesto.sys.pwd(), "enigmactl")); 48 | } 49 | 50 | dev-enigma.epilogue() { 51 | if (hefesto.sys.last_forge_result() == 0) { 52 | run_test(); 53 | forge_user_enigmactl(); 54 | hefesto.sys.echo("\n" + 55 | "*** All /dev/enigma was built. Let's celebrate, we are still alive!\n" + 56 | " For installing issues you should use: 'hefesto --install'\n"); 57 | } 58 | } 59 | 60 | local function forge_user_enigmactl() : result type none { 61 | var cwd type string; 62 | $cwd = hefesto.sys.pwd(); 63 | 64 | if (hefesto.sys.cd("enigmactl/user")) { 65 | hefesto.sys.forge("enigmactl", "Forgefile.hsl", "--obj-output-dir=o --bin-output-dir=bin"); 66 | hefesto.sys.cd($cwd); 67 | if (hefesto.sys.last_forge_result() != 0) { 68 | hefesto.project.abort(hefesto.sys.last_forge_result()); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/dev_ctx/dev_ctx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "dev_ctx.h" 9 | #if defined(__FreeBSD__) 10 | #include 11 | #endif 12 | #include 13 | #include 14 | 15 | static struct dev_enigma_ctx g_dev_ctx; 16 | 17 | static void copy_default_enigma_setting(libeel_enigma_ctx *enigma); 18 | 19 | struct dev_enigma_ctx *dev_ctx(void) { 20 | return &g_dev_ctx; 21 | } 22 | 23 | int lock_uline(const int uline) { 24 | if (!(uline >= 0 && uline <= DEV_USAGE_LINES_NR)) { 25 | return 0; 26 | } 27 | 28 | #if defined(__linux__) 29 | if (!mutex_trylock(&g_dev_ctx.ulines[uline].lock)) { 30 | return 0; 31 | } 32 | #elif defined(__FreeBSD__) 33 | if (!mtx_trylock(&g_dev_ctx.ulines[uline].lock)) { 34 | return 0; 35 | } 36 | #endif 37 | 38 | return 1; 39 | } 40 | 41 | void unlock_uline(const int uline) { 42 | if (!(uline >= 0 && uline <= DEV_USAGE_LINES_NR)) { 43 | return; 44 | } 45 | #if defined(__linux__) 46 | mutex_unlock(&g_dev_ctx.ulines[uline].lock); 47 | #elif defined(__FreeBSD__) 48 | mtx_unlock(&g_dev_ctx.ulines[uline].lock); 49 | #endif 50 | } 51 | 52 | int new_uline(void) { 53 | int u; 54 | int uline = -1; 55 | 56 | for (u = 0; u < DEV_USAGE_LINES_NR && uline == -1; u++) { 57 | lock_uline(u); 58 | if (g_dev_ctx.ulines[u].enigma == NULL) { 59 | g_dev_ctx.ulines[u].enigma = libeel_new_enigma_ctx(); 60 | if (g_dev_ctx.ulines[u].enigma != NULL) { 61 | uline = u; 62 | if (g_dev_ctx.default_setting != NULL) { 63 | copy_default_enigma_setting(g_dev_ctx.ulines[u].enigma); 64 | g_dev_ctx.ulines[u].has_init = libeel_init_machine(g_dev_ctx.ulines[u].enigma); 65 | } 66 | } 67 | } 68 | unlock_uline(u); 69 | } 70 | 71 | return uline; 72 | } 73 | 74 | void release_uline(const int uline) { 75 | if (!(uline >= 0 && uline <= DEV_USAGE_LINES_NR)) { 76 | return; 77 | } 78 | 79 | lock_uline(uline); 80 | 81 | if (g_dev_ctx.ulines[uline].enigma != NULL) { 82 | libeel_del_enigma_ctx(g_dev_ctx.ulines[uline].enigma); 83 | g_dev_ctx.ulines[uline].enigma = NULL; 84 | } 85 | 86 | if (g_dev_ctx.ulines[uline].ebuf_head != NULL) { 87 | del_ebuf_ctx(g_dev_ctx.ulines[uline].ebuf_head); 88 | g_dev_ctx.ulines[uline].ebuf_head = NULL; 89 | } 90 | 91 | unlock_uline(uline); 92 | } 93 | 94 | struct dev_enigma_usage_line_ctx *dev_uline_ctx(const int uline) { 95 | if (!(uline >= 0 && uline <= DEV_USAGE_LINES_NR)) { 96 | return NULL; 97 | } 98 | 99 | if (g_dev_ctx.ulines[uline].enigma == NULL) { 100 | return NULL; 101 | } 102 | 103 | return &g_dev_ctx.ulines[uline]; 104 | } 105 | 106 | void init_ulines(void) { 107 | int u; 108 | for (u = 0; u < DEV_USAGE_LINES_NR; u++) { 109 | g_dev_ctx.ulines[u].enigma = NULL; 110 | g_dev_ctx.ulines[u].ebuf_head = NULL; 111 | #if defined(__linux__) 112 | mutex_init(&g_dev_ctx.ulines[u].lock); 113 | #elif defined(__FreeBSD__) 114 | mtx_init(&g_dev_ctx.ulines[u].lock, "DEV_ENIGMA_uline_lock", NULL, MTX_DEF); 115 | #endif 116 | g_dev_ctx.ulines[u].has_init = 0; 117 | } 118 | } 119 | 120 | void deinit_ulines(void) { 121 | int u; 122 | for (u = 0; u < DEV_USAGE_LINES_NR; u++) { 123 | release_uline(u); 124 | #if defined(__linux__) 125 | mutex_destroy(&g_dev_ctx.ulines[u].lock); 126 | #elif defined(__FreeBSD__) 127 | mtx_destroy(&g_dev_ctx.ulines[u].lock); 128 | #endif 129 | } 130 | } 131 | 132 | static void copy_default_enigma_setting(libeel_enigma_ctx *enigma) { 133 | if (enigma == NULL) { 134 | return; 135 | } 136 | #if defined(__linux__) 137 | if (mutex_trylock(&g_dev_ctx.lock)) { 138 | memcpy(enigma, g_dev_ctx.default_setting, sizeof(libeel_enigma_ctx)); 139 | mutex_unlock(&g_dev_ctx.lock); 140 | } 141 | #elif defined(__FreeBSD__) 142 | if (mtx_trylock(&g_dev_ctx.lock)) { 143 | memcpy(enigma, g_dev_ctx.default_setting, sizeof(libeel_enigma_ctx)); 144 | mtx_unlock(&g_dev_ctx.lock); 145 | } 146 | #endif 147 | } 148 | 149 | int set_default_enigma_setting(const libeel_enigma_ctx *enigma) { 150 | int result = 0; 151 | 152 | #if defined(__linux__) 153 | if (!mutex_trylock(&g_dev_ctx.lock)) { 154 | return 0; 155 | } 156 | #else 157 | if (!mtx_trylock(&g_dev_ctx.lock)) { 158 | return 0; 159 | } 160 | #endif 161 | 162 | if (g_dev_ctx.default_setting != NULL) { 163 | libeel_del_enigma_ctx(g_dev_ctx.default_setting); 164 | } 165 | 166 | g_dev_ctx.default_setting = libeel_new_enigma_ctx(); 167 | 168 | if (g_dev_ctx.default_setting == NULL) { 169 | goto ___set_epilogue; 170 | } 171 | 172 | memcpy(g_dev_ctx.default_setting, enigma, sizeof(libeel_enigma_ctx)); 173 | 174 | result = libeel_init_machine(g_dev_ctx.default_setting); 175 | 176 | ___set_epilogue: 177 | if (result == 0 && g_dev_ctx.default_setting != NULL) { 178 | libeel_del_enigma_ctx(g_dev_ctx.default_setting); 179 | g_dev_ctx.default_setting = NULL; 180 | } 181 | 182 | #if defined(__linux__) 183 | mutex_unlock(&g_dev_ctx.lock); 184 | #elif defined(__FreeBSD__) 185 | mtx_unlock(&g_dev_ctx.lock); 186 | #endif 187 | 188 | return result; 189 | } 190 | 191 | int unset_default_enigma_setting(void) { 192 | #if defined(__linux__) 193 | if (!mutex_trylock(&g_dev_ctx.lock)) { 194 | return 0; 195 | } 196 | #elif defined(__FreeBSD__) 197 | if (!mtx_trylock(&g_dev_ctx.lock)) { 198 | return 0; 199 | } 200 | #endif 201 | 202 | if (g_dev_ctx.default_setting != NULL) { 203 | libeel_del_enigma_ctx(g_dev_ctx.default_setting); 204 | g_dev_ctx.default_setting = NULL; 205 | } 206 | 207 | #if defined(__linux__) 208 | mutex_unlock(&g_dev_ctx.lock); 209 | #elif defined(__FreeBSD__) 210 | mtx_unlock(&g_dev_ctx.lock); 211 | #endif 212 | 213 | return 1; 214 | } 215 | -------------------------------------------------------------------------------- /src/dev_ctx/dev_ctx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_DEV_CTX_H 9 | #define DEV_ENIGMA_DEV_CTX_H 1 10 | 11 | #include 12 | #include 13 | 14 | #if defined(__linux__) 15 | 16 | #include 17 | 18 | #elif defined(__FreeBSD__) 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #endif 25 | 26 | // INFO(Santiago): DEV_USAGE_LINES_NR specifies the number of users 27 | // which can be simultaneously hung in this device. 28 | 29 | #define DEV_USAGE_LINES_NR 10 30 | 31 | struct dev_enigma_usage_line_ctx { 32 | libeel_enigma_ctx *enigma; 33 | ebuf_ctx *ebuf_head, *ebuf_tail; 34 | #if defined(__linux__) 35 | struct mutex lock; 36 | #elif defined(__FreeBSD__) 37 | struct mtx lock; 38 | #endif 39 | int has_init; 40 | }; 41 | 42 | struct dev_enigma_ctx { 43 | struct dev_enigma_usage_line_ctx ulines[DEV_USAGE_LINES_NR]; 44 | #if defined(__linux__) 45 | int major_nr; 46 | struct class *device_class; 47 | struct device *device; 48 | #elif defined(__FreeBSD__) 49 | struct cdev *device; 50 | #endif 51 | libeel_enigma_ctx *default_setting; 52 | #if defined(__linux__) 53 | struct mutex lock; 54 | #elif defined(__FreeBSD__) 55 | struct mtx lock; 56 | #endif 57 | }; 58 | 59 | struct dev_enigma_ctx *dev_ctx(void); 60 | 61 | int lock_uline(const int uline); 62 | 63 | void unlock_uline(const int uline); 64 | 65 | int new_uline(void); 66 | 67 | void release_uline(const int uline); 68 | 69 | struct dev_enigma_usage_line_ctx *dev_uline_ctx(const int uline); 70 | 71 | void init_ulines(void); 72 | 73 | void deinit_ulines(void); 74 | 75 | void destroy_uline_mutexes(void); 76 | 77 | int set_default_enigma_setting(const libeel_enigma_ctx *enigma); 78 | 79 | int unset_default_enigma_setting(void); 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/ebuf/ebuf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "ebuf.h" 9 | 10 | #if defined(__linux__) 11 | 12 | #include 13 | 14 | #define new_ebuf_ctx(e) ( (e) = (ebuf_ctx *) kmalloc(sizeof(ebuf_ctx), GFP_ATOMIC), (e)->c = 0, (e)->next = NULL ) 15 | 16 | #elif defined(__FreeBSD__) 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | MALLOC_DEFINE(M_EBUF, "DEV_ENIGMA_ebuf", "Allocations related with ebuf"); 23 | 24 | #define new_ebuf_ctx(e) ( (e) = (ebuf_ctx *) malloc(sizeof(ebuf_ctx), M_EBUF, M_NOWAIT), (e)->c = 0, (e)->next = NULL ) 25 | 26 | #endif 27 | 28 | void del_ebuf_ctx(ebuf_ctx *ebuf) { 29 | ebuf_ctx *t, *p; 30 | for (t = p = ebuf; t != NULL; p = t) { 31 | t = p->next; 32 | p->c = 0; 33 | #if defined(__linux__) 34 | kfree(p); 35 | #elif defined(__FreeBSD__) 36 | free(p, M_EBUF); 37 | #endif 38 | } 39 | } 40 | 41 | int add_char_to_ebuf_ctx(ebuf_ctx **ebuf, const char c, ebuf_ctx *tail) { 42 | ebuf_ctx *ep; 43 | 44 | if ((*ebuf) == NULL) { 45 | new_ebuf_ctx((*ebuf)); 46 | ep = (*ebuf); 47 | } else { 48 | if (tail != NULL) { 49 | new_ebuf_ctx(tail->next); 50 | ep = tail->next; 51 | } else { 52 | for (ep = (*ebuf); ep->next != NULL; ep = ep->next); 53 | new_ebuf_ctx(ep->next); 54 | ep = ep->next; 55 | } 56 | } 57 | 58 | if (ep == NULL) { 59 | return 0; 60 | } 61 | 62 | if (tail != NULL) { 63 | tail = ep; 64 | } 65 | 66 | ep->c = c; 67 | 68 | return 1; 69 | } 70 | 71 | char get_char_from_ebuf_ctx(ebuf_ctx **ebuf) { 72 | ebuf_ctx *ep; 73 | char c; 74 | 75 | if (ebuf == NULL) { 76 | return 0; 77 | } 78 | 79 | ep = *ebuf; 80 | 81 | if (ep == NULL) { 82 | return 0; 83 | } 84 | 85 | c = ep->c; 86 | 87 | *ebuf = ep->next; 88 | 89 | ep->next = NULL; 90 | 91 | del_ebuf_ctx(ep); 92 | 93 | return c; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /src/ebuf/ebuf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_EBUF_H 9 | #define DEV_ENIGMA_EBUF_H 1 10 | 11 | typedef struct _ebuf_ctx { 12 | char c; 13 | struct _ebuf_ctx *next; 14 | }ebuf_ctx; 15 | 16 | int add_char_to_ebuf_ctx(ebuf_ctx **ebuf, const char c, ebuf_ctx *tail); 17 | 18 | char get_char_from_ebuf_ctx(ebuf_ctx **ebuf); 19 | 20 | void del_ebuf_ctx(ebuf_ctx *ebuf); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/eel/eel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006, 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "eel.h" 9 | 10 | #if defined(__linux__) 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #elif defined(__FreeBSD__) 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | MALLOC_DEFINE(M_EEL, "DEV_ENIGMA_eel", "Allocations related with libeel"); 27 | 28 | #endif 29 | 30 | struct libeel_rotor_wiring_ctx { 31 | libeel_rotor_wiring_t normal, inverse; 32 | libeel_notch_t notch; 33 | }; 34 | 35 | static struct libeel_rotor_wiring_ctx g_rotor_wiring[] = { 36 | { 37 | { 38 | 'E', 'K', 'M', 'F', 'L', 'G', 'D', 'Q', 'V', 'Z', 'N', 'T', 'O', 39 | 'W', 'Y', 'H', 'X', 'U', 'S', 'P', 'A', 'I', 'B', 'R', 'C', 'J' 40 | }, 41 | { 42 | 'U', 'W', 'Y', 'G', 'A', 'D', 'F', 'P', 'V', 'Z', 'B', 'E', 'C', 43 | 'K', 'M', 'T', 'H', 'X', 'S', 'L', 'R', 'I', 'N', 'Q', 'O', 'J' 44 | }, 45 | 'R' 46 | }, 47 | { 48 | { 49 | 'A', 'J', 'D', 'K', 'S', 'I', 'R', 'U', 'X', 'B', 'L', 'H', 'W', 50 | 'T', 'M', 'C', 'Q', 'G', 'Z', 'N', 'P', 'Y', 'F', 'V', 'O', 'E' 51 | }, 52 | { 53 | 'A', 'J', 'P', 'C', 'Z', 'W', 'R', 'L', 'F', 'B', 'D', 'K', 'O', 54 | 'T', 'Y', 'U', 'Q', 'G', 'E', 'N', 'H', 'X', 'M', 'I', 'V', 'S' 55 | }, 56 | 'F' 57 | }, 58 | { 59 | { 60 | 'B', 'D', 'F', 'H', 'J', 'L', 'C', 'P', 'R', 'T', 'X', 'V', 'Z', 61 | 'N', 'Y', 'E', 'I', 'W', 'G', 'A', 'K', 'M', 'U', 'S', 'Q', 'O' 62 | }, 63 | { 64 | 'T', 'A', 'G', 'B', 'P', 'C', 'S', 'D', 'Q', 'E', 'U', 'F', 'V', 65 | 'N', 'Z', 'H', 'Y', 'I', 'X', 'J', 'W', 'L', 'R', 'K', 'O', 'M' 66 | }, 67 | 'W' 68 | }, 69 | { 70 | { 71 | 'E', 'S', 'O', 'V', 'P', 'Z', 'J', 'A', 'Y', 'Q', 'U', 'I', 'R', 72 | 'H', 'X', 'L', 'N', 'F', 'T', 'G', 'K', 'D', 'C', 'M', 'W', 'B' 73 | }, 74 | { 75 | 'H', 'Z', 'W', 'V', 'A', 'R', 'T', 'N', 'L', 'G', 'U', 'P', 'X', 76 | 'Q', 'C', 'E', 'J', 'M', 'B', 'S', 'K', 'D', 'Y', 'O', 'I', 'F' 77 | }, 78 | 'K' 79 | }, 80 | { 81 | { 82 | 'V', 'Z', 'B', 'R', 'G', 'I', 'T', 'Y', 'U', 'P', 'S', 'D', 'N', 83 | 'H', 'L', 'X', 'A', 'W', 'M', 'J', 'Q', 'O', 'F', 'E', 'C', 'K' 84 | }, 85 | { 86 | 'Q', 'C', 'Y', 'L', 'X', 'W', 'E', 'N', 'F', 'T', 'Z', 'O', 'S', 87 | 'M', 'V', 'J', 'U', 'D', 'K', 'G', 'I', 'A', 'R', 'P', 'H', 'B' 88 | }, 89 | 'A' 90 | }, 91 | { 92 | { 93 | 'J', 'P', 'G', 'V', 'O', 'U', 'M', 'F', 'Y', 'Q', 'B', 'E', 'N', 94 | 'H', 'Z', 'R', 'D', 'K', 'A', 'S', 'X', 'L', 'I', 'C', 'T', 'W' 95 | }, 96 | { 97 | 'S', 'K', 'X', 'Q', 'L', 'H', 'C', 'N', 'W', 'A', 'R', 'V', 'G', 98 | 'M', 'E', 'B', 'J', 'P', 'T', 'Y', 'F', 'D', 'Z', 'U', 'I', 'O' 99 | }, 100 | 'A' 101 | }, 102 | { 103 | { 104 | 'N', 'Z', 'J', 'H', 'G', 'R', 'C', 'X', 'M', 'Y', 'S', 'W', 'B', 105 | 'O', 'U', 'F', 'A', 'I', 'V', 'L', 'P', 'E', 'K', 'Q', 'D', 'T' 106 | }, 107 | { 108 | 'Q', 'M', 'G', 'Y', 'V', 'P', 'E', 'D', 'R', 'C', 'W', 'T', 'I', 109 | 'A', 'N', 'U', 'X', 'F', 'K', 'Z', 'O', 'S', 'L', 'H', 'J', 'B' 110 | }, 111 | 'A' 112 | }, 113 | { 114 | { 115 | 'F', 'K', 'Q', 'H', 'T', 'L', 'X', 'O', 'C', 'B', 'J', 'S', 'P', 116 | 'D', 'Z', 'R', 'A', 'M', 'E', 'W', 'N', 'I', 'U', 'Y', 'G', 'V' 117 | }, 118 | { 119 | 'Q', 'J', 'I', 'N', 'S', 'A', 'Y', 'D', 'V', 'K', 'B', 'F', 'R', 120 | 'U', 'H', 'M', 'C', 'P', 'L', 'E', 'W', 'Z', 'T', 'G', 'X', 'O' 121 | }, 122 | 'N' 123 | } 124 | }; 125 | 126 | static size_t g_rotor_wiring_nr = sizeof(g_rotor_wiring) / sizeof(g_rotor_wiring[0]); 127 | 128 | static libeel_rotor_wiring_t g_reflector[] = { 129 | { 130 | 'Y', 'R', 'U', 'H', 'Q', 'S', 'L', 'D', 'P', 'X', 'N', 'G', 'O', 131 | 'K', 'M', 'I', 'E', 'R', 'F', 'Z', 'C', 'W', 'V', 'J', 'A', 'T' 132 | }, 133 | { 134 | 'F', 'V', 'P', 'J', 'I', 'A', 'O', 'Y', 'E', 'D', 'R', 'Z', 'X', 135 | 'W', 'G', 'C', 'T', 'K', 'U', 'Q', 'S', 'B', 'N', 'M', 'H', 'L' 136 | } 137 | }; 138 | 139 | static size_t g_reflector_nr = sizeof(g_reflector) / sizeof(g_reflector[0]); 140 | 141 | static libeel_rotor_wiring_t g_basic_display = { 142 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 143 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' 144 | }; 145 | 146 | static void libeel_set_rotor_position(libeel_rotor_wiring_t rotor, const libeel_rotor_display_t stop); 147 | 148 | static void libeel_set_rotor(libeel_rotor_wiring_t rotor, libeel_rotor_wiring_t rotor_inv, const libeel_rotor_t r); 149 | 150 | static void libeel_spin_rotor(libeel_rotor_wiring_t rotor); 151 | 152 | static void libeel_spin_rotor_l(libeel_rotor_wiring_t rotor); 153 | 154 | static void libeel_set_plugboard(libeel_enigma_ctx *enigma); 155 | 156 | static void libeel_refresh_display(libeel_rotor_display_t *display); 157 | 158 | static int libeel_setting_sanity_check(const libeel_enigma_ctx *enigma); 159 | 160 | static libeel_rotor_display_t libeel_get_rotor_signal(const libeel_rotor_wiring_t rotor_offset, const libeel_rotor_wiring_t rotor, const char input); 161 | 162 | static void libeel_set_reflector(libeel_rotor_wiring_t reflector, const libeel_reflector_t r); 163 | 164 | static void libeel_clear_enigma_ctx(libeel_enigma_ctx *enigma); 165 | 166 | int libeel_init_machine(libeel_enigma_ctx *enigma) { 167 | 168 | libeel_ring_t r; 169 | 170 | if (enigma == NULL) { 171 | return 0; 172 | } 173 | 174 | if (!libeel_setting_sanity_check(enigma)) { 175 | return 0; 176 | } 177 | 178 | libeel_set_rotor(libeel_rotor(enigma, l), libeel_rotor_inv(enigma, l), enigma->left_rotor); 179 | 180 | libeel_set_rotor(libeel_rotor(enigma, m), libeel_rotor_inv(enigma, m), enigma->middle_rotor); 181 | libeel_notch(enigma, m) = g_rotor_wiring[enigma->middle_rotor % g_rotor_wiring_nr].notch; 182 | 183 | libeel_set_rotor(libeel_rotor(enigma, r), libeel_rotor_inv(enigma, r), enigma->right_rotor); 184 | libeel_notch(enigma, r) = g_rotor_wiring[enigma->right_rotor % g_rotor_wiring_nr].notch; 185 | 186 | memcpy(libeel_rotor_offset(enigma, l), g_basic_display, sizeof(libeel_rotor_wiring_t)); 187 | libeel_set_rotor_position(libeel_rotor_offset(enigma, l), libeel_rotor_at(enigma, l)); 188 | 189 | memcpy(libeel_rotor_offset(enigma, m), g_basic_display, sizeof(libeel_rotor_wiring_t)); 190 | libeel_set_rotor_position(libeel_rotor_offset(enigma, m), libeel_rotor_at(enigma, m)); 191 | 192 | memcpy(libeel_rotor_offset(enigma, r), g_basic_display, sizeof(libeel_rotor_wiring_t)); 193 | libeel_set_rotor_position(libeel_rotor_offset(enigma, r), libeel_rotor_at(enigma, r)); 194 | 195 | for (r = 1; r < libeel_ring(enigma, l); r++) { 196 | libeel_spin_rotor_l(libeel_rotor_offset(enigma, l)); 197 | } 198 | 199 | for (r = 1; r < libeel_ring(enigma, m); r++) { 200 | libeel_spin_rotor_l(libeel_rotor_offset(enigma, m)); 201 | } 202 | 203 | for (r = 1; r < libeel_ring(enigma, r); r++) { 204 | libeel_spin_rotor_l(libeel_rotor_offset(enigma, r)); 205 | } 206 | 207 | libeel_display(enigma, l) = libeel_rotor_at(enigma, l); 208 | libeel_display(enigma, m) = libeel_rotor_at(enigma, m); 209 | libeel_display(enigma, r) = libeel_rotor_at(enigma, r); 210 | 211 | memcpy(libeel_keyboard(enigma), g_basic_display, sizeof(libeel_rotor_wiring_t)); 212 | 213 | libeel_set_plugboard(enigma); 214 | 215 | libeel_set_reflector(libeel_reflector(enigma), enigma->reflector); 216 | 217 | return 1; 218 | } 219 | 220 | static void libeel_set_rotor(libeel_rotor_wiring_t rotor, libeel_rotor_wiring_t rotor_inv, const libeel_rotor_t r) { 221 | memcpy(rotor, g_rotor_wiring[r % g_rotor_wiring_nr].normal, sizeof(libeel_rotor_wiring_t)); 222 | memcpy(rotor_inv, g_rotor_wiring[r % g_rotor_wiring_nr].inverse, sizeof(libeel_rotor_wiring_t)); 223 | } 224 | 225 | static void libeel_set_rotor_position(libeel_rotor_wiring_t rotor, const libeel_rotor_display_t stop) { 226 | int s = toupper(stop); 227 | while (s-- > 'A') { 228 | libeel_spin_rotor(rotor); 229 | } 230 | } 231 | 232 | static void libeel_spin_rotor(libeel_rotor_wiring_t rotor) { 233 | int s = 24; 234 | char aux = rotor[25]; 235 | 236 | while (s >= 0) { 237 | rotor[s + 1] = rotor[s]; 238 | s--; 239 | } 240 | 241 | rotor[0] = aux; 242 | } 243 | 244 | static void libeel_spin_rotor_l(libeel_rotor_wiring_t rotor) { 245 | int s = 1; 246 | char aux = rotor[0]; 247 | 248 | while (s < 26) { 249 | rotor[s + 1] = rotor[s]; 250 | s++; 251 | } 252 | 253 | rotor[25] = aux; 254 | } 255 | 256 | static void libeel_set_plugboard(libeel_enigma_ctx *enigma) { 257 | if (libeel_plugboard(enigma, 1).l != 0) { 258 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 1).l) - 'A'] = toupper(libeel_plugboard(enigma, 1).r); 259 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 1).r) - 'A'] = toupper(libeel_plugboard(enigma, 1).l); 260 | } 261 | 262 | if (libeel_plugboard(enigma, 2).l != 0) { 263 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 2).l) - 'A'] = toupper(libeel_plugboard(enigma, 2).r); 264 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 2).r) - 'A'] = toupper(libeel_plugboard(enigma, 2).l); 265 | } 266 | 267 | if (libeel_plugboard(enigma, 3).l != 0) { 268 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 3).l) - 'A'] = toupper(libeel_plugboard(enigma, 3).r); 269 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 3).r) - 'A'] = toupper(libeel_plugboard(enigma, 3).l); 270 | } 271 | 272 | if (libeel_plugboard(enigma, 4).l != 0) { 273 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 4).l) - 'A'] = toupper(libeel_plugboard(enigma, 4).r); 274 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 4).r) - 'A'] = toupper(libeel_plugboard(enigma, 4).l); 275 | } 276 | 277 | if (libeel_plugboard(enigma, 5).l != 0) { 278 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 5).l) - 'A'] = toupper(libeel_plugboard(enigma, 5).r); 279 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 5).r) - 'A'] = toupper(libeel_plugboard(enigma, 5).l); 280 | } 281 | 282 | if (libeel_plugboard(enigma, 6).l != 0) { 283 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 6).l) - 'A'] = toupper(libeel_plugboard(enigma, 6).r); 284 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 6).r) - 'A'] = toupper(libeel_plugboard(enigma, 6).l); 285 | } 286 | 287 | if (libeel_plugboard(enigma, 7).l != 0) { 288 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 7).l) - 'A'] = toupper(libeel_plugboard(enigma, 7).r); 289 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 7).r) - 'A'] = toupper(libeel_plugboard(enigma, 7).l); 290 | } 291 | 292 | if (libeel_plugboard(enigma, 8).l != 0) { 293 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 8).l) - 'A'] = toupper(libeel_plugboard(enigma, 8).r); 294 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 8).r) - 'A'] = toupper(libeel_plugboard(enigma, 8).l); 295 | } 296 | 297 | if (libeel_plugboard(enigma, 9).l != 0) { 298 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 9).l) - 'A'] = toupper(libeel_plugboard(enigma, 9).r); 299 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 9).r) - 'A'] = toupper(libeel_plugboard(enigma, 9).l); 300 | } 301 | 302 | if (libeel_plugboard(enigma, 10).l != 0) { 303 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 10).l) - 'A'] = toupper(libeel_plugboard(enigma, 10).r); 304 | libeel_keyboard(enigma)[toupper(libeel_plugboard(enigma, 10).r) - 'A'] = toupper(libeel_plugboard(enigma, 10).l); 305 | } 306 | } 307 | 308 | static void libeel_set_reflector(libeel_rotor_wiring_t reflector, const libeel_reflector_t r) { 309 | memcpy(reflector, g_reflector[r % g_reflector_nr], sizeof(libeel_rotor_wiring_t)); 310 | } 311 | 312 | char libeel_type(libeel_enigma_ctx *enigma) { 313 | char outchar = 0; 314 | libeel_rotor_display_t m_pos = 0; 315 | int spin = 0, is_lwr = 0; 316 | 317 | if (enigma == NULL) { 318 | return 0; 319 | } 320 | 321 | outchar = libeel_enigma_input(enigma); 322 | 323 | if (isalpha(outchar)) { 324 | m_pos = libeel_display(enigma, m) + 1; 325 | 326 | if (m_pos > 'Z') { 327 | m_pos = 'A'; 328 | } 329 | 330 | spin = (libeel_display(enigma, r) == libeel_notch(enigma, r) && m_pos == libeel_notch(enigma, m)); 331 | 332 | libeel_spin_rotor(libeel_rotor_offset(enigma, r)); 333 | 334 | libeel_refresh_display(&libeel_display(enigma, r)); 335 | 336 | if (spin || libeel_display(enigma, r) == libeel_notch(enigma, r)) { 337 | libeel_spin_rotor(libeel_rotor_offset(enigma, m)); 338 | 339 | libeel_refresh_display(&libeel_display(enigma, m)); 340 | 341 | if (libeel_display(enigma, m) == libeel_notch(enigma, m)) { 342 | libeel_spin_rotor(libeel_rotor_offset(enigma, l)); 343 | 344 | libeel_refresh_display(&libeel_display(enigma, l)); 345 | } 346 | } 347 | 348 | is_lwr = islower(outchar); 349 | 350 | outchar = libeel_get_rotor_signal(g_basic_display, libeel_keyboard(enigma), toupper(outchar)); 351 | 352 | outchar = libeel_get_rotor_signal(libeel_rotor_offset(enigma, r), libeel_rotor(enigma, r), outchar); 353 | outchar = libeel_get_rotor_signal(g_basic_display, libeel_rotor_offset(enigma, r), outchar); 354 | 355 | outchar = libeel_get_rotor_signal(libeel_rotor_offset(enigma, m), libeel_rotor(enigma, m), outchar); 356 | outchar = libeel_get_rotor_signal(g_basic_display, libeel_rotor_offset(enigma, m), outchar); 357 | 358 | outchar = libeel_get_rotor_signal(libeel_rotor_offset(enigma, l), libeel_rotor(enigma, l), outchar); 359 | outchar = libeel_get_rotor_signal(g_basic_display, libeel_rotor_offset(enigma, l), outchar); 360 | 361 | outchar = libeel_get_rotor_signal(libeel_reflector(enigma), g_basic_display, outchar); 362 | 363 | outchar = libeel_get_rotor_signal(libeel_rotor_offset(enigma, l), libeel_rotor_inv(enigma, l), outchar); 364 | outchar = libeel_get_rotor_signal(g_basic_display, libeel_rotor_offset(enigma, l), outchar); 365 | 366 | outchar = libeel_get_rotor_signal(libeel_rotor_offset(enigma, m), libeel_rotor_inv(enigma, m), outchar); 367 | outchar = libeel_get_rotor_signal(g_basic_display, libeel_rotor_offset(enigma, m), outchar); 368 | 369 | outchar = libeel_get_rotor_signal(libeel_rotor_offset(enigma, r), libeel_rotor_inv(enigma, r), outchar); 370 | outchar = libeel_get_rotor_signal(g_basic_display, libeel_rotor_offset(enigma, r), outchar); 371 | 372 | outchar = libeel_get_rotor_signal(libeel_keyboard(enigma), g_basic_display, outchar); 373 | 374 | if (is_lwr) { 375 | outchar = tolower(outchar); 376 | } 377 | 378 | libeel_enigma_output(enigma) = outchar; 379 | } 380 | 381 | return outchar; 382 | } 383 | 384 | void libeel_del_enigma_ctx(libeel_enigma_ctx *enigma) { 385 | if (enigma != NULL) { 386 | libeel_clear_enigma_ctx(enigma); 387 | #if defined(__linux__) 388 | kfree(enigma); 389 | #elif defined(__FreeBSD__) 390 | free(enigma, M_EEL); 391 | #endif 392 | } 393 | } 394 | 395 | static void libeel_clear_enigma_ctx(libeel_enigma_ctx *enigma) { 396 | if (enigma != NULL) { 397 | memset(enigma, 0, sizeof(libeel_enigma_ctx)); 398 | libeel_ring(enigma, l) = 1; 399 | libeel_ring(enigma, m) = 1; 400 | libeel_ring(enigma, r) = 1; 401 | } 402 | } 403 | 404 | libeel_enigma_ctx *libeel_new_enigma_ctx(void) { 405 | #if defined(__linux__) 406 | libeel_enigma_ctx *enigma = (libeel_enigma_ctx *)kmalloc(sizeof(libeel_enigma_ctx), GFP_ATOMIC); 407 | #elif defined(__FreeBSD__) 408 | libeel_enigma_ctx *enigma = (libeel_enigma_ctx *)malloc(sizeof(libeel_enigma_ctx), M_EEL, M_NOWAIT); 409 | #endif 410 | libeel_clear_enigma_ctx(enigma); 411 | return enigma; 412 | } 413 | 414 | static libeel_rotor_display_t libeel_get_rotor_signal(const libeel_rotor_wiring_t rotor_offset, const libeel_rotor_wiring_t rotor, const char input) { 415 | int r; 416 | 417 | for (r = 0; r < 26; r++) { 418 | if (rotor_offset[r] == input) { 419 | return rotor[r]; 420 | } 421 | } 422 | 423 | for (r = 0; r < 26; r++) { 424 | if (rotor[r] == input) { 425 | return rotor_offset[r]; 426 | } 427 | } 428 | 429 | return 0; // WARN(Santiago): On normal conditions it should never happen. 430 | } 431 | 432 | static void libeel_refresh_display(libeel_rotor_display_t *display) { 433 | if (display == NULL) { 434 | return; 435 | } 436 | 437 | *display = (toupper(*display) + 1) % 91; 438 | 439 | if (*display == 0) { 440 | *display = 'A'; 441 | } 442 | } 443 | 444 | static int libeel_setting_sanity_check(const libeel_enigma_ctx *enigma) { 445 | if (enigma == NULL) { 446 | return 0; 447 | } 448 | 449 | if (!(enigma->left_rotor >= i && enigma->left_rotor <= viii)) { 450 | return 0; 451 | } 452 | 453 | if (!(enigma->middle_rotor >= i && enigma->middle_rotor <= viii)) { 454 | return 0; 455 | } 456 | 457 | if (!(enigma->right_rotor >= i && enigma->right_rotor <= viii)) { 458 | return 0; 459 | } 460 | 461 | if (enigma->left_rotor == enigma->right_rotor || 462 | enigma->left_rotor == enigma->middle_rotor || 463 | enigma->right_rotor == enigma->middle_rotor) { 464 | return 0; 465 | } 466 | 467 | if (!(enigma->reflector >= b && enigma->reflector <= c)) { 468 | return 0; 469 | } 470 | 471 | if (!(libeel_ring(enigma, l) >= 1 && libeel_ring(enigma, l) <= 26)) { 472 | return 0; 473 | } 474 | 475 | if (!(libeel_ring(enigma, m) >= 1 && libeel_ring(enigma, m) <= 26)) { 476 | return 0; 477 | } 478 | 479 | if (!(libeel_ring(enigma, r) >= 1 && libeel_ring(enigma, r) <= 26)) { 480 | return 0; 481 | } 482 | 483 | if ((libeel_plugboard(enigma, 1).l != 0 && !isalpha(libeel_plugboard(enigma, 1).l)) || 484 | (libeel_plugboard(enigma, 1).r != 0 && !isalpha(libeel_plugboard(enigma, 1).r)) || 485 | (libeel_plugboard(enigma, 1).l != 0 && libeel_plugboard(enigma, 1).r == 0) || 486 | (libeel_plugboard(enigma, 1).r != 0 && libeel_plugboard(enigma, 1).l == 0)) { 487 | return 0; 488 | } 489 | 490 | if ((libeel_plugboard(enigma, 2).l != 0 && !isalpha(libeel_plugboard(enigma, 2).l)) || 491 | (libeel_plugboard(enigma, 2).r != 0 && !isalpha(libeel_plugboard(enigma, 2).r)) || 492 | (libeel_plugboard(enigma, 2).l != 0 && libeel_plugboard(enigma, 2).r == 0) || 493 | (libeel_plugboard(enigma, 2).r != 0 && libeel_plugboard(enigma, 2).l == 0)) { 494 | return 0; 495 | } 496 | 497 | if ((libeel_plugboard(enigma, 3).l != 0 && !isalpha(libeel_plugboard(enigma, 3).l)) || 498 | (libeel_plugboard(enigma, 3).r != 0 && !isalpha(libeel_plugboard(enigma, 3).r)) || 499 | (libeel_plugboard(enigma, 3).l != 0 && libeel_plugboard(enigma, 3).r == 0) || 500 | (libeel_plugboard(enigma, 3).r != 0 && libeel_plugboard(enigma, 3).l == 0)) { 501 | return 0; 502 | } 503 | 504 | if ((libeel_plugboard(enigma, 4).l != 0 && !isalpha(libeel_plugboard(enigma, 4).l)) || 505 | (libeel_plugboard(enigma, 4).r != 0 && !isalpha(libeel_plugboard(enigma, 4).r)) || 506 | (libeel_plugboard(enigma, 4).l != 0 && libeel_plugboard(enigma, 4).r == 0) || 507 | (libeel_plugboard(enigma, 4).r != 0 && libeel_plugboard(enigma, 4).l == 0)) { 508 | return 0; 509 | } 510 | 511 | if ((libeel_plugboard(enigma, 5).l != 0 && !isalpha(libeel_plugboard(enigma, 5).l)) || 512 | (libeel_plugboard(enigma, 5).r != 0 && !isalpha(libeel_plugboard(enigma, 5).r)) || 513 | (libeel_plugboard(enigma, 5).l != 0 && libeel_plugboard(enigma, 5).r == 0) || 514 | (libeel_plugboard(enigma, 5).r != 0 && libeel_plugboard(enigma, 5).l == 0)) { 515 | return 0; 516 | } 517 | 518 | if ((libeel_plugboard(enigma, 6).l != 0 && !isalpha(libeel_plugboard(enigma, 6).l)) || 519 | (libeel_plugboard(enigma, 6).r != 0 && !isalpha(libeel_plugboard(enigma, 6).r)) || 520 | (libeel_plugboard(enigma, 6).l != 0 && libeel_plugboard(enigma, 6).r == 0) || 521 | (libeel_plugboard(enigma, 6).r != 0 && libeel_plugboard(enigma, 6).l == 0)) { 522 | return 0; 523 | } 524 | 525 | if ((libeel_plugboard(enigma, 1).l > 0 && libeel_plugboard(enigma, 1).l == libeel_plugboard(enigma, 2).l) || 526 | (libeel_plugboard(enigma, 1).l > 0 && libeel_plugboard(enigma, 1).l == libeel_plugboard(enigma, 2).r) || 527 | (libeel_plugboard(enigma, 1).l > 0 && libeel_plugboard(enigma, 1).l == libeel_plugboard(enigma, 3).l) || 528 | (libeel_plugboard(enigma, 1).l > 0 && libeel_plugboard(enigma, 1).l == libeel_plugboard(enigma, 3).r) || 529 | (libeel_plugboard(enigma, 1).l > 0 && libeel_plugboard(enigma, 1).l == libeel_plugboard(enigma, 4).l) || 530 | (libeel_plugboard(enigma, 1).l > 0 && libeel_plugboard(enigma, 1).l == libeel_plugboard(enigma, 4).r) || 531 | (libeel_plugboard(enigma, 1).l > 0 && libeel_plugboard(enigma, 1).l == libeel_plugboard(enigma, 5).l) || 532 | (libeel_plugboard(enigma, 1).l > 0 && libeel_plugboard(enigma, 1).l == libeel_plugboard(enigma, 5).r) || 533 | (libeel_plugboard(enigma, 1).l > 0 && libeel_plugboard(enigma, 1).l == libeel_plugboard(enigma, 6).l) || 534 | (libeel_plugboard(enigma, 1).l > 0 && libeel_plugboard(enigma, 1).l == libeel_plugboard(enigma, 6).r) || 535 | (libeel_plugboard(enigma, 1).l > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 2).l) || 536 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 2).r) || 537 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 3).l) || 538 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 3).r) || 539 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 4).l) || 540 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 4).r) || 541 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 5).l) || 542 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 5).r) || 543 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 6).l) || 544 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 6).r) || 545 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 7).l) || 546 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 7).r) || 547 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 8).l) || 548 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 8).r) || 549 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 9).l) || 550 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 9).r) || 551 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 10).l) || 552 | (libeel_plugboard(enigma, 1).r > 0 && libeel_plugboard(enigma, 1).r == libeel_plugboard(enigma, 10).r) || 553 | (libeel_plugboard(enigma, 2).l > 0 && libeel_plugboard(enigma, 2).l == libeel_plugboard(enigma, 3).l) || 554 | (libeel_plugboard(enigma, 2).l > 0 && libeel_plugboard(enigma, 2).l == libeel_plugboard(enigma, 3).r) || 555 | (libeel_plugboard(enigma, 2).l > 0 && libeel_plugboard(enigma, 2).l == libeel_plugboard(enigma, 4).l) || 556 | (libeel_plugboard(enigma, 2).l > 0 && libeel_plugboard(enigma, 2).l == libeel_plugboard(enigma, 4).r) || 557 | (libeel_plugboard(enigma, 2).l > 0 && libeel_plugboard(enigma, 2).l == libeel_plugboard(enigma, 5).l) || 558 | (libeel_plugboard(enigma, 2).l > 0 && libeel_plugboard(enigma, 2).l == libeel_plugboard(enigma, 5).r) || 559 | (libeel_plugboard(enigma, 2).l > 0 && libeel_plugboard(enigma, 2).l == libeel_plugboard(enigma, 6).l) || 560 | (libeel_plugboard(enigma, 2).l > 0 && libeel_plugboard(enigma, 2).l == libeel_plugboard(enigma, 6).r) || 561 | (libeel_plugboard(enigma, 2).l > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 3).l) || 562 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 3).r) || 563 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 4).l) || 564 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 4).r) || 565 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 5).l) || 566 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 5).r) || 567 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 6).l) || 568 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 6).r) || 569 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 7).l) || 570 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 7).r) || 571 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 8).l) || 572 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 8).r) || 573 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 9).l) || 574 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 9).r) || 575 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 10).l) || 576 | (libeel_plugboard(enigma, 2).r > 0 && libeel_plugboard(enigma, 2).r == libeel_plugboard(enigma, 10).r) || 577 | (libeel_plugboard(enigma, 3).l > 0 && libeel_plugboard(enigma, 3).l == libeel_plugboard(enigma, 4).l) || 578 | (libeel_plugboard(enigma, 3).l > 0 && libeel_plugboard(enigma, 3).l == libeel_plugboard(enigma, 4).r) || 579 | (libeel_plugboard(enigma, 3).l > 0 && libeel_plugboard(enigma, 3).l == libeel_plugboard(enigma, 5).l) || 580 | (libeel_plugboard(enigma, 3).l > 0 && libeel_plugboard(enigma, 3).l == libeel_plugboard(enigma, 5).r) || 581 | (libeel_plugboard(enigma, 3).l > 0 && libeel_plugboard(enigma, 3).l == libeel_plugboard(enigma, 6).l) || 582 | (libeel_plugboard(enigma, 3).l > 0 && libeel_plugboard(enigma, 3).l == libeel_plugboard(enigma, 6).r) || 583 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 4).l) || 584 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 4).r) || 585 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 5).l) || 586 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 5).r) || 587 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 6).l) || 588 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 6).r) || 589 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 7).l) || 590 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 7).r) || 591 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 8).l) || 592 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 8).r) || 593 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 9).l) || 594 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 9).r) || 595 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 10).l) || 596 | (libeel_plugboard(enigma, 3).r > 0 && libeel_plugboard(enigma, 3).r == libeel_plugboard(enigma, 10).r) || 597 | (libeel_plugboard(enigma, 4).l > 0 && libeel_plugboard(enigma, 4).l == libeel_plugboard(enigma, 5).l) || 598 | (libeel_plugboard(enigma, 4).l > 0 && libeel_plugboard(enigma, 4).l == libeel_plugboard(enigma, 5).r) || 599 | (libeel_plugboard(enigma, 4).l > 0 && libeel_plugboard(enigma, 4).l == libeel_plugboard(enigma, 6).l) || 600 | (libeel_plugboard(enigma, 4).l > 0 && libeel_plugboard(enigma, 4).l == libeel_plugboard(enigma, 6).r) || 601 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 5).l) || 602 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 5).r) || 603 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 6).l) || 604 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 6).r) || 605 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 7).l) || 606 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 7).r) || 607 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 8).l) || 608 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 8).r) || 609 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 9).l) || 610 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 9).r) || 611 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 10).l) || 612 | (libeel_plugboard(enigma, 4).r > 0 && libeel_plugboard(enigma, 4).r == libeel_plugboard(enigma, 10).r) || 613 | (libeel_plugboard(enigma, 5).l > 0 && libeel_plugboard(enigma, 5).l == libeel_plugboard(enigma, 6).l) || 614 | (libeel_plugboard(enigma, 5).l > 0 && libeel_plugboard(enigma, 5).l == libeel_plugboard(enigma, 6).r) || 615 | (libeel_plugboard(enigma, 5).r > 0 && libeel_plugboard(enigma, 5).r == libeel_plugboard(enigma, 7).l) || 616 | (libeel_plugboard(enigma, 5).r > 0 && libeel_plugboard(enigma, 5).r == libeel_plugboard(enigma, 7).r) || 617 | (libeel_plugboard(enigma, 5).r > 0 && libeel_plugboard(enigma, 5).r == libeel_plugboard(enigma, 8).l) || 618 | (libeel_plugboard(enigma, 5).r > 0 && libeel_plugboard(enigma, 5).r == libeel_plugboard(enigma, 8).r) || 619 | (libeel_plugboard(enigma, 5).r > 0 && libeel_plugboard(enigma, 5).r == libeel_plugboard(enigma, 9).l) || 620 | (libeel_plugboard(enigma, 5).r > 0 && libeel_plugboard(enigma, 5).r == libeel_plugboard(enigma, 9).r) || 621 | (libeel_plugboard(enigma, 5).r > 0 && libeel_plugboard(enigma, 5).r == libeel_plugboard(enigma, 10).l) || 622 | (libeel_plugboard(enigma, 5).r > 0 && libeel_plugboard(enigma, 5).r == libeel_plugboard(enigma, 10).r) || 623 | (libeel_plugboard(enigma, 6).r > 0 && libeel_plugboard(enigma, 6).r == libeel_plugboard(enigma, 7).l) || 624 | (libeel_plugboard(enigma, 6).r > 0 && libeel_plugboard(enigma, 6).r == libeel_plugboard(enigma, 7).r) || 625 | (libeel_plugboard(enigma, 6).r > 0 && libeel_plugboard(enigma, 6).r == libeel_plugboard(enigma, 8).l) || 626 | (libeel_plugboard(enigma, 6).r > 0 && libeel_plugboard(enigma, 6).r == libeel_plugboard(enigma, 8).r) || 627 | (libeel_plugboard(enigma, 6).r > 0 && libeel_plugboard(enigma, 6).r == libeel_plugboard(enigma, 9).l) || 628 | (libeel_plugboard(enigma, 6).r > 0 && libeel_plugboard(enigma, 6).r == libeel_plugboard(enigma, 9).r) || 629 | (libeel_plugboard(enigma, 6).r > 0 && libeel_plugboard(enigma, 6).r == libeel_plugboard(enigma, 10).l) || 630 | (libeel_plugboard(enigma, 6).r > 0 && libeel_plugboard(enigma, 6).r == libeel_plugboard(enigma, 10).r) || 631 | (libeel_plugboard(enigma, 7).r > 0 && libeel_plugboard(enigma, 7).r == libeel_plugboard(enigma, 8).l) || 632 | (libeel_plugboard(enigma, 7).r > 0 && libeel_plugboard(enigma, 7).r == libeel_plugboard(enigma, 8).r) || 633 | (libeel_plugboard(enigma, 7).r > 0 && libeel_plugboard(enigma, 7).r == libeel_plugboard(enigma, 9).l) || 634 | (libeel_plugboard(enigma, 7).r > 0 && libeel_plugboard(enigma, 7).r == libeel_plugboard(enigma, 9).r) || 635 | (libeel_plugboard(enigma, 7).r > 0 && libeel_plugboard(enigma, 7).r == libeel_plugboard(enigma, 10).l) || 636 | (libeel_plugboard(enigma, 7).r > 0 && libeel_plugboard(enigma, 7).r == libeel_plugboard(enigma, 10).r) || 637 | (libeel_plugboard(enigma, 9).r > 0 && libeel_plugboard(enigma, 9).r == libeel_plugboard(enigma, 10).l) || 638 | (libeel_plugboard(enigma, 9).r > 0 && libeel_plugboard(enigma, 9).r == libeel_plugboard(enigma, 10).r)) { 639 | return 0; 640 | } 641 | 642 | return 1; 643 | } 644 | -------------------------------------------------------------------------------- /src/eel/eel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006, 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef LIBEEL_EEL_H 9 | #define LIBEEL_EEL_H 1 10 | 11 | #include "types.h" 12 | 13 | #define libeel_rotor(e, p) ( (e)->gears_## p ## r ) 14 | 15 | #define libeel_rotor_inv(e, p) ( (e)->gears_## p ## r_1 ) 16 | 17 | #define libeel_notch(e, p) ( (e)->gears_ ## p ## n ) 18 | 19 | #define libeel_display(e, p) ( (e)->gears_## p ## d ) 20 | 21 | #define libeel_keyboard(e) ( (e)->keyboard ) 22 | 23 | #define libeel_reflector(e) ( (e)->gears_## rf ) 24 | 25 | #define libeel_rotor_offset(e, p) ( (e)->gears_ ## p ## _off ) 26 | 27 | #define libeel_rotor_at(e, p) ( (e)->gears_ ## p ## _at ) 28 | 29 | #define libeel_ring(e, p) ( (e)->gears_ ## p ## _ring ) 30 | 31 | #define libeel_plugboard(e, n) ( (e)->plugboard.plug ## n ) 32 | 33 | #define libeel_enigma_input(e) ( (e)->l_in ) 34 | 35 | #define libeel_enigma_output(e) ( (e)->l_out ) 36 | 37 | #ifdef __cplusplus 38 | 39 | extern "C" { 40 | 41 | #endif // #ifdef __cplusplus 42 | 43 | int libeel_init_machine(libeel_enigma_ctx *enigma); 44 | 45 | char libeel_type(libeel_enigma_ctx *enigma); 46 | 47 | void libeel_del_enigma_ctx(libeel_enigma_ctx *enigma); 48 | 49 | libeel_enigma_ctx *libeel_new_enigma_ctx(void); 50 | 51 | #ifdef __cplusplus 52 | 53 | } 54 | 55 | #endif // #ifdef __cplusplus 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/eel/types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2006, 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef LIBEEL_TYPES_H 9 | #define LIBEEL_TYPES_H 1 10 | 11 | #ifdef __cplusplus 12 | 13 | extern "C" { 14 | 15 | #endif // #ifdef __cplusplus 16 | 17 | typedef enum _libeel_rotor_t { 18 | i = 0, ii, iii, iv, v, vi, vii, viii 19 | }libeel_rotor_t; 20 | 21 | typedef enum _libeel_reflector_t { 22 | b = 0, c 23 | }libeel_reflector_t; 24 | 25 | struct libeel_plug_setting_ctx { 26 | char l, r; 27 | }; 28 | 29 | typedef struct _libeel_plugboard_ctx { 30 | struct libeel_plug_setting_ctx plug1, plug2, plug3, plug4, plug5, 31 | plug6, plug7, plug8, plug9, plug10; 32 | }libeel_plugboard_ctx; 33 | 34 | typedef char libeel_rotor_wiring_t[26]; 35 | 36 | typedef char libeel_notch_t; 37 | 38 | typedef char libeel_rotor_display_t; 39 | 40 | typedef int libeel_ring_t; 41 | 42 | typedef struct _libeel_enigma_ctx { 43 | libeel_rotor_t left_rotor, middle_rotor, right_rotor; 44 | libeel_reflector_t reflector; 45 | libeel_rotor_wiring_t keyboard; 46 | libeel_plugboard_ctx plugboard; 47 | libeel_rotor_wiring_t gears_lr, gears_mr, gears_rr; 48 | libeel_rotor_wiring_t gears_lr_1, gears_mr_1, gears_rr_1; 49 | libeel_notch_t gears_mn, gears_rn; 50 | libeel_rotor_display_t gears_ld, gears_md, gears_rd; 51 | libeel_rotor_wiring_t gears_rf; 52 | libeel_rotor_wiring_t gears_l_off, gears_m_off, gears_r_off; 53 | libeel_rotor_display_t gears_l_at, gears_m_at, gears_r_at; 54 | libeel_ring_t gears_l_ring, gears_m_ring, gears_r_ring; 55 | libeel_rotor_display_t l_in, l_out; 56 | }libeel_enigma_ctx; 57 | 58 | #ifdef __cplusplus 59 | 60 | } 61 | 62 | #endif // #ifdef __cplusplus 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/enigmactl/enigmactl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_ENIGMACTL_H 9 | #define DEV_ENIGMA_ENIGMACTL_H 1 10 | 11 | #if defined(__linux__) 12 | 13 | #include 14 | 15 | #elif defined(__FreeBSD__) 16 | 17 | #include 18 | 19 | #endif 20 | 21 | #define ENIGMA_IOC_MAGIC 'E' // WARN(Santiago): I did not pick a valid IOC_MAGIC, for sure that it will clash. 22 | 23 | #define ENIGMA_RESET _IO(ENIGMA_IOC_MAGIC, 0) 24 | #define ENIGMA_SET _IOW(ENIGMA_IOC_MAGIC, 1, libeel_enigma_ctx) 25 | #define ENIGMA_SET_DEFAULT_SETTING _IOW(ENIGMA_IOC_MAGIC, 2, libeel_enigma_ctx) 26 | #define ENIGMA_UNSET_DEFAULT_SETTING _IO(ENIGMA_IOC_MAGIC, 3) 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/enigmactl/user/.ivk: -------------------------------------------------------------------------------- 1 | --forgefiles=Forgefile.hsl --Forgefile-projects=enigmactl --obj-output-dir=o --bin-output-dir=bin 2 | -------------------------------------------------------------------------------- /src/enigmactl/user/Forgefile.hsl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 by Rafael Santiago 3 | # 4 | # This is free software. You can redistribute it and/or modify under 5 | # the terms of the GNU General Public License version 2. 6 | # 7 | # 8 | 9 | include ~/toolsets/gcc/gcc-app.hsl 10 | 11 | var sources type list; 12 | var includes type list; 13 | var cflags type list; 14 | var libraries type list; 15 | var ldflags type list; 16 | 17 | project enigmactl : toolset "gcc-c-app" : $sources, $includes, $cflags, $libraries, $ldflags, "enigmactl"; 18 | 19 | enigmactl.prologue() { 20 | forge_eel(); 21 | 22 | $sources.ls(".*\\.c$"); 23 | $includes.add_item("../../"); 24 | $includes.add_item("../"); 25 | $includes.add_item("../../mod_traps/" + hefesto.sys.os_name()); 26 | $includes.add_item("eel/src"); 27 | 28 | $libraries.add_item("eel/src/lib"); 29 | $ldflags.add_item("-leel"); 30 | } 31 | 32 | enigmactl.epilogue() { 33 | if (hefesto.sys.last_forge_result() == 0) { 34 | hefesto.sys.cd("test"); 35 | hefesto.sys.forge("enigmactl-unit", "Forgefile.hsl", "--obj-output-dir=o --bin-output-dir=bin"); 36 | hefesto.sys.cd(".."); 37 | if (hefesto.sys.last_forge_result() != 0) { 38 | hefesto.project.abort(hefesto.sys.last_forge_result()); 39 | } 40 | } 41 | } 42 | 43 | local function forge_eel() : result type none { 44 | if (hefesto.sys.cd("eel/src")) { 45 | hefesto.sys.forge("libeel", "Forgefile.hsl", "--bin-output-dir=lib --obj-output-dir=o"); 46 | hefesto.sys.cd("../.."); 47 | if (hefesto.sys.last_forge_result() != 0) { 48 | hefesto.project.abort(hefesto.sys.last_forge_result()); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/enigmactl/user/doc/man/enigmactl.1: -------------------------------------------------------------------------------- 1 | .TH enigmactl 1 "October 17, 2016" "version 0.0.1" "USER COMMANDS" 2 | .SH NAME 3 | enigmactl \- the /dev/enigma controller 4 | .SH SYNOPSIS 5 | .B enigmactl [\fIOPTIONS\fR] 6 | .SH DESCRIPTION 7 | \fIenigmactl\fR is used to set up or even unset your \fI/dev/enigma\fR. 8 | 9 | .SH OPTIONS 10 | .TP 11 | \-\-unset 12 | Indicates the unset operation. 13 | 14 | .TP 15 | \-\-set 16 | Indicates the set operation. 17 | 18 | .TP 19 | \-\-l-rotor=\fI\fR 20 | Specifies the left rotor. 21 | 22 | .TP 23 | \-\-m-rotor=\fI\fR 24 | Specifies the middle rotor. 25 | 26 | .TP 27 | \-\-r-rotor=\fI\fR 28 | Specifies the right rotor. 29 | 30 | .TP 31 | \-\-l-rotor-at=\fI\fR 32 | Specifies the left rotor position. 33 | 34 | .TP 35 | \-\-m-rotor-at=\fI\fR 36 | Specifies the middle rotor position. 37 | 38 | .TP 39 | \-\-r-rotor-at=\fI\fR 40 | Specifies the right rotor position. 41 | 42 | .TP 43 | \-\-l-ring=\fI<1-26>\fR 44 | Specifies the left ring position. 45 | 46 | .TP 47 | \-\-m-ring=\fI<1-26>\fR 48 | Specifies the middle ring position. 49 | 50 | .TP 51 | \-\-r-ring=\fI<1-26>\fR 52 | Specifies the right ring position. 53 | 54 | .TP 55 | \-\-reflector=\fI\fR 56 | Specifies the reflector. 57 | 58 | .TP 59 | \-\-plugboard=\fI\fR 60 | Specifies the plugboard swaps. 61 | 62 | .TP 63 | \-\-help 64 | Shows the general help. 65 | 66 | .TP 67 | \-\-version 68 | Show the software version. 69 | 70 | .PP 71 | .SH EXIT STATUS 72 | If the execution succeeds enigmactl returns zero, otherwise non zero value will be returned. 73 | 74 | .PP 75 | .SH 76 | SEE ALSO 77 | .TP 78 | \fI/usr/local/share/dev-enigma/doc\fR (or equivalent in your system) 79 | .PP 80 | .SH 81 | HOMEPAGE 82 | .TP 83 | https://github.com/rafael-santiago/dev-enigma 84 | .SH AUTHOR 85 | Rafael Santiago 86 | -------------------------------------------------------------------------------- /src/enigmactl/user/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "option.h" 9 | #include "setloader.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define ENIGMACTL_VERSION "0.0.1" 19 | 20 | static int enigmactl_help(void); 21 | 22 | static int enigmactl_set(void); 23 | 24 | static int enigmactl_version(void); 25 | 26 | static int enigmactl_unset(void); 27 | 28 | static int enigmactl_help(void) { 29 | if (get_bool_option("set", 0)) { 30 | printf("usage: enigmactl --set --l-rotor= --m-rotor= --r-rotor= --l-rotor-at= --m-rotor-at= --r-rotor-at= [--l-ring= --m-ring= --r-ring= --plugboard=SWP1/SWP1',...,SWP6/SWP6']\n"); 31 | } else if (get_bool_option("unset", 0)) { 32 | printf("usage: enigmactl --unset\n"); 33 | } else { 34 | printf("usage: enigmactl -- args...\n\n" 35 | "By the way, the operations are: 'set', 'unset' and 'help'.\n\n" 36 | "enigmactl is Copyright (C) 2016 by Rafael Santiago.\n" 37 | "Bug reports, feedback, etc: or \n"); 38 | } 39 | return 0; 40 | } 41 | 42 | static int enigmactl_set(void) { 43 | libeel_enigma_ctx *enigma_setting; 44 | int result = 1; 45 | int dev = open("/dev/" DEVNAME, O_RDWR); 46 | 47 | if (dev < 0) { 48 | printf("ERROR: unable to open '%s'.\n", "/dev/" DEVNAME); 49 | return 1; 50 | } 51 | 52 | enigma_setting = ld_enigma_setting(); 53 | 54 | if (enigma_setting != NULL) { 55 | result = ioctl(dev, ENIGMA_SET_DEFAULT_SETTING, enigma_setting); 56 | 57 | if (result != 0) { 58 | perror("ioctl"); 59 | } 60 | } 61 | 62 | close(dev); 63 | 64 | return result; 65 | } 66 | 67 | static int enigmactl_version(void) { 68 | printf("enigmactl-v" ENIGMACTL_VERSION "\n"); 69 | return 0; 70 | } 71 | 72 | static int enigmactl_unset(void) { 73 | int result = 1; 74 | int dev = open("/dev/" DEVNAME, O_RDWR); 75 | 76 | if (dev < 0) { 77 | printf("ERROR: unable to open '%s'.\n", "/dev/" DEVNAME); 78 | return 1; 79 | } 80 | 81 | result = ioctl(dev, ENIGMA_UNSET_DEFAULT_SETTING); 82 | 83 | if (result != 0) { 84 | perror("ioctl"); 85 | } 86 | 87 | close(dev); 88 | 89 | return result; 90 | } 91 | 92 | int main(int argc, char **argv) { 93 | set_argc_argv(argc, argv); 94 | 95 | if (get_bool_option("version", 0)) { 96 | return enigmactl_version(); 97 | } 98 | 99 | if (get_bool_option("help", 0)) { 100 | return enigmactl_help(); 101 | } 102 | 103 | if (get_bool_option("set", 0)) { 104 | return enigmactl_set(); 105 | } 106 | 107 | if (get_bool_option("unset", 0)) { 108 | return enigmactl_unset(); 109 | } 110 | 111 | return enigmactl_help(); 112 | } 113 | -------------------------------------------------------------------------------- /src/enigmactl/user/option.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "option.h" 9 | #include 10 | #include 11 | 12 | static int g_argc = 0; 13 | static char **g_argv = NULL; 14 | 15 | static void *getoptdata(const char *option, const char bool_option, void *default_value); 16 | 17 | static void *getoptdata(const char *option, const char bool_option, void *default_value) { 18 | int o; 19 | char temp[255] = ""; 20 | static int tru = 1; 21 | 22 | if (option == NULL || g_argc == 0 || g_argv == NULL) { 23 | return default_value; 24 | } 25 | 26 | sprintf(temp, "--%s%s", option, (!bool_option) ? "=" : "\0"); 27 | 28 | for (o = 0; o < g_argc; o++) { 29 | if (strstr(g_argv[o], temp) == &g_argv[o][0]) { 30 | return ((bool_option) ? (void *)&tru : (void *)&g_argv[o][0] + strlen(temp)); 31 | } 32 | } 33 | 34 | return default_value; 35 | } 36 | 37 | 38 | char *get_option(const char *option, char *default_value) { 39 | return getoptdata(option, 0, default_value); 40 | } 41 | 42 | int get_bool_option(const char *option, int default_value) { 43 | return *((int *)getoptdata(option, 1, &default_value)); 44 | } 45 | 46 | void set_argc_argv(int argc, char **argv) { 47 | g_argc = argc; 48 | g_argv = argv; 49 | } 50 | -------------------------------------------------------------------------------- /src/enigmactl/user/option.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef ENIGMACTL_OPTION_H 9 | #define ENIGMACTL_OPTION_H 1 10 | 11 | char *get_option(const char *option, char *default_value); 12 | 13 | int get_bool_option(const char *option, int default_value); 14 | 15 | void set_argc_argv(int argc, char **argv); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/enigmactl/user/setloader.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "setloader.h" 9 | #include "option.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | // WARN(Santiago): This code module is a terrible boredom, you should not spend your time reading this piece of shit. 16 | 17 | typedef int (*setting_verifier)(const char *data); 18 | 19 | static int get_rotor_value(const char *data); 20 | 21 | static int is_valid_rotor(const char *data); 22 | 23 | static int is_valid_ring(const char *data); 24 | 25 | static int is_valid_number(const char *data); 26 | 27 | static int is_valid_plugboard(const char *data); 28 | 29 | static int is_valid_rotor_pos(const char *data); 30 | 31 | static int get_reflector_value(const char *data); 32 | 33 | static int is_valid_reflector(const char *data); 34 | 35 | 36 | typedef int (*plugboard_verifier)(int c); 37 | 38 | static int isnext(int c); 39 | 40 | static int isbar(int c); 41 | 42 | 43 | typedef void (*setting_loader)(libeel_enigma_ctx *enigma, const char *data); 44 | 45 | static void ld_l_rotor(libeel_enigma_ctx *enigma, const char *data); 46 | 47 | static void ld_m_rotor(libeel_enigma_ctx *enigma, const char *data); 48 | 49 | static void ld_r_rotor(libeel_enigma_ctx *enigma, const char *data); 50 | 51 | static void ld_l_rotor_pos(libeel_enigma_ctx *enigma, const char *data); 52 | 53 | static void ld_m_rotor_pos(libeel_enigma_ctx *enigma, const char *data); 54 | 55 | static void ld_r_rotor_pos(libeel_enigma_ctx *enigma, const char *data); 56 | 57 | static void ld_l_ring(libeel_enigma_ctx *enigma, const char *data); 58 | 59 | static void ld_m_ring(libeel_enigma_ctx *enigma, const char *data); 60 | 61 | static void ld_r_ring(libeel_enigma_ctx *enigma, const char *data); 62 | 63 | static void ld_plugboard(libeel_enigma_ctx *enigma, const char *data); 64 | 65 | static void ld_reflector(libeel_enigma_ctx *enigma, const char *data); 66 | 67 | static int isnext(int c) { 68 | return (c == ',' || c == 0); 69 | } 70 | 71 | static int isbar(int c) { 72 | return (c == '/'); 73 | } 74 | 75 | static int get_reflector_value(const char *data) { 76 | if (!(data != NULL && strlen(data) == 1 && tolower(*data) == 'c' || tolower(*data) == 'b')) { 77 | return -1; 78 | } 79 | return (tolower(*data) - 'b'); 80 | } 81 | 82 | static int is_valid_reflector(const char *data) { 83 | return (get_reflector_value(data) != -1); 84 | } 85 | 86 | static int is_valid_number(const char *data) { 87 | const char *dp = NULL, *dp_end = NULL; 88 | 89 | if (data == NULL) { 90 | return 0; 91 | } 92 | 93 | dp = data; 94 | dp_end = dp + strlen(data); 95 | 96 | while (dp != dp_end) { 97 | if (!isdigit(*dp)) { 98 | return 0; 99 | } 100 | dp++; 101 | } 102 | 103 | return 1; 104 | } 105 | 106 | static int is_valid_ring(const char *data) { 107 | int value; 108 | return (is_valid_number(data) && (value = atoi(data)) >= 1 && value <= 26); 109 | } 110 | 111 | static int is_valid_rotor_pos(const char *data) { 112 | return (data != NULL && isalpha(*data)); 113 | } 114 | 115 | static int is_valid_plugboard(const char *data) { 116 | const char *dp = NULL, *dp_end = NULL; 117 | int state = 0; 118 | plugboard_verifier vprogram[] = { 119 | isalpha, 120 | isbar, 121 | isalpha, 122 | isnext 123 | }; 124 | const size_t vprogram_state_nr = sizeof(vprogram) / sizeof(vprogram[0]); 125 | size_t swaps_nr = 0; 126 | 127 | dp = data; 128 | dp_end = dp + strlen(dp); 129 | 130 | while (dp != dp_end && swaps_nr < 11) { 131 | if (!vprogram[state](*dp)) { 132 | printf("ERROR: Invalid plugboard setting.\n"); 133 | return 0; 134 | } 135 | state = (state + 1) % vprogram_state_nr; 136 | if (state == 3) { 137 | swaps_nr++; 138 | } 139 | dp++; 140 | } 141 | 142 | if (swaps_nr > 10) { 143 | printf("ERROR: Not enough space to make the requested swaps in the plugboard.\n"); 144 | return 0; 145 | } 146 | 147 | if (*dp != 0 || state != 3) { 148 | printf("ERROR: Unterminated plugboard setting.\n"); 149 | return 0; 150 | } 151 | 152 | return 1; 153 | } 154 | 155 | static int is_valid_rotor(const char *data) { 156 | return (get_rotor_value(data) != -1); 157 | } 158 | 159 | static int get_rotor_value(const char *data) { 160 | static char *rotors[] = { 161 | "i", 162 | "ii", 163 | "iii", 164 | "iv", 165 | "v", 166 | "vi", 167 | "vii", 168 | "viii" 169 | }; 170 | const size_t rotors_nr = sizeof(rotors) / sizeof(rotors[0]); 171 | size_t r; 172 | char temp[255]; 173 | char *tp = NULL, *tp_end = NULL; 174 | const char *dp = NULL, *dp_end = NULL; 175 | 176 | if (data == NULL) { 177 | return -1; 178 | } 179 | 180 | dp = data; 181 | dp_end = dp + strlen(dp); 182 | tp = &temp[0]; 183 | tp_end = tp + sizeof(temp); 184 | memset(temp, 0, sizeof(temp)); 185 | 186 | while (dp != dp_end) { 187 | *tp = tolower(*dp); 188 | dp++; 189 | tp++; 190 | } 191 | 192 | for (r = 0; r < rotors_nr; r++) { 193 | if (strcmp(data, rotors[r]) == 0) { 194 | return r; 195 | } 196 | } 197 | 198 | return -1; 199 | } 200 | 201 | // INFO(Santiago): Well, let's avoid being so pedantic here, if everything is fine after verifying 202 | // we do not need to re-check all that boring stuff again. 203 | // 204 | // (It would be pretty stupid...) 205 | 206 | static void ld_l_rotor(libeel_enigma_ctx *enigma, const char *data) { 207 | enigma->left_rotor = get_rotor_value(data); 208 | } 209 | 210 | static void ld_m_rotor(libeel_enigma_ctx *enigma, const char *data) { 211 | enigma->middle_rotor = get_rotor_value(data); 212 | } 213 | 214 | static void ld_r_rotor(libeel_enigma_ctx *enigma, const char *data) { 215 | enigma->right_rotor = get_rotor_value(data); 216 | } 217 | 218 | static void ld_l_rotor_pos(libeel_enigma_ctx *enigma, const char *data) { 219 | libeel_rotor_at(enigma, l) = *data; 220 | } 221 | 222 | static void ld_m_rotor_pos(libeel_enigma_ctx *enigma, const char *data) { 223 | libeel_rotor_at(enigma, m) = *data; 224 | } 225 | 226 | static void ld_r_rotor_pos(libeel_enigma_ctx *enigma, const char *data) { 227 | libeel_rotor_at(enigma, r) = *data; 228 | } 229 | 230 | static void ld_l_ring(libeel_enigma_ctx *enigma, const char *data) { 231 | libeel_ring(enigma, l) = atoi(data); 232 | } 233 | 234 | static void ld_m_ring(libeel_enigma_ctx *enigma, const char *data) { 235 | libeel_ring(enigma, m) = atoi(data); 236 | } 237 | 238 | static void ld_r_ring(libeel_enigma_ctx *enigma, const char *data) { 239 | libeel_ring(enigma, r) = atoi(data); 240 | } 241 | 242 | static void ld_plugboard(libeel_enigma_ctx *enigma, const char *data) { 243 | const char *dp = data; 244 | const char *dp_end = dp + strlen(dp); 245 | int swap = 0; 246 | 247 | while (dp < dp_end) { 248 | switch (swap) { 249 | case 0: 250 | libeel_plugboard(enigma, 1).l = *dp; 251 | libeel_plugboard(enigma, 1).r = *(dp + 2); 252 | break; 253 | 254 | case 1: 255 | libeel_plugboard(enigma, 2).l = *dp; 256 | libeel_plugboard(enigma, 2).r = *(dp + 2); 257 | break; 258 | 259 | case 2: 260 | libeel_plugboard(enigma, 3).l = *dp; 261 | libeel_plugboard(enigma, 3).r = *(dp + 2); 262 | break; 263 | 264 | case 3: 265 | libeel_plugboard(enigma, 4).l = *dp; 266 | libeel_plugboard(enigma, 4).r = *(dp + 2); 267 | break; 268 | 269 | case 4: 270 | libeel_plugboard(enigma, 5).l = *dp; 271 | libeel_plugboard(enigma, 5).r = *(dp + 2); 272 | break; 273 | 274 | case 5: 275 | libeel_plugboard(enigma, 6).l = *dp; 276 | libeel_plugboard(enigma, 6).r = *(dp + 2); 277 | break; 278 | 279 | case 6: 280 | libeel_plugboard(enigma, 7).l = *dp; 281 | libeel_plugboard(enigma, 7).r = *(dp + 2); 282 | break; 283 | 284 | case 7: 285 | libeel_plugboard(enigma, 8).l = *dp; 286 | libeel_plugboard(enigma, 8).r = *(dp + 2); 287 | break; 288 | 289 | case 8: 290 | libeel_plugboard(enigma, 9).l = *dp; 291 | libeel_plugboard(enigma, 9).r = *(dp + 2); 292 | break; 293 | 294 | case 9: 295 | libeel_plugboard(enigma, 10).l = *dp; 296 | libeel_plugboard(enigma, 10).r = *(dp + 2); 297 | break; 298 | } 299 | 300 | dp += 4; 301 | swap++; 302 | } 303 | } 304 | 305 | static void ld_reflector(libeel_enigma_ctx *enigma, const char *data) { 306 | enigma->reflector = get_reflector_value(data); 307 | } 308 | 309 | // WARN(Santiago): Go to sleep! :) 310 | 311 | libeel_enigma_ctx *ld_enigma_setting(void) { 312 | struct enigma_loader_program { 313 | const char *option; 314 | const int mandatory; 315 | setting_verifier verify; 316 | setting_loader load; 317 | }; 318 | struct enigma_loader_program ld_program[] = { 319 | { "l-rotor", 1, is_valid_rotor, ld_l_rotor }, 320 | { "m-rotor", 1, is_valid_rotor, ld_m_rotor }, 321 | { "r-rotor", 1, is_valid_rotor, ld_r_rotor }, 322 | { "l-rotor-at", 1, is_valid_rotor_pos, ld_l_rotor_pos }, 323 | { "m-rotor-at", 1, is_valid_rotor_pos, ld_m_rotor_pos }, 324 | { "r-rotor-at", 1, is_valid_rotor_pos, ld_r_rotor_pos }, 325 | { "l-ring", 0, is_valid_ring, ld_l_ring }, 326 | { "m-ring", 0, is_valid_ring, ld_m_ring }, 327 | { "r-ring", 0, is_valid_ring, ld_r_ring }, 328 | { "reflector", 1, is_valid_reflector, ld_reflector }, 329 | { "plugboard", 0, is_valid_plugboard, ld_plugboard } 330 | }; 331 | const size_t ld_program_size = sizeof(ld_program) / sizeof(ld_program[0]); 332 | char *data = NULL; 333 | ssize_t program_counter = -1; 334 | libeel_enigma_ctx *enigma = libeel_new_enigma_ctx(); 335 | 336 | while (++program_counter < ld_program_size) { 337 | data = get_option(ld_program[program_counter].option, NULL); 338 | 339 | if (data == NULL && !ld_program[program_counter].mandatory) { 340 | continue; 341 | } if (data == NULL) { 342 | printf("ERROR: The mandatory option '%s' is lacking.\n", ld_program[program_counter].option); 343 | goto ___ld_error_epilogue; // WARN(Santiago): Hold on your friend's hand and try not pee in your pants. 344 | } 345 | 346 | if (!ld_program[program_counter].verify(data)) { 347 | printf("ERROR: The option '%s' has invalid data.\n", ld_program[program_counter].option); 348 | goto ___ld_error_epilogue; // WARN(Santiago): Hold on your friend's hand and try not pee in your pants. 349 | } 350 | 351 | ld_program[program_counter].load(enigma, data); 352 | } 353 | 354 | return enigma; 355 | 356 | ___ld_error_epilogue: 357 | libeel_del_enigma_ctx(enigma); 358 | 359 | return NULL; 360 | } 361 | -------------------------------------------------------------------------------- /src/enigmactl/user/setloader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef ENIGMACTL_SETLOADER_H 9 | #define ENIGMACTL_SETLOADER_H 1 10 | 11 | #include 12 | 13 | libeel_enigma_ctx *ld_enigma_setting(void); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/enigmactl/user/test/.ivk: -------------------------------------------------------------------------------- 1 | --forgefiles=Forgefile.hsl --Forgefile-projects=enigmactl-unit --obj-output-dir=o --bin-output-dir=bin 2 | -------------------------------------------------------------------------------- /src/enigmactl/user/test/Forgefile.hsl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 by Rafael Santiago 3 | # 4 | # This is free software. You can redistribute it and/or modify under 5 | # the terms of the GNU General Public License version 2. 6 | # 7 | # 8 | 9 | include ~/toolsets/gcc/gcc-app.hsl 10 | 11 | var sources type list; 12 | var includes type list; 13 | var cflags type list; 14 | var libraries type list; 15 | var ldflags type list; 16 | 17 | project enigmactl-unit : toolset "gcc-c-app" : $sources, $includes, $cflags, $libraries, $ldflags, "enigmactl-unit"; 18 | 19 | enigmactl-unit.prologue() { 20 | $sources.ls(".*\\.c$"); 21 | 22 | $includes.add_item("../eel/src/test/cutest/src"); 23 | $includes.add_item("../eel/src"); 24 | 25 | $ldflags = get_enigmactl_objects(); 26 | 27 | $libraries.add_item("../eel/src/test/cutest/src/lib"); 28 | $ldflags.add_item("-lcutest"); 29 | if (hefesto.sys.os_name() == "linux") { 30 | $ldflags.add_item("-ldl"); 31 | $ldflags.add_item("-lpthread"); 32 | } else if (hefesto.sys.os_name() == "freebsd") { 33 | $ldflags.add_item("-lexecinfo"); 34 | $ldflags.add_item("-lpthread"); 35 | } 36 | 37 | $libraries.add_item("../eel/src/lib"); 38 | $ldflags.add_item("-leel"); 39 | } 40 | 41 | enigmactl-unit.epilogue() { 42 | if (hefesto.sys.last_forge_result() == 0) { 43 | var exit_code type int; 44 | 45 | $exit_code = runtests(); 46 | 47 | if ($exit_code != 0) { 48 | hefesto.project.abort($exit_code); 49 | } 50 | } 51 | } 52 | 53 | local function runtests() : result type int { 54 | result hefesto.sys.run(hefesto.sys.make_path("bin", "enigmactl-unit")); 55 | } 56 | 57 | local function get_enigmactl_objects() : result type list { 58 | var objects type list; 59 | var cwd type string; 60 | 61 | $cwd = hefesto.sys.pwd(); 62 | 63 | if (hefesto.sys.cd("../o")) { 64 | $objects.ls(".*\\.o$"); 65 | 66 | var o type int; 67 | $o = 0; 68 | 69 | while ($o < $objects.count()) { 70 | var object type string; 71 | $object = $objects.item($o); 72 | if ($object.match(".*main\\.o$")) { 73 | $objects.del_index($o); 74 | break; 75 | } 76 | 77 | $o = $o + 1; 78 | } 79 | } 80 | 81 | result $objects; 82 | } 83 | -------------------------------------------------------------------------------- /src/enigmactl/user/test/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | 9 | #include "../option.h" 10 | #include "../setloader.h" 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | static int load_module(void); 17 | 18 | static int unload_module(void); 19 | 20 | 21 | static int load_module(void) { 22 | int exit_code = 1; 23 | 24 | #if defined(__linux__) 25 | exit_code = system("insmod ../../../enigma.ko"); 26 | #elif defined(__FreeBSD__) 27 | exit_code = system("kldload ../../../enigma.ko"); 28 | #endif 29 | 30 | return exit_code; 31 | } 32 | 33 | static int unload_module(void) { 34 | int exit_code = 1; 35 | 36 | #if defined(__linux__) 37 | exit_code = system("rmmod enigma"); 38 | #elif defined(__FreeBSD__) 39 | exit_code = system("kldunload enigma.ko"); 40 | #endif 41 | 42 | return exit_code; 43 | } 44 | 45 | 46 | CUTE_TEST_CASE(enigmactl_option_tests) 47 | char *argv[] = { 48 | "--foo=bar", 49 | "--dummy-flag" 50 | }; 51 | int argc = sizeof(argv) / sizeof(argv[0]); 52 | char *buf = NULL; 53 | 54 | CUTE_ASSERT(get_option("boo", NULL) == NULL); 55 | 56 | CUTE_ASSERT(get_bool_option("boo", 1) == 1); 57 | 58 | set_argc_argv(argc, argv); 59 | 60 | buf = get_option("foo", NULL); 61 | 62 | CUTE_ASSERT(buf != NULL); 63 | 64 | CUTE_ASSERT(strcmp(buf, "bar") == 0); 65 | 66 | CUTE_ASSERT(get_bool_option("dummy-flag", 0) == 1); 67 | CUTE_TEST_CASE_END 68 | 69 | CUTE_TEST_CASE(enigmactl_setloader_tests) 70 | 71 | // INFO(Santiago): Bad constructions. 72 | 73 | char *argv_0[] = { 74 | "--r-rotor=ii", 75 | "--m-rotor=iii", 76 | "--l-rotor-at=a", 77 | "--r-rotor-at=a", 78 | "--m-rotor-at=z", 79 | "--reflector=c" 80 | }; 81 | 82 | char *argv_1[] = { 83 | "--l-rotor=i", 84 | "--m-rotor=iii", 85 | "--l-rotor-at=a", 86 | "--r-rotor-at=a", 87 | "--m-rotor-at=z", 88 | "--reflector=c" 89 | }; 90 | 91 | char *argv_2[] = { 92 | "--l-rotor=i", 93 | "--r-rotor=ii", 94 | "--l-rotor-at=a", 95 | "--r-rotor-at=a", 96 | "--m-rotor-at=z", 97 | "--reflector=c" 98 | }; 99 | 100 | char *argv_3[] = { 101 | "--l-rotor=i", 102 | "--r-rotor=ii", 103 | "--m-rotor=iii", 104 | "--r-rotor-at=a", 105 | "--m-rotor-at=z", 106 | "--reflector=c" 107 | }; 108 | 109 | char *argv_4[] = { 110 | "--l-rotor=i", 111 | "--r-rotor=ii", 112 | "--m-rotor=iii", 113 | "--l-rotor-at=a", 114 | "--m-rotor-at=z", 115 | "--reflector=c" 116 | }; 117 | 118 | char *argv_5[] = { 119 | "--l-rotor=i", 120 | "--r-rotor=ii", 121 | "--m-rotor=iii", 122 | "--l-rotor-at=a", 123 | "--r-rotor-at=a", 124 | "--reflector=c" 125 | }; 126 | 127 | char *argv_6[] = { 128 | "--l-rotor=i", 129 | "--r-rotor=ii", 130 | "--m-rotor=iii", 131 | "--l-rotor-at=a", 132 | "--r-rotor-at=a", 133 | "--m-rotor-at=z" 134 | }; 135 | 136 | char *argv_7[] = { 137 | "--l-rotor=0", 138 | "--r-rotor=ii", 139 | "--m-rotor=iii", 140 | "--l-rotor-at=a", 141 | "--r-rotor-at=a", 142 | "--m-rotor-at=z", 143 | "--reflector=c" 144 | }; 145 | 146 | char *argv_8[] = { 147 | "--l-rotor=i", 148 | "--r-rotor=b", 149 | "--m-rotor=iii", 150 | "--l-rotor-at=a", 151 | "--r-rotor-at=a", 152 | "--m-rotor-at=z", 153 | "--reflector=c" 154 | }; 155 | 156 | char *argv_9[] = { 157 | "--l-rotor=i", 158 | "--r-rotor=ii", 159 | "--m-rotor=3", 160 | "--l-rotor-at=a", 161 | "--r-rotor-at=a", 162 | "--m-rotor-at=z", 163 | "--reflector=c" 164 | }; 165 | 166 | char *argv_10[] = { 167 | "--l-rotor=i", 168 | "--r-rotor=ii", 169 | "--m-rotor=iii", 170 | "--l-rotor-at=#", 171 | "--r-rotor-at=a", 172 | "--m-rotor-at=z", 173 | "--reflector=c" 174 | }; 175 | 176 | char *argv_11[] = { 177 | "--l-rotor=i", 178 | "--r-rotor=ii", 179 | "--m-rotor=iii", 180 | "--l-rotor-at=a", 181 | "--r-rotor-at=?", 182 | "--m-rotor-at=z", 183 | "--reflector=c" 184 | }; 185 | 186 | char *argv_12[] = { 187 | "--l-rotor=i", 188 | "--r-rotor=ii", 189 | "--m-rotor=iii", 190 | "--l-rotor-at=a", 191 | "--r-rotor-at=a", 192 | "--m-rotor-at=8", 193 | "--reflector=c" 194 | }; 195 | 196 | char *argv_13[] = { 197 | "--l-rotor=i", 198 | "--r-rotor=ii", 199 | "--m-rotor=iii", 200 | "--l-rotor-at=a", 201 | "--r-rotor-at=a", 202 | "--m-rotor-at=z", 203 | "--reflector=x" 204 | }; 205 | 206 | char *argv_14[] = { 207 | "--l-rotor=i", 208 | "--r-rotor=ii", 209 | "--m-rotor=iii", 210 | "--l-rotor-at=a", 211 | "--r-rotor-at=a", 212 | "--m-rotor-at=z", 213 | "--reflector=c", 214 | "--l-ring=1a" 215 | }; 216 | 217 | char *argv_15[] = { 218 | "--l-rotor=i", 219 | "--r-rotor=ii", 220 | "--m-rotor=iii", 221 | "--l-rotor-at=a", 222 | "--r-rotor-at=a", 223 | "--m-rotor-at=z", 224 | "--reflector=c", 225 | "--l-ring=1", 226 | "--r-ring=b" 227 | }; 228 | 229 | char *argv_16[] = { 230 | "--l-rotor=i", 231 | "--r-rotor=ii", 232 | "--m-rotor=iii", 233 | "--l-rotor-at=a", 234 | "--r-rotor-at=a", 235 | "--m-rotor-at=z", 236 | "--reflector=c", 237 | "--l-ring=1", 238 | "--r-ring=2", 239 | "--m-ring=three" 240 | }; 241 | 242 | char *argv_17[] = { 243 | "--l-rotor=i", 244 | "--r-rotor=ii", 245 | "--m-rotor=iii", 246 | "--l-rotor-at=a", 247 | "--r-rotor-at=a", 248 | "--m-rotor-at=z", 249 | "--reflector=c", 250 | "--l-ring=1", 251 | "--r-ring=2", 252 | "--m-ring=3", 253 | "--plugboard=q/w,e/r,t/y,u" 254 | }; 255 | 256 | char *argv_18[] = { 257 | "--l-rotor=i", 258 | "--r-rotor=ii", 259 | "--m-rotor=iii", 260 | "--l-rotor-at=a", 261 | "--r-rotor-at=a", 262 | "--m-rotor-at=z", 263 | "--reflector=c", 264 | "--l-ring=1", 265 | "--r-ring=2", 266 | "--m-ring=3", 267 | "--plugboard=q/w,e/r,t/y,u/i," 268 | }; 269 | 270 | char *argv_19[] = { 271 | "--l-rotor=i", 272 | "--r-rotor=ii", 273 | "--m-rotor=iii", 274 | "--l-rotor-at=a", 275 | "--r-rotor-at=a", 276 | "--m-rotor-at=z", 277 | "--reflector=c", 278 | "--l-ring=1", 279 | "--r-ring=2", 280 | "--m-ring=3", 281 | "--plugboard=q/w,e/r,t/y,u/i,o/" 282 | }; 283 | 284 | char *argv_20[] = { 285 | "--l-rotor=i", 286 | "--r-rotor=ii", 287 | "--m-rotor=iii", 288 | "--l-rotor-at=a", 289 | "--r-rotor-at=a", 290 | "--m-rotor-at=z", 291 | "--reflector=c", 292 | "--l-ring=1", 293 | "--r-ring=2", 294 | "--m-ring=3", 295 | "--plugboard=q/w,e/r,t/y,u/i,o/p,s/d,f/g,h/j,k/l,z/x,c" 296 | }; 297 | 298 | char *argv_21[] = { 299 | "--l-rotor=i", 300 | "--r-rotor=ii", 301 | "--m-rotor=iii", 302 | "--l-rotor-at=a", 303 | "--r-rotor-at=a", 304 | "--m-rotor-at=z", 305 | "--reflector=c", 306 | "--l-ring=1", 307 | "--r-ring=2", 308 | "--m-ring=3", 309 | "--plugboard=q/w,e/r,t/y,u/i,o/p,s/d,f/g,h/j,k/l,z/x,c/" 310 | }; 311 | 312 | char *argv_22[] = { 313 | "--l-rotor=i", 314 | "--r-rotor=ii", 315 | "--m-rotor=iii", 316 | "--l-rotor-at=a", 317 | "--r-rotor-at=a", 318 | "--m-rotor-at=z", 319 | "--reflector=c", 320 | "--l-ring=1", 321 | "--r-ring=2", 322 | "--m-ring=3", 323 | "--plugboard=q/w,e/r,t/y,u/i,o/p,s/d,f/g,h/j,k/l,z/x,c/m" 324 | }; 325 | 326 | // INFO(Santiago): From now on, all ok. 327 | 328 | char *argv_23[] = { 329 | "--l-rotor=i", 330 | "--r-rotor=ii", 331 | "--m-rotor=iii", 332 | "--l-rotor-at=a", 333 | "--r-rotor-at=a", 334 | "--m-rotor-at=z", 335 | "--reflector=c" 336 | }; 337 | 338 | char *argv_24[] = { 339 | "--l-rotor=i", 340 | "--r-rotor=ii", 341 | "--m-rotor=iii", 342 | "--l-rotor-at=a", 343 | "--r-rotor-at=a", 344 | "--m-rotor-at=z", 345 | "--reflector=c", 346 | "--l-ring=1" 347 | }; 348 | 349 | char *argv_25[] = { 350 | "--l-rotor=i", 351 | "--r-rotor=ii", 352 | "--m-rotor=iii", 353 | "--l-rotor-at=a", 354 | "--r-rotor-at=a", 355 | "--m-rotor-at=z", 356 | "--reflector=c", 357 | "--l-ring=1", 358 | "--r-ring=2" 359 | }; 360 | 361 | char *argv_26[] = { 362 | "--l-rotor=i", 363 | "--r-rotor=ii", 364 | "--m-rotor=iii", 365 | "--l-rotor-at=a", 366 | "--r-rotor-at=a", 367 | "--m-rotor-at=z", 368 | "--reflector=c", 369 | "--l-ring=1", 370 | "--r-ring=2", 371 | "--m-ring=3" 372 | }; 373 | 374 | char *argv_27[] = { 375 | "--l-rotor=i", 376 | "--r-rotor=ii", 377 | "--m-rotor=iii", 378 | "--l-rotor-at=a", 379 | "--r-rotor-at=a", 380 | "--m-rotor-at=z", 381 | "--reflector=c", 382 | "--l-ring=1", 383 | "--r-ring=2", 384 | "--m-ring=3", 385 | "--plugboard=q/w" 386 | }; 387 | 388 | char *argv_28[] = { 389 | "--l-rotor=i", 390 | "--r-rotor=ii", 391 | "--m-rotor=iii", 392 | "--l-rotor-at=a", 393 | "--r-rotor-at=a", 394 | "--m-rotor-at=z", 395 | "--reflector=c", 396 | "--l-ring=1", 397 | "--r-ring=2", 398 | "--m-ring=3", 399 | "--plugboard=q/w,e/r" 400 | }; 401 | 402 | char *argv_29[] = { 403 | "--l-rotor=i", 404 | "--r-rotor=ii", 405 | "--m-rotor=iii", 406 | "--l-rotor-at=a", 407 | "--r-rotor-at=a", 408 | "--m-rotor-at=z", 409 | "--reflector=c", 410 | "--l-ring=1", 411 | "--r-ring=2", 412 | "--m-ring=3", 413 | "--plugboard=q/w,e/r,t/y" 414 | }; 415 | 416 | char *argv_30[] = { 417 | "--l-rotor=i", 418 | "--r-rotor=ii", 419 | "--m-rotor=iii", 420 | "--l-rotor-at=a", 421 | "--r-rotor-at=a", 422 | "--m-rotor-at=z", 423 | "--reflector=c", 424 | "--l-ring=1", 425 | "--r-ring=2", 426 | "--m-ring=3", 427 | "--plugboard=q/w,e/r,t/y,u/i" 428 | }; 429 | 430 | char *argv_31[] = { 431 | "--l-rotor=i", 432 | "--r-rotor=ii", 433 | "--m-rotor=iii", 434 | "--l-rotor-at=a", 435 | "--r-rotor-at=a", 436 | "--m-rotor-at=z", 437 | "--reflector=c", 438 | "--l-ring=1", 439 | "--r-ring=2", 440 | "--m-ring=3", 441 | "--plugboard=q/w,e/r,t/y,u/i,o/p" 442 | }; 443 | 444 | char *argv_32[] = { 445 | "--l-rotor=i", 446 | "--r-rotor=ii", 447 | "--m-rotor=iii", 448 | "--l-rotor-at=a", 449 | "--r-rotor-at=a", 450 | "--m-rotor-at=z", 451 | "--reflector=c", 452 | "--l-ring=1", 453 | "--r-ring=2", 454 | "--m-ring=3", 455 | "--plugboard=q/w,e/r,t/y,u/i,o/p,s/d" 456 | }; 457 | 458 | char *argv_33[] = { 459 | "--l-rotor=i", 460 | "--r-rotor=ii", 461 | "--m-rotor=iii", 462 | "--l-rotor-at=a", 463 | "--r-rotor-at=a", 464 | "--m-rotor-at=z", 465 | "--reflector=c", 466 | "--l-ring=1", 467 | "--r-ring=2", 468 | "--m-ring=3", 469 | "--plugboard=q/w,e/r,t/y,u/i,o/p,s/d,f/g" 470 | }; 471 | 472 | char *argv_34[] = { 473 | "--l-rotor=i", 474 | "--r-rotor=ii", 475 | "--m-rotor=iii", 476 | "--l-rotor-at=a", 477 | "--r-rotor-at=a", 478 | "--m-rotor-at=z", 479 | "--reflector=c", 480 | "--l-ring=1", 481 | "--r-ring=2", 482 | "--m-ring=3", 483 | "--plugboard=q/w,e/r,t/y,u/i,o/p,s/d,f/g,h/j" 484 | }; 485 | 486 | char *argv_35[] = { 487 | "--l-rotor=i", 488 | "--r-rotor=ii", 489 | "--m-rotor=iii", 490 | "--l-rotor-at=a", 491 | "--r-rotor-at=a", 492 | "--m-rotor-at=z", 493 | "--reflector=c", 494 | "--l-ring=1", 495 | "--r-ring=2", 496 | "--m-ring=3", 497 | "--plugboard=q/w,e/r,t/y,u/i,o/p,s/d,f/g,h/j,k/l" 498 | }; 499 | 500 | char *argv_36[] = { 501 | "--l-rotor=i", 502 | "--r-rotor=ii", 503 | "--m-rotor=iii", 504 | "--l-rotor-at=a", 505 | "--r-rotor-at=a", 506 | "--m-rotor-at=z", 507 | "--reflector=c", 508 | "--l-ring=1", 509 | "--r-ring=2", 510 | "--m-ring=3", 511 | "--plugboard=q/w,e/r,t/y,u/i,o/p,s/d,f/g,h/j,k/l,z/x" 512 | }; 513 | 514 | struct test_vector_ctx { 515 | char **argv; 516 | int argc; 517 | int ok; 518 | }; 519 | 520 | #define add_test_step(n, o) { argv_ ## n, sizeof(argv_ ## n) / sizeof(argv_ ## n[0]), o } 521 | 522 | struct test_vector_ctx test_vector[] = { 523 | add_test_step( 0, 0), add_test_step( 1, 0), add_test_step( 2, 0), add_test_step( 3, 0), add_test_step( 4, 0), 524 | add_test_step( 5, 0), add_test_step( 6, 0), add_test_step( 7, 0), add_test_step( 8, 0), add_test_step( 9, 0), 525 | add_test_step(10, 0), add_test_step(11, 0), add_test_step(12, 0), add_test_step(13, 0), add_test_step(14, 0), 526 | add_test_step(15, 0), add_test_step(16, 0), add_test_step(17, 0), add_test_step(18, 0), add_test_step(19, 0), 527 | add_test_step(20, 0), add_test_step(21, 0), add_test_step(22, 0), add_test_step(23, 1), add_test_step(24, 1), 528 | add_test_step(25, 1), add_test_step(26, 1), add_test_step(27, 1), add_test_step(28, 1), add_test_step(29, 1), 529 | add_test_step(30, 1), add_test_step(31, 1), add_test_step(32, 1), add_test_step(33, 1), add_test_step(34, 1), 530 | add_test_step(35, 1), add_test_step(36, 1) 531 | }; 532 | 533 | #undef add_test_step 534 | 535 | const size_t test_vector_nr = sizeof(test_vector) / sizeof(test_vector[0]); 536 | 537 | size_t t = 0; 538 | 539 | libeel_enigma_ctx *setting = NULL; 540 | 541 | set_argc_argv(0, NULL); 542 | setting = ld_enigma_setting(); 543 | 544 | CUTE_ASSERT(setting == NULL); 545 | 546 | while (t < test_vector_nr) { 547 | set_argc_argv(test_vector[t].argc, test_vector[t].argv); 548 | 549 | setting = ld_enigma_setting(); 550 | 551 | if (test_vector[t].ok) { 552 | CUTE_ASSERT(setting != NULL); 553 | libeel_del_enigma_ctx(setting); 554 | setting = NULL; 555 | } else { 556 | CUTE_ASSERT(setting == NULL); 557 | } 558 | 559 | t++; 560 | } 561 | CUTE_TEST_CASE_END 562 | 563 | CUTE_TEST_CASE(enigmactl_trinket_poking_tests) 564 | const char *binpath = "../bin/enigmactl"; 565 | char cmd[255] = ""; 566 | 567 | unload_module(); 568 | 569 | sleep(1); 570 | 571 | // INFO(Santiago): no module, no args. 572 | CUTE_ASSERT(system(binpath) == 0); 573 | 574 | sprintf(cmd, "%s --unset", binpath); 575 | CUTE_ASSERT(system(cmd) != 0); 576 | 577 | CUTE_ASSERT(load_module() == 0); 578 | 579 | sleep(1); 580 | 581 | // INFO(Santiago): with module, no args. 582 | CUTE_ASSERT(system(binpath) == 0); 583 | 584 | sprintf(cmd, "%s --help", binpath); 585 | CUTE_ASSERT(system(cmd) == 0); 586 | 587 | sprintf(cmd, "%s --unset", binpath); 588 | CUTE_ASSERT(system(cmd) == 0); 589 | 590 | sprintf(cmd, "%s --set", binpath); 591 | CUTE_ASSERT(system(cmd) != 0); 592 | 593 | sprintf(cmd, "%s --set --l-rotor=i", binpath); 594 | CUTE_ASSERT(system(cmd) != 0); 595 | 596 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii", binpath); 597 | CUTE_ASSERT(system(cmd) != 0); 598 | 599 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii", binpath); 600 | CUTE_ASSERT(system(cmd) != 0); 601 | 602 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a", binpath); 603 | CUTE_ASSERT(system(cmd) != 0); 604 | 605 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=a", binpath); 606 | CUTE_ASSERT(system(cmd) != 0); 607 | 608 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=a --r-rotor-at=z", binpath); 609 | CUTE_ASSERT(system(cmd) != 0); 610 | 611 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=a --r-rotor-at=z --reflector=b", binpath); 612 | CUTE_ASSERT(system(cmd) == 0); 613 | 614 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=a --r-rotor-at=z --reflector=bx", binpath); 615 | CUTE_ASSERT(system(cmd) == 0); 616 | 617 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=a --r-rotor-at=z --reflector=d", binpath); 618 | CUTE_ASSERT(system(cmd) != 0); 619 | 620 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=a --r-rotor-at=7 --reflector=b", binpath); 621 | CUTE_ASSERT(system(cmd) != 0); 622 | 623 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=3 --r-rotor-at=z --reflector=b", binpath); 624 | CUTE_ASSERT(system(cmd) != 0); 625 | 626 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=. --m-rotor-at=a --r-rotor-at=z --reflector=b", binpath); 627 | CUTE_ASSERT(system(cmd) != 0); 628 | 629 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iiia --l-rotor-at=a --m-rotor-at=a --r-rotor-at=z --reflector=b", binpath); 630 | CUTE_ASSERT(system(cmd) != 0); 631 | 632 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=2 --r-rotor=iii --l-rotor-at=a --m-rotor-at=a --r-rotor-at=z --reflector=b", binpath); 633 | CUTE_ASSERT(system(cmd) != 0); 634 | 635 | sprintf(cmd, "%s --set --l-rotor=1 --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=a --r-rotor-at=z --reflector=b", binpath); 636 | CUTE_ASSERT(system(cmd) != 0); 637 | 638 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=a --r-rotor-at=z --reflector=b --l-ring=2", binpath); 639 | CUTE_ASSERT(system(cmd) == 0); 640 | 641 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=a --r-rotor-at=z --reflector=b --m-ring=3", binpath); 642 | CUTE_ASSERT(system(cmd) == 0); 643 | 644 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=a --r-rotor-at=z --reflector=b --r-ring=5", binpath); 645 | CUTE_ASSERT(system(cmd) == 0); 646 | 647 | sprintf(cmd, "%s --set --l-rotor=i --m-rotor=ii --r-rotor=iii --l-rotor-at=a --m-rotor-at=a --r-rotor-at=z --reflector=c --plugboard=a/b,c/d,e/f,x/g", binpath); 648 | CUTE_ASSERT(system(cmd) == 0); 649 | 650 | sprintf(cmd, "%s --unset", binpath); 651 | CUTE_ASSERT(system(cmd) == 0); 652 | 653 | sleep(1); 654 | 655 | CUTE_ASSERT(unload_module() == 0); 656 | CUTE_TEST_CASE_END 657 | 658 | CUTE_TEST_CASE(enigmactl_tests) 659 | CUTE_RUN_TEST(enigmactl_option_tests); 660 | CUTE_RUN_TEST(enigmactl_setloader_tests); 661 | CUTE_RUN_TEST(enigmactl_trinket_poking_tests); 662 | CUTE_TEST_CASE_END 663 | 664 | CUTE_MAIN(enigmactl_tests); 665 | -------------------------------------------------------------------------------- /src/fops_impl/freebsd/dev_close.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "dev_close.h" 9 | #include "dev_open.h" 10 | #include 11 | #include 12 | #include 13 | 14 | int dev_close(struct cdev *dev, int flags __unused, int devtype __unused, struct thread *td __unused) { 15 | if (dev->si_drv1 == NULL) { 16 | return -EBADF; 17 | } 18 | 19 | return 0; 20 | } 21 | 22 | void dev_close_dtor(void *data) { 23 | if (data == NULL) { 24 | return; 25 | } 26 | 27 | release_uline(*(int *)data); 28 | 29 | free(data, M_DEV_OPEN); 30 | 31 | data = NULL; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/fops_impl/freebsd/dev_close.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_FOPS_IMPL_FREEBSD_DEV_CLOSE_H 9 | #define DEV_ENIGMA_FOPS_IMPL_FREEBSD_DEV_CLOSE_H 1 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | int dev_close(struct cdev *dev, int flags, int devtype, struct thread *td); 17 | 18 | void dev_close_dtor(void *data); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/fops_impl/freebsd/dev_ioctl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "dev_ioctl.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | int dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) { 15 | long result = 0; 16 | libeel_enigma_ctx user_enigma; 17 | struct dev_enigma_usage_line_ctx *ulp; 18 | int uline; 19 | 20 | if (dev->si_drv1 == NULL) { 21 | return -EINVAL; 22 | } 23 | 24 | uline = *(int *)dev->si_drv1; 25 | 26 | ulp = dev_uline_ctx(uline); 27 | 28 | if (ulp == NULL) { 29 | return -EINVAL; 30 | } 31 | 32 | switch (cmd) { 33 | 34 | case ENIGMA_RESET: 35 | if (ulp->has_init) { 36 | 37 | if (!lock_uline(uline)) { 38 | return -EBUSY; 39 | } 40 | 41 | ulp->has_init = libeel_init_machine(ulp->enigma); 42 | 43 | if (!ulp->has_init) { 44 | result = -EINVAL; 45 | } else if (ulp->ebuf_head != NULL) { 46 | del_ebuf_ctx(ulp->ebuf_head); 47 | ulp->ebuf_head = NULL; 48 | } 49 | 50 | unlock_uline(uline); 51 | 52 | } else { 53 | result = -EINVAL; 54 | } 55 | break; 56 | 57 | case ENIGMA_SET: 58 | if (data == NULL) { 59 | return -EFAULT; 60 | } 61 | 62 | if (!lock_uline(uline)) { 63 | return -EBUSY; 64 | } 65 | 66 | memcpy(ulp->enigma, (libeel_enigma_ctx *)data, sizeof(libeel_enigma_ctx)); 67 | 68 | if (!(ulp->has_init = libeel_init_machine(ulp->enigma))) { 69 | result = -EINVAL; 70 | } else if (ulp->ebuf_head != NULL) { 71 | del_ebuf_ctx(ulp->ebuf_head); 72 | ulp->ebuf_head = NULL; 73 | } 74 | 75 | unlock_uline(uline); 76 | break; 77 | 78 | case ENIGMA_SET_DEFAULT_SETTING: 79 | if (data == NULL) { 80 | return -EFAULT; 81 | } 82 | 83 | memcpy(&user_enigma, (libeel_enigma_ctx *)data, sizeof(libeel_enigma_ctx)); 84 | 85 | if (!set_default_enigma_setting(&user_enigma)) { 86 | result = -EINVAL; 87 | } 88 | break; 89 | 90 | case ENIGMA_UNSET_DEFAULT_SETTING: 91 | if (!unset_default_enigma_setting()) { 92 | result = -EFAULT; 93 | } 94 | break; 95 | 96 | default: 97 | result = -ENOTTY; 98 | break; 99 | 100 | } 101 | 102 | return result; 103 | } 104 | -------------------------------------------------------------------------------- /src/fops_impl/freebsd/dev_ioctl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_FOPS_IMPL_FREEBSD_DEV_IOCTL_H 9 | #define DEV_ENIGMA_FOPS_IMPL_FREEBSD_DEV_IOCTL_H 1 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | int dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/fops_impl/freebsd/dev_open.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "dev_open.h" 9 | #include "dev_close.h" 10 | #include 11 | #include 12 | 13 | MALLOC_DEFINE(M_DEV_OPEN, "DEV_ENIGMA_dev_open", "Allocations related with dev_open"); 14 | 15 | int dev_open(struct cdev *dev, int flags __unused, int devtype __unused, struct thread *td __unused) { 16 | int uline = new_uline(); 17 | 18 | if (uline == -1) { 19 | return -EBUSY; 20 | } 21 | 22 | if (!lock_uline(uline)) { 23 | return -EBUSY; 24 | } 25 | 26 | dev->si_drv1 = malloc(sizeof(int), M_DEV_OPEN, M_NOWAIT); 27 | 28 | if (dev->si_drv1 != NULL) { 29 | *((int *)dev->si_drv1) = uline; 30 | devfs_set_cdevpriv(dev->si_drv1, dev_close_dtor); 31 | } 32 | 33 | unlock_uline(uline); 34 | 35 | return (dev->si_drv1 != NULL) ? 0 : -ENOMEM; 36 | } 37 | -------------------------------------------------------------------------------- /src/fops_impl/freebsd/dev_open.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_FOPS_IMPL_FREEBSD_DEV_OPEN_H 9 | #define DEV_ENIGMA_FOPS_IMPL_FREEBSD_DEV_OPEN_H 1 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | MALLOC_DECLARE(M_DEV_OPEN); 18 | 19 | int dev_open(struct cdev *dev, int flags, int devtype, struct thread *td); 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/fops_impl/freebsd/dev_read.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "dev_read.h" 9 | #include 10 | #include 11 | 12 | int dev_read(struct cdev *dev, struct uio *uio, int ioflags) { 13 | int uline; 14 | struct dev_enigma_usage_line_ctx *ulp; 15 | char byte; 16 | size_t read_bytes = 0; 17 | size_t user_len = 0; 18 | 19 | uline = *(int *)dev->si_drv1; 20 | 21 | ulp = dev_uline_ctx(uline); 22 | 23 | if (ulp == NULL) { 24 | return -EBADF; 25 | } 26 | 27 | if (!lock_uline(uline)) { 28 | return -EBUSY; 29 | } 30 | 31 | user_len = uio->uio_iov->iov_len; 32 | 33 | while (read_bytes != user_len && ulp->ebuf_head != NULL) { 34 | byte = get_char_from_ebuf_ctx(&ulp->ebuf_head); 35 | if (uiomove(&byte, 1, uio) != 0) { 36 | read_bytes = 0; 37 | goto __dev_read_epilogue; 38 | } 39 | read_bytes++; 40 | } 41 | 42 | __dev_read_epilogue: 43 | unlock_uline(uline); 44 | 45 | return (read_bytes == 0) ? EFAULT : 0; 46 | } 47 | -------------------------------------------------------------------------------- /src/fops_impl/freebsd/dev_read.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_FOPS_IMPL_FREEBSD_DEV_READ_H 9 | #define DEV_ENIGMA_FOPS_IMPL_FREEBSD_DEV_READ_H 1 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | int dev_read(struct cdev *dev, struct uio *uio, int ioflag); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/fops_impl/freebsd/dev_write.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "dev_write.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | MALLOC_DEFINE(M_DEV_WRITE, "DEV_ENIGMA_dev_write", "Allocations related with dev_write"); 15 | 16 | int dev_write(struct cdev *dev, struct uio *uio, int ioflags) { 17 | struct dev_enigma_usage_line_ctx *ulp; 18 | int uline; 19 | char *temp_buf = NULL; 20 | char *bp, *bp_end; 21 | ssize_t written_bytes = 0; 22 | size_t temp_buf_size = 0; 23 | 24 | uline = *(int *)dev->si_drv1; 25 | 26 | ulp = dev_uline_ctx(uline); 27 | 28 | if (ulp == NULL) { 29 | return -EBADF; 30 | } 31 | 32 | if (!ulp->has_init) { 33 | return -EINVAL; 34 | } 35 | 36 | temp_buf_size = uio->uio_iov->iov_len; 37 | temp_buf = (char *) malloc(temp_buf_size, M_DEV_WRITE, M_NOWAIT); 38 | 39 | if (temp_buf == NULL) { 40 | return -ENOMEM; 41 | } 42 | 43 | if (!lock_uline(uline)) { 44 | return -EBUSY; 45 | } 46 | 47 | if (uiomove(temp_buf, temp_buf_size, uio) != 0) { 48 | free(temp_buf, M_DEV_WRITE); 49 | unlock_uline(uline); 50 | return -EFAULT; 51 | } 52 | 53 | bp = temp_buf; 54 | bp_end = bp + temp_buf_size; 55 | 56 | while (bp != bp_end) { 57 | libeel_enigma_input(ulp->enigma) = *bp; 58 | written_bytes += add_char_to_ebuf_ctx(&ulp->ebuf_head, libeel_type(ulp->enigma), ulp->ebuf_tail); 59 | bp++; 60 | } 61 | 62 | free(temp_buf, M_DEV_WRITE); 63 | 64 | unlock_uline(uline); 65 | 66 | return (written_bytes == temp_buf_size) ? 0 : EFAULT; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/fops_impl/freebsd/dev_write.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_FOPS_IMPL_FREEBSD_DEV_WRITE_H 9 | #define DEV_ENIGMA_FOPS_IMPL_FREEBSD_DEV_WRITE_H 1 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | int dev_write(struct cdev *dev, struct uio *uio, int ioflag); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/fops_impl/linux/dev_ioctl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "dev_ioctl.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | long dev_ioctl(struct file *fp, unsigned int cmd, unsigned long usr_param) { 16 | long result = 0; 17 | libeel_enigma_ctx user_enigma; 18 | struct dev_enigma_usage_line_ctx *ulp; 19 | int uline; 20 | 21 | if (fp->private_data == NULL) { 22 | return -EINVAL; 23 | } 24 | 25 | uline = *(int *)fp->private_data; 26 | 27 | ulp = dev_uline_ctx(uline); 28 | 29 | if (ulp == NULL) { 30 | return -EINVAL; 31 | } 32 | 33 | switch (cmd) { 34 | 35 | case ENIGMA_RESET: 36 | if (ulp->has_init) { 37 | 38 | if (!lock_uline(uline)) { 39 | return -EBUSY; 40 | } 41 | 42 | ulp->has_init = libeel_init_machine(ulp->enigma); 43 | 44 | if (!ulp->has_init) { 45 | result = -EINVAL; 46 | } else if (ulp->ebuf_head != NULL) { 47 | del_ebuf_ctx(ulp->ebuf_head); 48 | ulp->ebuf_head = NULL; 49 | } 50 | 51 | unlock_uline(uline); 52 | 53 | } else { 54 | result = -EINVAL; 55 | } 56 | break; 57 | 58 | case ENIGMA_SET: 59 | if ((void *)usr_param == NULL || 60 | !access_ok(VERIFY_READ, (void __user *)usr_param, _IOC_SIZE(cmd))) { 61 | return -EFAULT; 62 | } 63 | 64 | if (!lock_uline(uline)) { 65 | return -EBUSY; 66 | } 67 | 68 | if (copy_from_user(&user_enigma, (libeel_enigma_ctx *)usr_param, sizeof(libeel_enigma_ctx)) != 0) { 69 | unlock_uline(uline); 70 | return -EFAULT; 71 | } 72 | 73 | memcpy(ulp->enigma, &user_enigma, sizeof(libeel_enigma_ctx)); 74 | 75 | memset(&user_enigma, 0, sizeof(user_enigma)); 76 | 77 | if (!(ulp->has_init = libeel_init_machine(ulp->enigma))) { 78 | result = -EINVAL; 79 | } else if (ulp->ebuf_head != NULL) { 80 | del_ebuf_ctx(ulp->ebuf_head); 81 | ulp->ebuf_head = NULL; 82 | } 83 | 84 | unlock_uline(uline); 85 | break; 86 | 87 | case ENIGMA_SET_DEFAULT_SETTING: 88 | if ((void *)usr_param == NULL || 89 | !access_ok(VERIFY_READ, (void __user *)usr_param, _IOC_SIZE(cmd))) { 90 | return -EFAULT; 91 | } 92 | 93 | if (copy_from_user(&user_enigma, (libeel_enigma_ctx *)usr_param, sizeof(libeel_enigma_ctx)) != 0) { 94 | return -EFAULT; 95 | } 96 | 97 | if (!set_default_enigma_setting(&user_enigma)) { 98 | result = -EINVAL; 99 | } 100 | break; 101 | 102 | case ENIGMA_UNSET_DEFAULT_SETTING: 103 | if (!unset_default_enigma_setting()) { 104 | result = -EFAULT; 105 | } 106 | break; 107 | 108 | default: 109 | result = -ENOTTY; 110 | break; 111 | 112 | } 113 | 114 | return result; 115 | } 116 | -------------------------------------------------------------------------------- /src/fops_impl/linux/dev_ioctl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_FOPS_IMPL_DEV_IOCTL_H 9 | #define DEV_ENIGMA_FOPS_IMPL_DEV_IOCTL_H 1 10 | 11 | #include 12 | 13 | long dev_ioctl(struct file *fp, unsigned int cmd, unsigned long usr_param); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/fops_impl/linux/dev_open.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "dev_open.h" 9 | #include 10 | #include 11 | 12 | int dev_open(struct inode *ip, struct file *fp) { 13 | int uline = new_uline(); 14 | 15 | if (uline == -1) { 16 | return -EBUSY; 17 | } 18 | 19 | if (!lock_uline(uline)) { 20 | return -EBUSY; 21 | } 22 | 23 | fp->private_data = kmalloc(sizeof(int), GFP_ATOMIC); 24 | 25 | if (fp->private_data != NULL) { 26 | *((int *)fp->private_data) = uline; 27 | } 28 | 29 | unlock_uline(uline); 30 | 31 | return (fp->private_data != NULL) ? 0 : -ENOMEM; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/fops_impl/linux/dev_open.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_FOPS_IMPL_LINUX_DEV_OPEN_H 9 | #define DEV_ENIGMA_FOPS_IMPL_LINUX_DEV_OPEN_H 1 10 | 11 | #include 12 | 13 | int dev_open(struct inode *ip, struct file *fp); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/fops_impl/linux/dev_read.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "dev_read.h" 9 | #include 10 | #include 11 | #include 12 | 13 | ssize_t dev_read(struct file *fp, char __user *buf, size_t count, loff_t *f_pos) { 14 | int uline; 15 | struct dev_enigma_usage_line_ctx *ulp; 16 | char byte; 17 | ssize_t read_bytes = 0; 18 | 19 | uline = *(int *)fp->private_data; 20 | 21 | ulp = dev_uline_ctx(uline); 22 | 23 | if (ulp == NULL) { 24 | return -EBADF; 25 | } 26 | 27 | if (!lock_uline(uline)) { 28 | return -EBUSY; 29 | } 30 | 31 | while (read_bytes != count && ulp->ebuf_head != NULL) { 32 | byte = get_char_from_ebuf_ctx(&ulp->ebuf_head); 33 | if (copy_to_user(buf + read_bytes, &byte, 1) != 0) { 34 | read_bytes = -EFAULT; 35 | goto __dev_read_epilogue; 36 | } 37 | read_bytes++; 38 | } 39 | 40 | *f_pos += read_bytes; 41 | 42 | __dev_read_epilogue: 43 | unlock_uline(uline); 44 | 45 | return read_bytes; 46 | } 47 | -------------------------------------------------------------------------------- /src/fops_impl/linux/dev_read.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_FOPS_IMPL_DEV_READ_H 9 | #define DEV_ENIGMA_FOPS_IMPL_DEV_READ_H 1 10 | 11 | #include 12 | 13 | ssize_t dev_read(struct file *fp, char __user *buf, size_t count, loff_t *f_pos); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/fops_impl/linux/dev_release.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "dev_release.h" 9 | #include 10 | #include 11 | 12 | int dev_release(struct inode *ip, struct file *fp) { 13 | if (fp->private_data == NULL) { 14 | return -EBADF; 15 | } 16 | 17 | release_uline(*(int *)fp->private_data); 18 | 19 | kfree(fp->private_data); 20 | fp->private_data = NULL; 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /src/fops_impl/linux/dev_release.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_FOPS_IMPL_DEV_RELEASE_H 9 | #define DEV_ENIGMA_FOPS_IMPL_DEV_RELEASE_H 1 10 | 11 | #include 12 | 13 | int dev_release(struct inode *ip, struct file *fp); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/fops_impl/linux/dev_write.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "dev_write.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | ssize_t dev_write(struct file *fp, const char __user *buf, size_t count, loff_t *fpos) { 16 | struct dev_enigma_usage_line_ctx *ulp; 17 | int uline; 18 | char *temp_buf = NULL; 19 | char *bp, *bp_end; 20 | ssize_t written_bytes = 0; 21 | 22 | uline = *(int *)fp->private_data; 23 | 24 | ulp = dev_uline_ctx(uline); 25 | 26 | if (ulp == NULL) { 27 | return -EBADF; 28 | } 29 | 30 | if (!ulp->has_init) { 31 | return -EINVAL; 32 | } 33 | 34 | if (!access_ok(VERIFY_READ, (void __user *)buf, count)) { 35 | return -EFAULT; 36 | } 37 | 38 | temp_buf = (char *) kmalloc(count, GFP_ATOMIC); 39 | 40 | if (temp_buf == NULL) { 41 | return -ENOMEM; 42 | } 43 | 44 | if (!lock_uline(uline)) { 45 | kfree(temp_buf); 46 | return -EBUSY; 47 | } 48 | 49 | if (copy_from_user(temp_buf, buf, count) != 0) { 50 | kfree(temp_buf); 51 | unlock_uline(uline); 52 | return -EFAULT; 53 | } 54 | 55 | bp = temp_buf; 56 | bp_end = bp + count; 57 | 58 | while (bp != bp_end) { 59 | libeel_enigma_input(ulp->enigma) = *bp; 60 | written_bytes += add_char_to_ebuf_ctx(&ulp->ebuf_head, libeel_type(ulp->enigma), ulp->ebuf_tail); 61 | bp++; 62 | } 63 | 64 | *fpos += written_bytes; 65 | 66 | kfree(temp_buf); 67 | 68 | unlock_uline(uline); 69 | 70 | return written_bytes; 71 | } 72 | -------------------------------------------------------------------------------- /src/fops_impl/linux/dev_write.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_FOPS_IMPL_DEV_WRITE_H 9 | #define DEV_ENIGMA_FOPS_IMPL_DEV_WRITE_H 1 10 | 11 | #include 12 | 13 | ssize_t dev_write(struct file *fp, const char __user *buf, size_t count, loff_t *f_pos); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/installer.hsl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 by Rafael Santiago 3 | # 4 | # This is free software. You can redistribute it and/or modify under 5 | # the terms of the GNU General Public License version 2. 6 | # 7 | # 8 | 9 | include ~/fsutil.hsl 10 | 11 | function device_installer() : result type none { 12 | var option type list; 13 | 14 | $option = hefesto.sys.get_option("install"); 15 | 16 | if ($option.count() > 0) { 17 | hefesto.project.abort(dev_install()); 18 | } 19 | 20 | $option = hefesto.sys.get_option("uninstall"); 21 | 22 | if ($option.count() > 0) { 23 | hefesto.project.abort(dev_uninstall()); 24 | } 25 | } 26 | 27 | local function dev_install() : result type int { 28 | var possible_answers type list; 29 | 30 | $possible_answers.add_item("y"); 31 | $possible_answers.add_item("Y"); 32 | $possible_answers.add_item("n"); 33 | $possible_answers.add_item("N"); 34 | 35 | var answer type string; 36 | 37 | $answer = get_answer("Do you want to install /dev/enigma? [y/n] ", $possible_answers); 38 | 39 | if ($answer == "n" || $answer == "N") { 40 | hefesto.sys.echo("\nERROR: Aborted by the user.\n"); 41 | result 1; 42 | } 43 | 44 | hefesto.sys.echo("\n"); 45 | 46 | if (isfile("enigma.ko") == 0) { 47 | var exit_code type int; 48 | $exit_code = hefesto.sys.run("hefesto"); 49 | 50 | if ($exit_code != 0) { 51 | hefesto.sys.echo("ERROR: Unable to install. Aborted.\n"); 52 | result 1; 53 | } 54 | } 55 | 56 | var device_trinket_src type list; 57 | var device_trinket_dst type list; 58 | 59 | $device_trinket_src.add_item("enigmactl/enigmactl.h"); 60 | $device_trinket_src.add_item("enigmactl/user/eel/src/eel.h"); 61 | $device_trinket_src.add_item("enigmactl/user/eel/src/types.h"); 62 | $device_trinket_src.add_item("enigma.ko"); 63 | $device_trinket_src.add_item("enigmactl/user/bin/enigmactl"); 64 | if (hefesto.sys.os_name() == "linux") { 65 | $device_trinket_src.add_item("../etc/99-enigma.rules"); 66 | } 67 | $device_trinket_src.add_item("../README.md"); 68 | $device_trinket_src.add_item("enigmactl/user/doc/man/enigmactl.1"); 69 | $device_trinket_src.add_item("../etc/enigmactl.sh"); 70 | 71 | $device_trinket_dst.add_item("/usr/local/share/dev-enigma/include/enigmactl.h"); 72 | $device_trinket_dst.add_item("/usr/local/share/dev-enigma/include/eel.h"); 73 | $device_trinket_dst.add_item("/usr/local/share/dev-enigma/include/types.h"); 74 | $device_trinket_dst.add_item("/usr/local/share/dev-enigma/mod/enigma.ko"); 75 | $device_trinket_dst.add_item("/usr/local/bin/enigmactl"); 76 | if (hefesto.sys.os_name() == "linux") { 77 | $device_trinket_dst.add_item("/etc/udev/rules.d/99-enigma.rules"); 78 | } 79 | $device_trinket_dst.add_item("/usr/local/share/dev-enigma/doc/README.md"); 80 | $device_trinket_dst.add_item("/usr/local/man/man1/enigmactl.1"); 81 | $device_trinket_dst.add_item("/usr/local/bin/enigmactl.sh"); 82 | 83 | var t type int; 84 | 85 | $t = 0; 86 | while ($t < $device_trinket_src.count()) { 87 | var dirpath type string; 88 | 89 | $dirpath = $device_trinket_dst.item($t); 90 | $dirpath = pathfromfilepath($dirpath); 91 | 92 | mktree($dirpath); 93 | 94 | if (hefesto.sys.cp($device_trinket_src.item($t), $device_trinket_dst.item($t)) != 1) { 95 | hefesto.sys.echo("ERROR: Unable to copy to " + $device_trinket_dst.item($t) + ". Aborted.\n"); 96 | result 1; 97 | } 98 | 99 | var filepath type string; 100 | $filepath = $device_trinket_dst.item($t); 101 | 102 | if ($filepath.match(".*\\.sh$") == 1) { 103 | hefesto.sys.run("chmod +x " + $filepath); 104 | } 105 | 106 | $t = $t + 1; 107 | } 108 | 109 | # INFO(Santiago): Let's properly customize a sheebang for the current machine. 110 | 111 | hefesto.sys.replace_in_file("/usr/local/bin/enigmactl.sh", "# ---GLUE YOUR SHEEBANG HERE---", "#!" + which_bash()); 112 | 113 | hefesto.sys.echo("INFO: The device was successfully installed.\n"); 114 | 115 | result 0; 116 | } 117 | 118 | local function dev_uninstall() : result type int { 119 | var possible_answers type list; 120 | 121 | $possible_answers.add_item("y"); 122 | $possible_answers.add_item("Y"); 123 | $possible_answers.add_item("n"); 124 | $possible_answers.add_item("N"); 125 | 126 | var answer type string; 127 | 128 | $answer = get_answer("Do you want to uninstall /dev/enigma? [y/n] ", $possible_answers); 129 | 130 | if ($answer == "n" || $answer == "N") { 131 | hefesto.sys.echo("\nERROR: Aborted by the user.\n"); 132 | result 1; 133 | } 134 | 135 | var to_burn type list; 136 | 137 | $to_burn.add_item("/usr/local/share/dev-enigma/include/enigmactl.h"); 138 | $to_burn.add_item("/usr/local/share/dev-enigma/include/eel.h"); 139 | $to_burn.add_item("/usr/local/share/dev-enigma/include/types.h"); 140 | $to_burn.add_item("/usr/local/share/dev-enigma/include"); 141 | $to_burn.add_item("/usr/local/share/dev-enigma/mod/enigma.ko"); 142 | $to_burn.add_item("/usr/local/share/dev-enigma/mod"); 143 | $to_burn.add_item("/usr/local/share/dev-enigma/doc/README.md"); 144 | $to_burn.add_item("/usr/local/share/dev-enigma/doc"); 145 | $to_burn.add_item("/usr/local/share/dev-enigma/"); 146 | $to_burn.add_item("/usr/local/bin/enigmactl"); 147 | $to_burn.add_item("/usr/local/bin/enigmactl.sh"); 148 | if (hefesto.sys.os_name() == "linux") { 149 | $to_burn.add_item("/etc/udev/rules.d/99-enigma.rules"); 150 | } 151 | $to_burn.add_item("/usr/local/man/man1/enigmactl.1"); 152 | 153 | var b type int; 154 | 155 | $b = 0; 156 | while ($b < $to_burn.count()) { 157 | var return type int; 158 | var path type string; 159 | 160 | $path = $to_burn.item($b); 161 | 162 | if (isdir($path)) { 163 | $return = (hefesto.sys.rmdir($path) == 0); 164 | } else if (isfile($path)) { 165 | $return = (hefesto.sys.rm($path) == 0); 166 | } 167 | 168 | if ($return == 0) { 169 | hefesto.sys.echo("WARN: Unable to remove " + $path + ".\n"); 170 | } 171 | 172 | $b = $b + 1; 173 | } 174 | 175 | result 0; 176 | } 177 | 178 | local function get_answer(question type string, possible_answers type list) : result type string { 179 | var answer type string; 180 | 181 | $answer = ""; 182 | 183 | while ($possible_answers.index_of($answer) == -1) { 184 | $answer = hefesto.sys.prompt($question); 185 | } 186 | 187 | result $answer; 188 | } 189 | 190 | local function which_bash() : result type string { 191 | var exit_code type int; 192 | $exit_code = hefesto.sys.run("which bash > .which_bash.out"); 193 | 194 | var which_bash_out type list; 195 | $which_bash_out = hefesto.sys.lines_from_file(".which_bash.out", ".*"); 196 | 197 | var bash_path type string; 198 | if ($which_bash_out.count() > 0) { 199 | $bash_path = $which_bash_out.item(0); 200 | } else if (hefesto.sys.os_name() == "linux") { 201 | $bash_path = "/bin/bash"; 202 | } else if (hefesto.sys.os_name() == "freebsd") { 203 | $bash_path = "/usr/local/bin/bash"; 204 | } 205 | 206 | hefesto.sys.rm(".which_bash.out"); 207 | 208 | result $bash_path; 209 | } 210 | -------------------------------------------------------------------------------- /src/mkclean.hsl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 by Rafael Santiago 3 | # 4 | # This is free software. You can redistribute it and/or modify under 5 | # the terms of the GNU General Public License version 2. 6 | # 7 | # 8 | 9 | include ~/fsutil.hsl 10 | 11 | function cleaner() : result type none { 12 | var option type list; 13 | 14 | $option = hefesto.sys.get_option("clean"); 15 | 16 | if ($option.count() > 0) { 17 | mkclean(); 18 | hefesto.project.abort(0); 19 | } 20 | } 21 | 22 | local function mkclean() : result type none { 23 | hefesto.sys.echo("*** Making it clean... wait...\n"); 24 | 25 | var dirs type list; 26 | $dirs.add_item(hefesto.sys.pwd()); 27 | 28 | mkclean_recur($dirs); 29 | 30 | hefesto.sys.cd($dirs.item(0)); 31 | 32 | hefesto.sys.echo("*** Clean\n"); 33 | } 34 | 35 | local function mkclean_recur(dirs type list) : result type none { 36 | var d type int; 37 | $d = 0; 38 | 39 | while ($d < $dirs.count()) { 40 | if (hefesto.sys.cd($dirs.item($d))) { 41 | hefesto.sys.echo(" Now on " + $dirs.item($d) + "...\n"); 42 | var objs type list; 43 | $objs.ls(".*\\.(o|ko|a)$"); 44 | 45 | while ($objs.count() > 0) { 46 | hefesto.sys.echo(" rm " + $objs.item(0) + "...\n"); 47 | hefesto.sys.rm($objs.item(0)); 48 | $objs.del_index(0); 49 | } 50 | 51 | mkclean_recur(lsdir()); 52 | } 53 | $d = $d + 1; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/mod.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include 9 | #include 10 | 11 | #if defined(__linux__) 12 | 13 | #include 14 | #include 15 | 16 | MODULE_LICENSE("GPL"); 17 | MODULE_AUTHOR("Rafael Santiago"); 18 | MODULE_DESCRIPTION("An Enigma machine simulator as char device"); 19 | MODULE_VERSION("0.0.1"); 20 | 21 | static int __init ini(void) { 22 | return enigma_init(); 23 | } 24 | 25 | static void __exit finis(void) { 26 | enigma_exit(); 27 | } 28 | 29 | module_init(ini); 30 | module_exit(finis); 31 | 32 | #elif defined(__FreeBSD__) 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | static int enigma_modevent(module_t mod __unused, int event, void *arg __unused) { 41 | int error = 0; 42 | 43 | switch (event) { 44 | case MOD_LOAD: 45 | error = enigma_init(); 46 | break; 47 | 48 | case MOD_UNLOAD: 49 | enigma_exit(); 50 | break; 51 | 52 | case MOD_QUIESCE: 53 | if (!safe_for_unloading()) { 54 | error = EBUSY; 55 | } 56 | break; 57 | 58 | default: 59 | error = EOPNOTSUPP; 60 | break; 61 | } 62 | 63 | return error; 64 | } 65 | 66 | DEV_MODULE(enigma, enigma_modevent, NULL); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/mod_info.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_MOD_TRAPS_MOD_INFO_H 9 | #define DEV_ENIGMA_MOD_TRAPS_MOD_INFO_H 1 10 | 11 | #define DEVNAME "enigma" 12 | #define CLASS_NAME "ems" 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/mod_traps/freebsd/mod_exit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "mod_exit.h" 9 | #include "mod_info.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | void enigma_exit(void) { 17 | uprintf("dev/enigma: The /dev/enigma is being unloaded...\n"); 18 | 19 | deinit_ulines(); 20 | 21 | unset_default_enigma_setting(); 22 | 23 | mtx_destroy(&dev_ctx()->lock); 24 | 25 | destroy_dev(dev_ctx()->device); 26 | 27 | uprintf("dev/enigma: Done.\n"); 28 | } 29 | -------------------------------------------------------------------------------- /src/mod_traps/freebsd/mod_exit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_MOD_TRAPS_FREEBSD_MOD_EXIT_H 9 | #define DEV_ENIGMA_MOD_TRAPS_FREEBSD_MOD_EXIT_H 1 10 | 11 | void enigma_exit(void); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/mod_traps/freebsd/mod_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "mod_init.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | static struct cdevsw dev_enigma_cdevsw = { 22 | .d_version = D_VERSION, 23 | .d_open = dev_open, 24 | .d_close = dev_close, 25 | .d_read = dev_read, 26 | .d_write = dev_write, 27 | .d_ioctl = dev_ioctl, 28 | .d_name = DEVNAME 29 | }; 30 | 31 | int enigma_init(void) { 32 | uprintf("dev/enigma: Initializing the /dev/enigma...\n"); 33 | 34 | dev_ctx()->default_setting = NULL; 35 | mtx_init(&dev_ctx()->lock, "DEV_ENIGMA_device_lock", NULL, MTX_DEF); 36 | 37 | init_ulines(); 38 | 39 | dev_ctx()->device = make_dev(&dev_enigma_cdevsw, 0, UID_ROOT, GID_WHEEL, 0666, DEVNAME); 40 | 41 | if (dev_ctx()->device == NULL) { 42 | uprintf("dev/enigma: device creation fail.\n"); 43 | return 1; 44 | } 45 | 46 | uprintf("dev/enigma: Done.\n"); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /src/mod_traps/freebsd/mod_init.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_MOD_TRAPS_FREEBSD_INIT_H 9 | #define DEV_ENIGMA_MOD_TRAPS_FREEBSD_INIT_H 1 10 | 11 | int enigma_init(void); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/mod_traps/freebsd/mod_quiesce.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "mod_quiesce.h" 9 | #include 10 | 11 | int safe_for_unloading(void) { 12 | int safe = 1; 13 | int u; 14 | 15 | for (u = 0; u < DEV_USAGE_LINES_NR && safe; u++) { 16 | if (!lock_uline(u)) { 17 | safe = 0; 18 | } else { 19 | safe = (dev_ctx()->ulines[u].enigma == NULL); 20 | unlock_uline(u); 21 | } 22 | } 23 | 24 | return safe; 25 | } 26 | -------------------------------------------------------------------------------- /src/mod_traps/freebsd/mod_quiesce.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_MOD_TRAPS_FREEBSD_MOD_QUIESCE_H 9 | #define DEV_ENIGMA_MOD_TRAPS_FREEBSD_MOD_QUIESCE_H 1 10 | 11 | int safe_for_unloading(void); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/mod_traps/linux/mod_exit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "mod_exit.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | void __exit enigma_exit(void) { 19 | printk(KERN_INFO "dev/enigma: The /dev/enigma is being unloaded...\n"); 20 | 21 | deinit_ulines(); 22 | 23 | unset_default_enigma_setting(); 24 | 25 | mutex_destroy(&dev_ctx()->lock); 26 | 27 | device_destroy(dev_ctx()->device_class, MKDEV(dev_ctx()->major_nr, 0)); 28 | 29 | class_unregister(dev_ctx()->device_class); 30 | class_destroy(dev_ctx()->device_class); 31 | 32 | unregister_chrdev(dev_ctx()->major_nr, DEVNAME); 33 | 34 | printk(KERN_INFO "dev/enigma: Done.\n"); 35 | } 36 | -------------------------------------------------------------------------------- /src/mod_traps/linux/mod_exit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_MOD_TRAPS_LINUX_MOD_EXIT_H 9 | #define DEV_ENIGMA_MOD_TRAPS_LINUX_MOD_EXIT_H 1 10 | 11 | void enigma_exit(void); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/mod_traps/linux/mod_init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include "mod_init.h" 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | static struct file_operations fops = { 21 | .owner = THIS_MODULE, 22 | .open = dev_open, 23 | .release = dev_release, 24 | .read = dev_read, 25 | .write = dev_write, 26 | .unlocked_ioctl = dev_ioctl 27 | }; 28 | 29 | int __init enigma_init(void) { 30 | printk(KERN_INFO "dev/enigma: Initializing the /dev/enigma...\n"); 31 | 32 | dev_ctx()->default_setting = NULL; 33 | mutex_init(&dev_ctx()->lock); 34 | 35 | init_ulines(); 36 | 37 | dev_ctx()->major_nr = register_chrdev(0, DEVNAME, &fops); 38 | 39 | if (dev_ctx()->major_nr < 0) { 40 | printk(KERN_INFO "dev/enigma: \tdevice registration has failed.\n"); 41 | return dev_ctx()->major_nr; 42 | } 43 | 44 | printk(KERN_INFO "dev/enigma: \tdevice registered under the number %d.\n", dev_ctx()->major_nr); 45 | 46 | dev_ctx()->device_class = class_create(THIS_MODULE, CLASS_NAME); 47 | 48 | if (IS_ERR(dev_ctx()->device_class)) { 49 | unregister_chrdev(dev_ctx()->major_nr, DEVNAME); 50 | printk(KERN_INFO "dev/enigma: \tclass creation fail.\n"); 51 | return PTR_ERR(dev_ctx()->device_class); 52 | } 53 | 54 | printk(KERN_INFO "dev/enigma: \tdevice class successfully created.\n"); 55 | 56 | dev_ctx()->device = device_create(dev_ctx()->device_class, NULL, MKDEV(dev_ctx()->major_nr, 0), NULL, DEVNAME); 57 | 58 | if (IS_ERR(dev_ctx()->device)) { 59 | class_destroy(dev_ctx()->device_class); 60 | unregister_chrdev(dev_ctx()->major_nr, DEVNAME); 61 | printk(KERN_INFO "dev/enigma: \tdevice creation fail.\n"); 62 | return PTR_ERR(dev_ctx()->device); 63 | } 64 | 65 | printk(KERN_INFO "dev/enigma: Done.\n"); 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /src/mod_traps/linux/mod_init.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #ifndef DEV_ENIGMA_MOD_TRAPS_LINUX_INIT_H 9 | #define DEV_ENIGMA_MOD_TRAPS_LINUX_INIT_H 1 10 | 11 | int enigma_init(void); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/run_test.hsl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 by Rafael Santiago 3 | # 4 | # This is free software. You can redistribute it and/or modify under 5 | # the terms of the GNU General Public License version 2. 6 | # 7 | # 8 | 9 | function run_test() : result type none { 10 | var skip_test type list; 11 | $skip_test = hefesto.sys.get_option("skip-test"); 12 | if ($skip_test.count() > 0) { 13 | result 0; 14 | } 15 | if (hefesto.sys.cd("test")) { 16 | var test_options type string; 17 | $test_options = "--obj-output-dir=o --bin-output-dir=bin"; 18 | 19 | var devels_forge type list; 20 | $devels_forge = hefesto.sys.get_option("devels-forge"); 21 | 22 | if ($devels_forge.count() == 0) { 23 | $test_options = $test_options + " --no-pontius-check"; 24 | } 25 | hefesto.sys.forge("incendiary-tests", "Forgefile.hsl", $test_options); 26 | hefesto.sys.cd(".."); 27 | if (hefesto.sys.last_forge_result() != 0) { 28 | hefesto.project.abort(hefesto.sys.last_forge_result()); 29 | } 30 | } else { 31 | hefesto.sys.echo("ERROR: Unable to run the tests.\n"); 32 | hefesto.project.abort(1); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/.ivk: -------------------------------------------------------------------------------- 1 | --forgefiles=Forgefile.hsl --Forgefile-projects=incendiary-tests --obj-output-dir=o --bin-output-dir=bin 2 | -------------------------------------------------------------------------------- /src/test/Forgefile.hsl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 by Rafael Santiago 3 | # 4 | # This is free software. You can redistribute it and/or modify under 5 | # the terms of the GNU General Public License version 2. 6 | # 7 | # 8 | 9 | include ~/toolsets/gcc/gcc-app.hsl 10 | 11 | var sources type list; 12 | var includes type list; 13 | var cflags type list; 14 | var libraries type list; 15 | var ldflags type list; 16 | var appname type string; 17 | 18 | project incendiary-tests : toolset "gcc-c-app" : $sources, $includes, $cflags, $libraries, $ldflags, $appname; 19 | 20 | incendiary-tests.prologue() { 21 | pontius_check(); 22 | 23 | $appname = "dev-enigma-tests"; 24 | 25 | $sources.ls(".*\\.c$"); 26 | $includes.add_item("../eel"); 27 | $includes.add_item("cutest/src"); 28 | $includes.add_item("../enigmactl"); 29 | 30 | var cwd type string; 31 | $cwd = hefesto.sys.pwd(); 32 | 33 | if (hefesto.sys.cd("cutest/src")) { 34 | hefesto.sys.forge("cutest", "Forgefile.hsl", "--obj-output-dir=obj --bin-output-dir=lib"); 35 | hefesto.sys.cd($cwd); 36 | } 37 | 38 | if (hefesto.sys.last_forge_result() != 0) { 39 | hefesto.project.abort(hefesto.sys.last_forge_result()); 40 | } 41 | 42 | $libraries.add_item("cutest/src/lib"); 43 | $ldflags.add_item("-lcutest"); 44 | 45 | if (hefesto.sys.os_name() == "linux") { 46 | $ldflags.add_item("-ldl"); 47 | $ldflags.add_item("-lpthread"); 48 | } else if (hefesto.sys.os_name() == "freebsd") { 49 | $ldflags.add_item("-lexecinfo"); 50 | $ldflags.add_item("-lpthread"); 51 | } 52 | } 53 | 54 | incendiary-tests.epilogue() { 55 | if (hefesto.sys.last_forge_result() == 0) { 56 | var exit_code type int; 57 | $exit_code = hefesto.sys.run(hefesto.sys.make_path("bin", $appname)); 58 | if ($exit_code != 0) { 59 | hefesto.project.abort($exit_code); 60 | } 61 | } 62 | } 63 | 64 | local function pontius_check() : result type none { 65 | var run_babe_run type list; 66 | $run_babe_run = hefesto.sys.get_option("no-pontius-check"); 67 | 68 | if ($run_babe_run.count() == 0) { 69 | var opt type string; 70 | var answers type list; 71 | $answers.add_item("y"); 72 | $answers.add_item("Y"); 73 | $answers.add_item("n"); 74 | $answers.add_item("N"); 75 | $opt = "?"; 76 | while ($answers.index_of($opt) == -1) { 77 | $opt = hefesto.sys.prompt("=== WARNING: Now tests over a kernel module will be executed.\n\n" + 78 | " If you have made changes over this LKM and you are not so sure about its basic correctness,\n" + 79 | " maybe you should avoid running it because you can get kernel panics among other amazing stuff.\n\n" + 80 | "Q: Are you sure that you want to start a fir... err... to insert the generated module into your kernel and\n" + 81 | " test it by your own risk? [y/n] "); 82 | if ($answers.index_of($opt) == -1) { 83 | hefesto.sys.echo("\nYep, Hey " + mascot_name() + "!... I see that we got a genius here man, let's try again... S l o w l y . . .\n\n"); 84 | } 85 | } 86 | 87 | if ($opt == "n" || $opt == "N") { 88 | hefesto.sys.echo("\n~~~INFO: The module tests were aborted by the user.\n"); 89 | hefesto.project.abort(0); 90 | } 91 | } 92 | } 93 | 94 | local function mascot_name() : result type string { 95 | if (hefesto.sys.os_name() == "linux") { 96 | result "Tux"; 97 | } 98 | 99 | if (hefesto.sys.os_name() == "freebsd") { 100 | result "Beastie"; 101 | } 102 | 103 | result "Foobar"; 104 | } 105 | -------------------------------------------------------------------------------- /src/test/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 by Rafael Santiago 3 | * 4 | * This is free software. You can redistribute it and/or modify under 5 | * the terms of the GNU General Public License version 2. 6 | * 7 | */ 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define BREATH_INSECS 0 // WARN(Santiago): If you are experiencing some LKM loading/unload issues try to increase it. 17 | 18 | static int devfd; 19 | 20 | static int load_module(void); 21 | 22 | static int unload_module(void); 23 | 24 | static int load_module(void) { 25 | int exit_code = 1; 26 | 27 | #if defined(__linux__) 28 | exit_code = system("insmod ../enigma.ko"); 29 | #elif defined(__FreeBSD__) 30 | exit_code = system("kldload ../enigma.ko"); 31 | #endif 32 | 33 | return exit_code; 34 | } 35 | 36 | static int unload_module(void) { 37 | int exit_code = 1; 38 | 39 | #if defined(__linux__) 40 | exit_code = system("rmmod enigma"); 41 | #elif defined(__FreeBSD__) 42 | exit_code = system("kldunload enigma.ko"); 43 | #endif 44 | 45 | return exit_code; 46 | } 47 | 48 | CUTE_TEST_CASE(open_tests) 49 | int exit_code; 50 | int fd; 51 | 52 | fd = open("/dev/enigma", O_RDWR); 53 | 54 | CUTE_ASSERT(fd != -1); 55 | 56 | close(fd); 57 | CUTE_TEST_CASE_END 58 | 59 | CUTE_TEST_CASE(dev_ctls_tests) 60 | int fd; 61 | libeel_enigma_ctx daily_setting; 62 | int result = 0; 63 | 64 | fd = open("/dev/enigma", O_RDWR); 65 | 66 | CUTE_ASSERT(fd >= 0); 67 | 68 | CUTE_ASSERT(ioctl(fd, ENIGMA_RESET) != 0); 69 | 70 | sleep(BREATH_INSECS); 71 | 72 | CUTE_ASSERT(ioctl(fd, ENIGMA_SET, NULL) != 0); 73 | 74 | sleep(BREATH_INSECS); 75 | 76 | CUTE_ASSERT(ioctl(fd, ENIGMA_UNSET_DEFAULT_SETTING) == 0); 77 | 78 | sleep(BREATH_INSECS); 79 | 80 | CUTE_ASSERT(ioctl(fd, ENIGMA_SET_DEFAULT_SETTING, NULL) != 0); 81 | 82 | daily_setting.left_rotor = i; 83 | daily_setting.middle_rotor = iv; 84 | daily_setting.right_rotor = i; 85 | 86 | daily_setting.reflector = b; 87 | 88 | libeel_ring(&daily_setting, l) = 1; 89 | libeel_ring(&daily_setting, m) = 5; 90 | libeel_ring(&daily_setting, r) = 23; 91 | 92 | libeel_rotor_at(&daily_setting, l) = 'L'; 93 | libeel_rotor_at(&daily_setting, m) = 'N'; 94 | libeel_rotor_at(&daily_setting, r) = 'X'; 95 | 96 | libeel_plugboard(&daily_setting, 1).l = 'A'; 97 | libeel_plugboard(&daily_setting, 1).r = 'M'; 98 | libeel_plugboard(&daily_setting, 2).l = 'B'; 99 | libeel_plugboard(&daily_setting, 2).r = 'O'; 100 | libeel_plugboard(&daily_setting, 3).l = 'C'; 101 | libeel_plugboard(&daily_setting, 3).r = 'P'; 102 | libeel_plugboard(&daily_setting, 4).l = 'D'; 103 | libeel_plugboard(&daily_setting, 4).r = 'Q'; 104 | libeel_plugboard(&daily_setting, 5).l = 'E'; 105 | libeel_plugboard(&daily_setting, 5).r = 'R'; 106 | libeel_plugboard(&daily_setting, 6).l = 'F'; 107 | libeel_plugboard(&daily_setting, 6).r = 'S'; 108 | 109 | CUTE_ASSERT(ioctl(fd, ENIGMA_SET, &daily_setting) != 0); 110 | 111 | CUTE_ASSERT(ioctl(fd, ENIGMA_SET_DEFAULT_SETTING, &daily_setting) != 0); 112 | 113 | daily_setting.right_rotor = vii; 114 | 115 | CUTE_ASSERT(ioctl(fd, ENIGMA_SET, &daily_setting) == 0); 116 | 117 | sleep(BREATH_INSECS); 118 | 119 | CUTE_ASSERT(ioctl(fd, ENIGMA_SET_DEFAULT_SETTING, &daily_setting) == 0); 120 | 121 | sleep(BREATH_INSECS); 122 | 123 | result = ioctl(fd, ENIGMA_RESET); 124 | 125 | if (result != 0) { 126 | perror("ioctl"); 127 | printf("result = %d\n", result); 128 | sleep(2); 129 | result = ioctl(fd, ENIGMA_RESET); 130 | } 131 | 132 | CUTE_ASSERT(result == 0); 133 | 134 | sleep(BREATH_INSECS); 135 | 136 | CUTE_ASSERT(ioctl(fd, ENIGMA_RESET) == 0); 137 | 138 | sleep(BREATH_INSECS); 139 | 140 | CUTE_ASSERT(ioctl(fd, ENIGMA_UNSET_DEFAULT_SETTING) == 0); 141 | 142 | sleep(BREATH_INSECS); 143 | 144 | close(fd); 145 | CUTE_TEST_CASE_END 146 | 147 | CUTE_TEST_CASE(devio_open_tests) 148 | devfd = open("/dev/enigma", O_RDWR); 149 | CUTE_ASSERT(devfd > -1); 150 | CUTE_TEST_CASE_END 151 | 152 | CUTE_TEST_CASE(devio_ioctlset_tests) 153 | libeel_enigma_ctx dev_enigma; 154 | 155 | memset(&dev_enigma, 0, sizeof(dev_enigma)); 156 | 157 | dev_enigma.left_rotor = i; 158 | dev_enigma.middle_rotor = ii; 159 | dev_enigma.right_rotor = iii; 160 | 161 | libeel_ring(&dev_enigma, l) = 1; 162 | libeel_ring(&dev_enigma, m) = 1; 163 | libeel_ring(&dev_enigma, r) = 1; 164 | 165 | dev_enigma.reflector = b; 166 | 167 | libeel_rotor_at(&dev_enigma, l) = 'A'; 168 | libeel_rotor_at(&dev_enigma, m) = 'A'; 169 | libeel_rotor_at(&dev_enigma, r) = 'Z'; 170 | 171 | CUTE_ASSERT(ioctl(devfd, ENIGMA_SET, &dev_enigma) == 0); 172 | CUTE_TEST_CASE_END 173 | 174 | CUTE_TEST_CASE(devio_ioctldefaultset_tests) 175 | libeel_enigma_ctx dev_enigma; 176 | int devfd; 177 | 178 | CUTE_ASSERT((devfd = open("/dev/enigma", O_RDWR)) > -1); 179 | 180 | memset(&dev_enigma, 0, sizeof(dev_enigma)); 181 | 182 | dev_enigma.left_rotor = i; 183 | dev_enigma.middle_rotor = ii; 184 | dev_enigma.right_rotor = iii; 185 | 186 | libeel_ring(&dev_enigma, l) = 1; 187 | libeel_ring(&dev_enigma, m) = 1; 188 | libeel_ring(&dev_enigma, r) = 1; 189 | 190 | dev_enigma.reflector = b; 191 | 192 | libeel_rotor_at(&dev_enigma, l) = 'A'; 193 | libeel_rotor_at(&dev_enigma, m) = 'A'; 194 | libeel_rotor_at(&dev_enigma, r) = 'Z'; 195 | 196 | CUTE_ASSERT(ioctl(devfd, ENIGMA_SET_DEFAULT_SETTING, &dev_enigma) == 0); 197 | 198 | sleep(BREATH_INSECS); 199 | 200 | CUTE_ASSERT(close(devfd) == 0); 201 | CUTE_TEST_CASE_END 202 | 203 | CUTE_TEST_CASE(devio_write_tests) 204 | const char *plaintext = "GGGGGGGGGG"; 205 | size_t plaintext_size = strlen(plaintext); 206 | CUTE_ASSERT(write(devfd, plaintext, plaintext_size) == plaintext_size); 207 | CUTE_TEST_CASE_END 208 | 209 | CUTE_TEST_CASE(devio_read_tests) 210 | char ciphertext[11]; 211 | size_t ciphertext_size = 10; 212 | memset(ciphertext, 0, sizeof(ciphertext)); 213 | CUTE_ASSERT(read(devfd, ciphertext, ciphertext_size) == ciphertext_size); 214 | CUTE_ASSERT(strcmp(ciphertext, "PXWIAFZZLY") == 0); 215 | CUTE_TEST_CASE_END 216 | 217 | CUTE_TEST_CASE(devio_ioctlreset_tests) 218 | CUTE_ASSERT(ioctl(devfd, ENIGMA_RESET) == 0); 219 | CUTE_TEST_CASE_END 220 | 221 | CUTE_TEST_CASE(devio_write_inv_tests) 222 | const char *plaintext = "PXWIAFZZLY"; 223 | size_t plaintext_size = strlen(plaintext); 224 | CUTE_ASSERT(write(devfd, plaintext, plaintext_size) == plaintext_size); 225 | CUTE_TEST_CASE_END 226 | 227 | CUTE_TEST_CASE(devio_read_inv_tests) 228 | char ciphertext[11]; 229 | size_t ciphertext_size = 10; 230 | memset(ciphertext, 0, sizeof(ciphertext)); 231 | CUTE_ASSERT(read(devfd, ciphertext, ciphertext_size) == ciphertext_size); 232 | CUTE_ASSERT(strcmp(ciphertext, "GGGGGGGGGG") == 0); 233 | CUTE_TEST_CASE_END 234 | 235 | CUTE_TEST_CASE(devio_close_tests) 236 | CUTE_ASSERT(close(devfd) == 0); 237 | CUTE_TEST_CASE_END 238 | 239 | CUTE_TEST_CASE(usage_lines_tests) 240 | const int usage_lines_nr = 10; 241 | int fd[usage_lines_nr]; 242 | int f; 243 | 244 | for (f = 0; f < usage_lines_nr; f++) { 245 | fd[f] = open("/dev/enigma", O_RDWR); 246 | CUTE_ASSERT(fd[f] > -1); 247 | } 248 | 249 | f = open("/dev/enigma", O_RDWR); 250 | CUTE_ASSERT(f == -1); 251 | 252 | CUTE_ASSERT(close(fd[0]) == 0); 253 | 254 | f = open("/dev/enigma", O_RDWR); 255 | CUTE_ASSERT(f > -1); 256 | 257 | CUTE_ASSERT(close(f) == 0); 258 | 259 | for (f = 1; f < usage_lines_nr; f++) { 260 | CUTE_ASSERT(close(fd[f]) == 0); 261 | } 262 | CUTE_TEST_CASE_END 263 | 264 | CUTE_TEST_CASE_SUITE(device_poking_tests) 265 | CUTE_RUN_TEST(devio_open_tests); 266 | CUTE_RUN_TEST(devio_ioctlset_tests); 267 | CUTE_RUN_TEST(devio_write_tests); 268 | CUTE_RUN_TEST(devio_read_tests); 269 | CUTE_RUN_TEST(devio_ioctlreset_tests); 270 | CUTE_RUN_TEST(devio_write_inv_tests); 271 | CUTE_RUN_TEST(devio_read_inv_tests); 272 | CUTE_RUN_TEST(devio_close_tests); 273 | 274 | CUTE_RUN_TEST(devio_ioctldefaultset_tests); 275 | 276 | // INFO(Santiago): We are expecting the same result 277 | // even without a regular ioctl(ENIGMA_SET). 278 | CUTE_RUN_TEST(devio_open_tests); 279 | CUTE_RUN_TEST(devio_write_tests); 280 | CUTE_RUN_TEST(devio_read_tests); 281 | CUTE_RUN_TEST(devio_ioctlreset_tests); 282 | CUTE_RUN_TEST(devio_write_inv_tests); 283 | CUTE_RUN_TEST(devio_read_inv_tests); 284 | CUTE_RUN_TEST(devio_close_tests); 285 | CUTE_TEST_CASE_SUITE_END 286 | 287 | CUTE_TEST_CASE(device_tests) 288 | int exit_code = 1; 289 | 290 | printf("\n\n\033[1m\033[31m" 291 | "*** Hello Human, step back, I will test the \"enigma.ko\" within 5 secs.\n" 292 | " In case of any explosion, I strongly advise you to restart this computer. ***\033[m\n\n"); 293 | 294 | sleep(5); 295 | 296 | unload_module(); 297 | 298 | sleep(BREATH_INSECS); 299 | 300 | exit_code = load_module(); 301 | 302 | sleep(BREATH_INSECS); 303 | 304 | CUTE_ASSERT(exit_code == 0); 305 | 306 | CUTE_RUN_TEST(open_tests); 307 | CUTE_RUN_TEST(dev_ctls_tests); 308 | 309 | CUTE_RUN_TEST(usage_lines_tests); 310 | 311 | CUTE_RUN_TEST_SUITE(device_poking_tests); 312 | 313 | sleep(BREATH_INSECS); 314 | 315 | exit_code = unload_module(); 316 | 317 | CUTE_ASSERT(exit_code == 0); 318 | CUTE_TEST_CASE_END 319 | 320 | CUTE_MAIN(device_tests) 321 | -------------------------------------------------------------------------------- /src/toolsets.hsl: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2016 by Rafael Santiago 3 | # 4 | # This is free software. You can redistribute it and/or modify under 5 | # the terms of the GNU General Public License version 2. 6 | # 7 | # 8 | 9 | include on linux ~/toolsets/linux/linux-module.hsl 10 | include on freebsd ~/toolsets/freebsd/freebsd-module.hsl 11 | --------------------------------------------------------------------------------