operator-login.cc (4737B)
1 /* -*- Mode: c++; -*- */ 2 /* -------------------------------------------------------------------- 3 * Filename: 4 * operator-login.cc 5 * 6 * Description: 7 * Implementation of the LOGIN command. 8 * 9 * Authors: 10 * Andreas Aardal Hanssen <andreas-binc curly bincimap spot org> 11 * 12 * Bugs: 13 * 14 * ChangeLog: 15 * 16 * -------------------------------------------------------------------- 17 * Copyright 2002-2005 Andreas Aardal Hanssen 18 * 19 * This program is free software; you can redistribute it and/or modify 20 * it under the terms of the GNU General Public License as published by 21 * the Free Software Foundation; either version 2 of the License, or 22 * (at your option) any later version. 23 * 24 * This program is distributed in the hope that it will be useful, 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 * GNU General Public License for more details. 28 * 29 * You should have received a copy of the GNU General Public License 30 * along with this program; if not, write to the Free Software 31 * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. 32 * -------------------------------------------------------------------- 33 */ 34 #ifdef HAVE_CONFIG_H 35 #include <config.h> 36 #endif 37 38 #include <unistd.h> 39 #include <sys/types.h> 40 #include <signal.h> 41 #include <errno.h> 42 43 #include <string> 44 #include <iostream> 45 46 #include "recursivedescent.h" 47 #include "session.h" 48 #include "authenticate.h" 49 50 #include "io.h" 51 52 #include "depot.h" 53 #include "operators.h" 54 55 using namespace ::std; 56 using namespace Binc; 57 58 59 //---------------------------------------------------------------------- 60 LoginOperator::LoginOperator(void) 61 { 62 } 63 64 //---------------------------------------------------------------------- 65 LoginOperator::~LoginOperator(void) 66 { 67 } 68 69 //---------------------------------------------------------------------- 70 const string LoginOperator::getName(void) const 71 { 72 return "LOGIN"; 73 } 74 75 //---------------------------------------------------------------------- 76 int LoginOperator::getState(void) const 77 { 78 return Session::NONAUTHENTICATED; 79 } 80 81 //------------------------------------------------------------------------ 82 Operator::ProcessResult LoginOperator::process(Depot &depot, 83 Request &command) 84 { 85 Session &session = Session::getInstance(); 86 IO &com = IOFactory::getInstance().get(1); 87 88 const bool allowplain 89 = (session.globalconfig["Authentication"]["allow plain auth in non ssl"] == "yes"); 90 91 if (!session.command.ssl && session["sslmode"] != "yes" && !allowplain && !getenv("ALLOWPLAIN")) { 92 session.setLastError("Plain text password authentication" 93 " is disallowed. Please try enabling SSL" 94 " or TLS in your mail client."); 95 return NO; 96 } 97 98 putenv(strdup(("BINCIMAP_LOGIN=LOGIN+" + command.getTag()).c_str())); 99 100 switch (authenticate(depot, command.getUserID(), command.getPassword())) { 101 case 1: 102 session.setLastError("An internal error occurred when you attempted" 103 " to log in to the IMAP server. Please contact" 104 " your system administrator."); 105 return NO; 106 case 2: 107 session.setLastError("Login failed. Either your user name" 108 " or your password was wrong. Please try again," 109 " and if the problem persists, please contact" 110 " your system administrator."); 111 return NO; 112 case 3: 113 com << "* BYE Timeout after " << session.idletimeout 114 << " seconds of inactivity." << endl; 115 break; 116 case -1: 117 com << "* BYE The server died unexpectedly. Please contact " 118 "your system administrator for more information." << endl; 119 break; 120 } 121 122 // go to logout 123 session.setState(Session::LOGOUT); 124 125 return NOTHING; 126 } 127 128 //---------------------------------------------------------------------- 129 Operator::ParseResult LoginOperator::parse(Request &c_in) const 130 { 131 Session &session = Session::getInstance(); 132 133 if (c_in.getUidMode()) 134 return REJECT; 135 136 Operator::ParseResult res; 137 if ((res = expectSPACE()) != ACCEPT) { 138 session.setLastError("Expected single SPACE after LOGIN"); 139 return res; 140 } 141 142 string userid; 143 if ((res = expectAstring(userid)) != ACCEPT) { 144 session.setLastError("Expected userid after LOGIN SPACE"); 145 return res; 146 } 147 148 c_in.setUserID(userid); 149 150 if ((res = expectSPACE()) != ACCEPT) { 151 session.setLastError("Expected SPACE after LOGIN SPACE userid"); 152 return res; 153 } 154 155 string password; 156 if ((res = expectAstring(password)) != ACCEPT) { 157 session.setLastError("Expected password after LOGIN " 158 "SPACE userid SPACE"); 159 return res; 160 } 161 162 if ((res = expectCRLF()) != ACCEPT) { 163 session.setLastError("Expected CRLF after password"); 164 return res; 165 } 166 167 c_in.setPassword(password); 168 c_in.setName("LOGIN"); 169 return ACCEPT; 170 }