1 module authentication; 2 3 import core.stdc.string : memset; 4 import std.stdio; 5 import std.algorithm.searching; 6 import std.exception; 7 8 import libssh.session; 9 import libssh.utils; 10 import libssh.errors; 11 12 AuthState authenticateKbdint(SSHSession session, string password) { 13 auto err = session.userauthKeyboardInteractive(null); 14 while (err == AuthState.Info) { 15 auto name = session.userauthKeyboardInteractiveGetName(); 16 auto instruction = session.userauthKeyboardInteractiveGetInstruction(); 17 auto n = session.userauthKeyboardInteractiveGetNPrompts(); 18 19 if (name !is null && name.length > 0) { 20 stdout.writefln("%s", name); 21 } 22 23 if (instruction !is null && instruction.length > 0) { 24 stdout.writefln("%s", instruction); 25 } 26 27 for (int i = 0; i < n; i++) { 28 bool echo; 29 auto prompt = session.userauthKeyboardInteractiveGetPrompt(i, echo); 30 31 if (echo) { 32 stdout.writefln("%s", prompt); 33 34 auto buffer = stdin.readln()[0 .. $ - 1]; 35 session.userauthKeyboardInteractiveSetAnswer(i, buffer); 36 } else { 37 string answer; 38 char[] buffer; 39 scope(exit) if (buffer !is null) memset(buffer.ptr, 0, buffer.length); 40 41 if (password !is null && prompt.canFind("Password:")) { 42 answer = password; 43 } else { 44 buffer = getPassword!(128)(prompt, false, false); 45 if (buffer is null) { 46 throw new SSHException("Error while reading password from user"); 47 } 48 answer = assumeUnique(buffer); 49 } 50 51 session.userauthKeyboardInteractiveSetAnswer(i, answer); 52 } 53 } 54 err = session.userauthKeyboardInteractive(null); 55 } 56 return err; 57 } 58 59 AuthState authenticateConsole(SSHSession session) { 60 // Try to authenticate 61 AuthState rc = session.userauthNone(null); 62 63 auto method = session.userauthList(null); 64 65 while (rc != AuthState.Success) { 66 if ((method & AuthMethod.GSSAPIMic) != 0) { 67 rc = session.userauthGSSAPI(); 68 if (rc == AuthState.Success) { 69 break; 70 } 71 } 72 73 // Try to authenticate with public key first 74 if ((method & AuthMethod.PublicKey) != 0) { 75 rc = session.userauthPublicKeyAuto(null, null); 76 if (rc == AuthState.Success) { 77 break; 78 } 79 } 80 81 // Try to authenticate with keyboard interactive"; 82 if ((method & AuthMethod.Interactive) != 0) { 83 rc = authenticateKbdint(session, null); 84 if (rc == AuthState.Success) { 85 break; 86 } 87 } 88 89 auto password = getPassword!(128)("Password: ", false, false); 90 if (password is null) { 91 throw new SSHException("Error while reading password from user"); 92 } 93 94 // Try to authenticate with password 95 if ((method & AuthMethod.Password) != 0) { 96 rc = session.userauthPassword(null, assumeUnique(password)); 97 if (rc == AuthState.Success) { 98 break; 99 } 100 } 101 memset(password.ptr, 0, password.length); 102 } 103 104 auto banner = session.issueBanner(); 105 if (banner !is null) { 106 stdout.writefln("%s", banner); 107 } 108 return rc; 109 }