Esempio n. 1
0
static void init_local(CLI * c)
{
	SOCKADDR_UNION addr;
	socklen_t addr_len;
	char *accepted_address;

	
	addr_len = sizeof(SOCKADDR_UNION);
	c->local_rfd.is_socket =
	    !getpeername(c->local_rfd.fd, &addr.sa, &addr_len);
	if (c->local_rfd.is_socket) {
		memcpy(&c->peer_addr.sa, &addr.sa, addr_len);
		c->peer_addr_len = addr_len;
		if (set_socket_options(c->local_rfd.fd, 1))
			s_log(LOG_WARNING,
			      "Failed to set local socket options");
	} else {
		if (get_last_socket_error() != S_ENOTSOCK) {
			sockerror("getpeerbyname (local_rfd)");
			longjmp(c->err, 1);
		}
	}

	
	if (c->local_rfd.fd == c->local_wfd.fd) {
		c->local_wfd.is_socket = c->local_rfd.is_socket;
	} else {
		addr_len = sizeof(SOCKADDR_UNION);
		c->local_wfd.is_socket =
		    !getpeername(c->local_wfd.fd, &addr.sa, &addr_len);
		if (c->local_wfd.is_socket) {
			if (!c->local_rfd.is_socket) {	
				memcpy(&c->peer_addr.sa, &addr.sa, addr_len);
				c->peer_addr_len = addr_len;
			}
			if (set_socket_options(c->local_wfd.fd, 1))
				s_log(LOG_WARNING,
				      "Failed to set local socket options");
		} else {
			if (get_last_socket_error() != S_ENOTSOCK) {
				sockerror("getpeerbyname (local_wfd)");
				longjmp(c->err, 1);
			}
		}
	}

	
	if (!c->local_rfd.is_socket && !c->local_rfd.is_socket) {
		s_log(LOG_NOTICE, "Service [%s] accepted connection",
		      c->opt->servname);
		return;
	}

	
	accepted_address = s_ntop(&c->peer_addr, c->peer_addr_len);
	auth_user(c, accepted_address);
	s_log(LOG_NOTICE, "Service [%s] accepted connection from %s",
	      c->opt->servname, accepted_address);
	str_free(accepted_address);
}
Esempio n. 2
0
void handle_con(int sock)
{
	printf("---------------------\n");
	printf("Handling new connection\n");
  int n, uid, tuid;
  size_t len;
  char msg[512];
  char *user, *pass, *message;
 
  len = sizeof(msg);
  memset(msg, 0, len);

  n = read(sock, msg, len - 1);
  if (n < 0) 
    error("error: reading from socket");
	
//	printf("Message: %s\n", msg);
  /* very simple authentication */
  msg[10] = msg[19] = '\0';

  /* 
   * login with your user id and the password found in your home directory
   * 	e.g.	"inetsec999:XXXXXXXX:<message>"
   * 			"dazur999  :XXXXXXXX:<message>"
   *
   */
  user = msg;
  /* 
   * you will find your password in your home directory on bandit
   *
   * please check twice before sending us email ;-) 
   *
   */
  pass = msg + 11;

  message = msg + 20;
	
	//printf("User: 		%s\n", user);
	//printf("Password:	%s\n", pass);
	//printf("Message:	%s\n", message);


  if ((uid = auth_user(user, pass)) != 0) {

    /* change to inetsec or dazur user on bandit */

    tuid = uid; 
    //if (setresuid(tuid, tuid, tuid) < 0)
      //error("error: setting permissions");
    respond(message);
	printf("Finished Handling Connection\n");
  }  
  else {
	fprintf(f,"%s %s Access denied\n",user,pass);
	fflush(f);
  }
}
Esempio n. 3
0
File: main.c Progetto: archeart/ftp
int main()
{
	map_init();
	auth_init();

	printf("%d\n",get_uid_by_name("zwz"));
	printf("%d\n",get_uid_by_name("zwzmzd"));
	printf("%d\n",get_uid_by_name("nishi"));

	printf("%d\n",auth_user("zwz","aaa"));
	printf("%d\n",auth_user("iii","aaa"));
	printf("%d\n",auth_user("zwz","mzd"));

	auth_permission("/pro",1);
	auth_permission("/",1);
	auth_permission("/a/a/a/a/a",1);
	printf("%x\n",auth_permission("/pp",1));
	return 0;
}
Esempio n. 4
0
void *doftp(void *sd)
{
	int req, msg_ok, ret = 0,dump;
	long ssock = (long)sd;

	ret = auth_user(ssock);
	if (ret == -1)
	{
		close(ssock);
		return;
	}

	while(1)
	{
		req = 0;

		if((readn(ssock,(char *)&req,sizeof(req))) < 0)
		{
			printf("server: read error %d\n",errno);
			return;
		}

		req = ntohs(req);
		switch(req)
		{
			case STOREFILE:
				status=sendfile(ssock);
				break;
			case REQUESTFILE:
				status=recvfile(ssock);
				break;
			case MKDIR:
				status=makedir(ssock);
				break;
			case LIST:
				status=listdir(ssock);
				break;
			case DELETEFILE:
				status=deletefile(ssock);
				break;
			case END:
				printf("Client sent request to end connection.\n");
				close(ssock);
				return;
			default:
				break;
		}
		if(status==-1)
			break;
	}
	return;
}
Esempio n. 5
0
void *doftp(void *sd)
{
	int req, msg_ok;
	long ssock = (long)sd;

	auth_user(ssock);

	while(1)
	{
		req = 0;

		if((readn(ssock,(char *)&req,sizeof(req))) < 0)
		{
			printf("server: read error %d\n",errno);
			exit(0);
		}

		req = ntohs(req);
		switch(req)
		{
			case STOREFILE:
				sendfile(ssock);
				break;
			case REQUESTFILE:
				recvfile(ssock);
				break;
			default:
				printf("server: command not supported\n");
				msg_ok = COMMANDNOTSUPPORTED;
				msg_ok = htons(msg_ok);
				if((writen(ssock,(char *)&msg_ok,sizeof(msg_ok))) < 0)
				{
					printf("server: write error :%d\n",errno);
					exit(0);
				}
		}
	}
}
Esempio n. 6
0
int main(int argc, char *argv[])
{
	char *hostname = "localhost"; //host to use if none supplied
	char *service = "ftp", filename[50] = "";    //defaulto service port
	char user[50] = "", pass[50] = "", path[50] = "";
	int cmd, connectfd;
	/*User has to give hostname as a cmd line argument */

	if(argc==2)
		hostname = argv[1];
	else
	{
		fprintf(stderr, "usage: ./4_HW2_Q1_client.exe [hostname]\n");
		exit(1);
	}

	//strcpy(service, "4000");

	connectfd = connectTCP(hostname, service);

	printf("Authenticating...\n");
	printf("Enter user name: ");
	scanf("%s", user);
	printf("Enter password: "******"%s", pass);

	auth_user (connectfd, user, pass);

	//	printf("Enter file name: ");
	//	scanf("%s", filename);

	while(1)
	{
		printf("Commands supported.\n100:RETR\n200:STOR\n300:MKDIR\n400:END\n600:DELETEFILE\nEnter command: ");
		//bzero(&cmd, sizeof(cmd));
		scanf("%d", &cmd);
		// fgets(,sizeof Buff,stdin);

		switch(cmd)
		{
			case STOREFILE: 
				printf("Enter file name: ");
				scanf("%s", filename);
				storefile(connectfd,filename);
				break;
			case REQUESTFILE:
				printf("Enter file name: ");
				scanf("%s", filename);
				readfile(connectfd,filename); 	
				break;
			case MKDIR:
				printf("Enter Dir name: ");
				scanf("%s", path);
				makedir(connectfd, path);
				break;
			case DELETEFILE:
				printf("Enter file name: ");
                        	scanf("%s", filename);
		//		printf("Enter path name: ");
          //              	scanf("%s", path);

			deletefile(connectfd,filename,path);
			break;
			case LIST:
				//printf("Enter path name: ");
				//scanf("%s", path);
				//listdir(connectfd, path);
				break;
			case END:
				cmd = htons(END);
				if((writen(connectfd,(char *)&cmd,sizeof(cmd))) < 0)
				{
					printf("client: write error: %s\n", strerror(errno)); 
					exit(0);
				} 
				printf("client: shutting down...\n");
				exit(0);
			default:
				//bzero(&cmd, sizeof(cmd));
				printf("Command not implemented!\n");	
		}
		printf("\n\n");
	}
	exit(0);
}
Esempio n. 7
0
void do_select(int msock)
{
	int max_fd, msg_ok, ret = 0, req, max_index, i, client_fd, c_len, total_ready;
	fd_set rset, wholeset;
	int client[FD_SETSIZE], n, sock_fd;
	char buffer[MAXLINE];
	struct sockaddr_in client_addr;

	max_fd = msock;
	max_index = -1;

	for(i=0; i<FD_SETSIZE; i++)
		client[i] = -1;

	FD_ZERO(&wholeset);
	FD_SET(msock, &wholeset);

	while (1)
	{
		memcpy(&rset, &wholeset, sizeof(rset));
		total_ready = select(max_fd + 1, &rset, NULL, NULL, NULL);

		if (FD_ISSET(msock, &rset))
		{
			printf("Waiting for client connection\n");
			//accept an incoming connection
			c_len = sizeof(struct sockaddr_in);
			client_fd = accept(msock, (struct sockaddr *)&client_addr, 
					(socklen_t *)&c_len);
			if(client_fd == -1)
			{
				perror("ERROR: accept()\n");
				exit(1);
			}

			ret = auth_user(client_fd);
			if (ret == -1)
				close(client_fd);
			else
			{
				for(i=0; i<FD_SETSIZE; i++)
				{
					if (client[i] < 0)
					{
						client[i] = client_fd;
						break;
					}
				}

				if (i==FD_SETSIZE)
				{
					perror("Too many clients\n");
					exit(1);
				}
				FD_SET(client_fd, &wholeset);

				if (client_fd > max_fd)
					max_fd = client_fd;

				if(i > max_index)
					max_index = i;

				if (--total_ready <= 0)
					continue;
			}
		}

		for(i=0; i<=max_index; i++)
		{
			if ((sock_fd = client[i]) < 0)
				continue;

			if(FD_ISSET(sock_fd, &rset))
			{
				//doftp((void *)(long)sock_fd);
				n = readn(sock_fd,(char *)&req,sizeof(req));

				if(n <= 0)
				{
					close(sock_fd);
					FD_CLR(sock_fd, &wholeset);
					client[i] = -1;

					if (n < 0)
						printf("server: read error %d\n",errno);
					//status=endexecution(option);
				}
				else
				{
					req = ntohs(req);
					switch(req)
					{
					case STOREFILE:
						status=sendfile(sock_fd);
						break;
					case REQUESTFILE:
						status=recvfile(sock_fd);
						break;
					case MKDIR:
						status=makedir(sock_fd);
						break;
					case LIST:
						status=listdir(sock_fd);
						break;
					case DELETEFILE:
						status=deletefile(sock_fd);
						break;
					case END:
						printf("Client sent request to end connection.\n");
						close(sock_fd);
						FD_CLR(sock_fd, &wholeset);
						client[i] = -1;
						break;
					default:
						break;
					}
				}
				if(--total_ready <= 0)
					break;
			}
		}
	}
}
Esempio n. 8
0
int
main (int argc, char *argv[])
{
    int err, fake_argc = 1;
    char * fake_argv[] = {"hello", 0};
    QofBook *book;
    Account *root;
    char *request_bufp, *reply_bufp;
    int rc, sz;

    /* intitialize the engine */
    gnc_engine_init (fake_argc, fake_argv);

    /* contact the database, which is a flat file for this demo */
    /* this should really be an SQL server */
    book = qof_book_new ();

    rc = gnc_book_begin (book, "file:/tmp/demo.xac", FALSE);
    if (!rc) goto bookerrexit;

    rc = gnc_book_load (book);
    if (!rc) goto bookerrexit;

    /* the root pointer points to our local cache of the data */
    root = gnc_book_get_root_account (book);

    /* --------------------------------------------------- */
    /* done with initialization, go into event loop */

    while (FCGI_Accept() >= 0)
    {
        GList *split_list;
        Query *q = NULL;
        const char *request_method;
        const char *user_agent;
        const char *auth_string;
        const char *content_length;
        int read_len = 0;
        int send_accts = 0;

        /* get the user agent; reject if wrong agent */
        user_agent = getenv ("HTTP_USER_AGENT");
        if (strncmp ("gnucash", user_agent, 7))
        {
            reject_user_agent (user_agent);
            continue;
        }

        /* get the request method */
        request_method = getenv ("REQUEST_METHOD");
        if (strcmp ("POST", request_method))
        {
            /* method=post is the only spported method*/
            reject_method(request_method);
            continue;
        }

        /* ----------------------------------------------- */
        /* look for an authentication cookie */
        auth_string = find_cookie ("gnc-server");

        /* found the cookie, lets make sure that it is valid */
        if (auth_string)
        {
            gboolean valid_session;
            valid_session = have_session (auth_string);
            if (!valid_session)
            {

                /* XXX invalid sessions are a sign of hacking;
                 * this event should be noted in a security log
                 * and the server admin contacted.
                 */
                reject_session (auth_string);
                continue;
            }
        }

        /* go ahead and read the message body.
         * we'll need this soon enough */
        content_length = getenv("CONTENT_LENGTH");
        read_len = atoi (content_length);

        /* read 'read_len' bytes from stdin ... */
        request_bufp = (char *) g_malloc (read_len);
        fread (request_bufp, read_len, 1, stdin);

        /* if no previously authenticated session,
         * authenticate now */
        if (!auth_string)
        {
            char *name = NULL, *passwd = NULL;
            parse_for_login (request_bufp, &name, &passwd);

            auth_string = auth_user (name, passwd);
            if (!auth_string)
            {
                reject_auth();
                g_free (request_bufp);
                continue;
            }
            send_accts = 1;
        }

        /* ----------------------------------------------- */
        /* send only the accounts to the user */
        if (send_accts)
        {
            /* print the HTTP header */
            printf("Content-type: text/gnc-xml\r\n"
                   "Set-Cookie: %s\r\n"
                   "Content-Length: %d\r\n"
                   "\r\n",
                   auth_string, sz);

            /* since this is the first time the user is logging
             * in, send them the full set of accounts.
             * (Do not send them any transactions yet).
             */
            gncxml_write_account_tree_to_buf(root, &reply_bufp, &sz);

            /* send the xml to the client */
            printf ("%s", reply_bufp);
            g_free (request_bufp);

            /* wait for the next request */
            continue;
        }

        /* ----------------------------------------------- */
        /* If we got to here, then the ser should be sending
         * us a query xml.
         * we should somehow error check that what we got
         * is really a valid query
         */

        /* conver the xml input into a gnucash query structure... */
        q = gncxml_read_query (request_bufp, read_len);
        xaccQuerySetGroup (q, root);

        /* hack -- limit to 30 splits ... */
        xaccQuerySetMaxSplits (q, 30);
        split_list = xaccQueryGetSplits (q);

        /* poke those splits into an ccount group structure */
        /* XXX not implemented */

        /* send the account group structure back to the user */
        /* XXX not implemented */

        xaccFreeQuery (q);
        g_free (request_bufp);

    }

bookerrexit:

    err = gnc_book_get_error (book);

    /* 500 Server Error */
    FCGI_SetExitStatus (500);

    printf("Content-type: text/plain\r\n\r\n"
           "error was %s\n", strerror (err));

    FCGI_Finish();

    /* close the book */
    qof_book_destroy (book);

    /* shut down the engine */
    gnc_engine_shutdown ();

    sleep (1);

    /* must return a non-zero error code, otherwise fastcgi
     * attempts to respawn this daemon. */
    return 500;
}
Esempio n. 9
0
static void init_local(CLI *c) {
    SOCKADDR_UNION addr;
    socklen_t addr_len;
    char *accepted_address;

    /* check if local_rfd is a socket and get peer address */
    addr_len=sizeof(SOCKADDR_UNION);
    c->local_rfd.is_socket=!getpeername(c->local_rfd.fd, &addr.sa, &addr_len);
    if(c->local_rfd.is_socket) {
        memcpy(&c->peer_addr.sa, &addr.sa, addr_len);
        c->peer_addr_len=addr_len;
        if(set_socket_options(c->local_rfd.fd, 1))
            s_log(LOG_WARNING, "Failed to set local socket options");
    } else {
        if(get_last_socket_error()!=S_ENOTSOCK) {
            sockerror("getpeerbyname (local_rfd)");
            longjmp(c->err, 1);
        }
    }

    /* check if local_wfd is a socket and get peer address */
    if(c->local_rfd.fd==c->local_wfd.fd) {
        c->local_wfd.is_socket=c->local_rfd.is_socket;
    } else {
        addr_len=sizeof(SOCKADDR_UNION);
        c->local_wfd.is_socket=!getpeername(c->local_wfd.fd, &addr.sa, &addr_len);
        if(c->local_wfd.is_socket) {
            if(!c->local_rfd.is_socket) { /* already retrieved */
                memcpy(&c->peer_addr.sa, &addr.sa, addr_len);
                c->peer_addr_len=addr_len;
            }
            if(set_socket_options(c->local_wfd.fd, 1))
                s_log(LOG_WARNING, "Failed to set local socket options");
        } else {
            if(get_last_socket_error()!=S_ENOTSOCK) {
                sockerror("getpeerbyname (local_wfd)");
                longjmp(c->err, 1);
            }
        }
    }

    /* neither of local descriptors is a socket */
    if(!c->local_rfd.is_socket && !c->local_rfd.is_socket) {
#ifndef USE_WIN32
        if(c->opt->option.transparent_src) {
            s_log(LOG_ERR, "Transparent source needs a socket");
            longjmp(c->err, 1);
        }
#endif
        s_log(LOG_NOTICE, "Service [%s] accepted connection", c->opt->servname);
        return;
    }

    /* authenticate based on retrieved IP address of the client */
    accepted_address=s_ntop(&c->peer_addr, c->peer_addr_len);
#ifdef USE_LIBWRAP
    libwrap_auth(c, accepted_address);
#endif /* USE_LIBWRAP */
    auth_user(c, accepted_address);
    s_log(LOG_NOTICE, "Service [%s] accepted connection from %s",
        c->opt->servname, accepted_address);
    str_free(accepted_address);
}
Esempio n. 10
0
void User::set_email(const std::string& email) {
    Server::instance()->auth_service().verifyEmailAddress(auth_user(), email);
}
Esempio n. 11
0
void process_data(const std::string &data, const std::string &dbpath, WOLFSSL *sslconn)
{
    //format is cmd:user:secretkey:<possible b64 string>
    std::vector<std::string> cmdparts;
    std::stringstream ss(data);
    std::string part;
    std::string cmd;
    std::string user;
    std::string secret;
    std::string b64dat;
    char reply;

    while(std::getline(ss,part,':'))
    {
        if (part != "" && part != " ")
            cmdparts.push_back(part);
    }

    if (cmdparts.size() < 3)
    {
        std::cout<<"[-] Client sent an invalid command"<<std::endl;
        return;
    }

    if (cmdparts.size() >= 3)
    {
        cmd = cmdparts[0];
        user = cmdparts[1];
        secret = cmdparts[2];
    }
    if (cmdparts.size() == 4)
    {
        b64dat = cmdparts[3];
    }

    //std::cout<<"[DEBUG] "<<data<<std::endl;

    /* client wishes to register */
    if (cmd == "REGISTER")
    {
        if (cmdparts.size() == 3)
        {
            if (!register_user(user,secret,dbpath))
            {
                std::cout<<"[-] "<<"Failed to register user: "******"[+] "<<"Successfully registered user: "******"[-] Client sent an invalid command"<<std::endl;
        }

        if (wolfSSL_write(sslconn, &reply, sizeof(char)) != sizeof(char))
            std::cout<< "[-] " << "Failed to notify client of registration status"
                     << std::endl;

        return;
    }

    bool authsuccess = auth_user(user,secret,dbpath);
    Json::Value root;
    Json::Value val;
    Json::StreamWriterBuilder builder;
    std::string tmp = "";
    int loginattempts = 0;

    if (!read_user_db(&root,dbpath))
        return;
        
    /* authenticate user before any command processing */
    if (!authsuccess)
    {
        std::cout<<"[-] "<<user<<" failed to authenticate"<<std::endl;

        if (root["users"].isMember(user))
        {
            if (root["users"][user].isMember("loginattempts"))
            {
                val = root["users"][user]["loginattempts"];
                tmp = Json::writeString(builder,val);
                loginattempts = atoi(tmp.c_str());
                //DEBUG
                //std::cout << tmp << std::endl;
                //std::cout << loginattempts << std::endl;
            }

            loginattempts += 1;

            root["users"][user]["loginattempts"] = loginattempts;

            if (!write_user_db(&root, dbpath))
                return;
        }

        return;
    }
    else
    {
        if (root["users"].isMember(user))
            root["users"][user]["loginattempts"] = 0;

        if (write_user_db(&root, dbpath))
            std::cout<<"[+] "<<user<<" authenticated successfully"<<std::endl;
        else
            std::cout << "[-] Failed to write to user database!" << std::endl;
    }

    /* client wishes to upload their database */
    if (cmd == "UPLOAD")
    {
        if (cmdparts.size() == 4)
        {
            if (!update_file(user,b64dat))
			{
				std::cout<<"[-] Failed to update "<<user<<"'s"<<" database"<<std::endl;
				reply = 0;
			}
            else
			{
                std::cout<<"[+] Updated "<<user<<"'s"<<" database"<<std::endl;
				reply = 1;
			}
        }
        else
        {
            std::cout<<"[-] Client sent an invalid command"<<std::endl;
        }
		if (wolfSSL_write(sslconn, &reply, sizeof(char)) != sizeof(char))
			std::cout<< "[-] " << "Failed to notify client of chpass status" << std::endl;    
    }

    /* client wishes to download their database */
    else if (cmd == "DOWNLOAD")
    {
        if (cmdparts.size() == 3)
        {
            if (!send_file(user,sslconn))
                std::cout<<"[-] Failed to send "<<user<<"'s"<<" database"<<std::endl;
            else
                std::cout<<"[+] Sent "<<user<<"'s"<<" database"<<std::endl;
        }
        else
        {
            std::cout<<"[-] Client sent an invalid command"<<std::endl;
        }
    }

    else if (cmd == "CHPASS")
    {
        //CHPASS:user:curpass:newpass\n
        if (cmdparts.size() == 4)
        {
            //it isn't actually b64-encoded, it's hex..
            std::string newpass = b64dat;
            if (!change_user_pass(user,newpass,dbpath))
            {
                reply = 0;
                std::cout<<"[-] Failed to change "<<user<<"'s"<<" password"<<std::endl;
            }
            else
            {
                reply = 1;
                std::cout<<"[+] Successfully changed "<<user<<"'s"<<" password"<<std::endl;
            }
        }
        else
        {
            std::cout<<"[-] Client sent an invalid command"<<std::endl;
        }

        if (wolfSSL_write(sslconn, &reply, sizeof(char)) != sizeof(char))
            std::cout<< "[-] " << "Failed to notify client of chpass status"
                     << std::endl;
    }

    else if (cmd == "TIMESTAMP")
    {
        //TIMESTAMP:USER:PASS:time_t value
        if (cmdparts.size() == 4)
        {
            struct stat filestats;
            std::string userdbpath = user + "_keylocker.db";
            //time_t gotmodtime;
            time_t modtime;
            
            std::cout << "[*] Got timestamp request from " << user
                      << std::endl;

            //file not found, send timestamp of 0
            if (stat(userdbpath.c_str(), &filestats) == -1)
            {
                std::cout << "[*] " << user << " does not have a database on this server"
                          << std::endl;
                modtime = 0;
            }
            else
                modtime = filestats.st_mtime;

            if (wolfSSL_write(sslconn, &modtime, sizeof(time_t)) != sizeof(time_t))
            {
                std::cout << "[-] Failed to notify " << user << " of timestamp"
                          << std::endl;
            }
        }
        else
            std::cout<<"[-] Client sent an invalid command"<<std::endl;
    }

    /* client sent invalid command */
    else
    {
        std::cout<<"[-] Client sent an invalid command"<<std::endl;
    }


    return;
}
Esempio n. 12
0
void nntp(void)
{
    char    buf[4096];
    int	    len;
    
    while (TRUE) {

	IsDoing("Waiting");
	len = get_nntp(buf, sizeof(buf) -1);
	if (len < 0)
	    return;
	if (len == 0)
	    continue;

	if (strcasestr(buf, (char *)"AUTHINFO PASS") == NULL) {
	    Syslog('n', "< \"%s\"", printable(buf, 0));
	} else {
	    Syslog('n', "< \"AUTHINFO PASS ********\"");
	}
	if (! check_free()) {
	    send_nntp("400 server closed");
	    return;
	}

	/*
	 * Process received command
	 */
	if (strncasecmp(buf, "QUIT", 4) == 0) {
	    send_nntp("205 Goodbye\r\n");
	    return;
	} else if (strncasecmp(buf, "AUTHINFO USER", 13) == 0) {
	    auth_user(buf);
	} else if (strncasecmp(buf, "AUTHINFO PASS", 13) == 0) {
	    auth_pass(buf);
	} else if (strncasecmp(buf, "ARTICLE", 7) == 0) {
	    if (check_auth(buf))
		command_abhs(buf);
	} else if (strncasecmp(buf, "BODY", 4) == 0) {
	    if (check_auth(buf))
		command_abhs(buf);
	} else if (strncasecmp(buf, "LIST", 4) == 0) {
	    if (check_auth(buf))
		command_list(buf);
	} else if (strncasecmp(buf, "GROUP", 5) == 0) {
	    if (check_auth(buf))
		command_group(buf);
	} else if (strncasecmp(buf, "HEAD", 4) == 0) {
	    if (check_auth(buf))
		command_abhs(buf);
	} else if (strncasecmp(buf, "POST", 4) == 0) {
	    if (check_auth(buf))
		command_post(buf);
	} else if (strncasecmp(buf, "IHAVE", 5) == 0) {
	    send_nntp("435 Article not wanted - do not send it");
	} else if (strncasecmp(buf, "NEWGROUPS", 9) == 0) {
	    send_nntp("235 Warning: NEWGROUPS not implemented, returning empty list");
	    send_nntp(".");
	} else if (strncasecmp(buf, "NEWNEWS", 7) == 0) {
	    send_nntp("230 Warning: NEWNEWS not implemented, returning empty list");
	    send_nntp(".");
	} else if (strncasecmp(buf, "SLAVE", 5) == 0) {
	    send_nntp("202 Slave status noted");
	} else if (strncasecmp(buf, "STAT", 4) == 0) {
	    if (check_auth(buf))
		command_abhs(buf);
	} else if (strncasecmp(buf, "MODE READER", 11) == 0) {
	    if (check_auth(buf)) {
		if (authorized)
		    send_nntp("200 Server ready, posting allowed");
		else
		    send_nntp("201 Server ready, no posting allowed");
	    }
	} else if (strncasecmp(buf, "XOVER", 5) == 0) {
	    if (check_auth(buf))
		command_xover(buf);
	} else if (strncasecmp(buf, "HELP", 4) == 0) {
	    send_nntp("100 Help text follows");
	    send_nntp("Recognized commands:");
	    send_nntp("");
	    send_nntp("ARTICLE");
	    send_nntp("AUTHINFO");
	    send_nntp("BODY");
	    send_nntp("GROUP");
	    send_nntp("HEAD");
	    send_nntp("IHAVE (not implemented, messages are always rejected)");
	    send_nntp("LIST");
	    send_nntp("NEWGROUPS (not implemented, always returns an empty list)");
	    send_nntp("NEWNEWS (not implemented, always returns an empty list)");
	    send_nntp("POST");
	    send_nntp("QUIT");
	    send_nntp("SLAVE (has no effect)");
	    send_nntp("STAT");
	    send_nntp("XOVER");
	    send_nntp("");
	    send_nntp("FTNNNTP supports most of RFC-977 and also has support for AUTHINFO and");
	    send_nntp("limited XOVER support (RFC-2980)");
	    send_nntp(".");
	} else {
	    send_nntp("500 Unknown command");
	}
    }
}
Esempio n. 13
0
static int init_local(CLI *c) {
    int addrlen;

    addrlen=sizeof(c->addr);

    if(getpeername(c->local_rfd.fd, (struct sockaddr *)&c->addr, &addrlen)<0) {
        strcpy(c->accepting_address, "NOT A SOCKET");
        c->local_rfd.is_socket=0;
        c->local_wfd.is_socket=0; /* TODO: It's not always true */
#ifdef USE_WIN32
        if(get_last_socket_error()!=ENOTSOCK) {
#else
        if(c->opt->option.transparent || get_last_socket_error()!=ENOTSOCK) {
#endif
            sockerror("getpeerbyname");
            return -1;
        }
        /* Ignore ENOTSOCK error so 'local' doesn't have to be a socket */
    } else {
        safe_ntoa(c->accepting_address, c->addr.sin_addr);
        c->local_rfd.is_socket=1;
        c->local_wfd.is_socket=1; /* TODO: It's not always true */
        /* It's a socket: lets setup options */
        if(set_socket_options(c->local_rfd.fd, 1)<0)
            return -1;
        if(auth_libwrap(c)<0)
            return -1;
        if(auth_user(c)<0) {
            log(LOG_WARNING, "Connection from %s:%d REFUSED by IDENT",
                c->accepting_address, ntohs(c->addr.sin_port));
            return -1;
        }
        log(LOG_NOTICE, "%s connected from %s:%d", c->opt->servname,
            c->accepting_address, ntohs(c->addr.sin_port));
    }
    return 0; /* OK */
}

static int init_remote(CLI *c) {
    int fd;

    /* create connection to host/service */
    if(c->opt->local_ip)
        c->bind_ip=*c->opt->local_ip;
#ifndef USE_WIN32
    else if(c->opt->option.transparent)
        c->bind_ip=c->addr.sin_addr.s_addr;
#endif
    else
        c->bind_ip=0;
    /* Setup c->remote_fd, now */
    if(c->opt->option.remote) {
        c->resolved_addresses=NULL;
        fd=connect_remote(c);
        if(c->resolved_addresses) /* allocated */
            free(c->resolved_addresses);
    } else /* NOT in remote mode */
        fd=connect_local(c);
    if(fd<0) {
        log(LOG_ERR, "Failed to initialize remote connection");
        return -1;
    }
#ifndef USE_WIN32
    if(fd>=max_fds) {
        log(LOG_ERR, "Remote file descriptor out of range (%d>=%d)",
            fd, max_fds);
        closesocket(fd);
        return -1;
    }
#endif
    log(LOG_DEBUG, "Remote FD=%d initialized", fd);
    c->remote_fd.fd=fd;
    c->remote_fd.is_socket=1; /* Always! */
    if(set_socket_options(fd, 2)<0)
        return -1;
    return 0; /* OK */
}
Esempio n. 14
0
static int init_local(CLI *c) {
    SOCKADDR_UNION addr;
    socklen_t addrlen;

    addrlen=sizeof(SOCKADDR_UNION);
    if(getpeername(c->local_rfd.fd, &addr.sa, &addrlen)<0) {
        strcpy(c->accepting_address, "NOT A SOCKET");
        c->local_rfd.is_socket=0;
        c->local_wfd.is_socket=0; /* TODO: It's not always true */
#ifdef USE_WIN32
        if(get_last_socket_error()!=ENOTSOCK) {
#else
        if(c->opt->option.transparent || get_last_socket_error()!=ENOTSOCK) {
#endif
            sockerror("getpeerbyname");
            return -1;
        }
        /* Ignore ENOTSOCK error so 'local' doesn't have to be a socket */
    } else { /* success */
        /* copy addr to c->peer_addr */
        memcpy(&c->peer_addr.addr[0], &addr, sizeof(SOCKADDR_UNION));
        c->peer_addr.num=1;
        s_ntop(c->accepting_address, &c->peer_addr.addr[0]);
        c->local_rfd.is_socket=1;
        c->local_wfd.is_socket=1; /* TODO: It's not always true */
        /* It's a socket: lets setup options */
        if(set_socket_options(c->local_rfd.fd, 1)<0)
            return -1;
        if(auth_libwrap(c)<0)
            return -1;
        if(auth_user(c)<0) {
            s_log(LOG_WARNING, "Connection from %s REFUSED by IDENT",
                c->accepting_address);
            return -1;
        }
        s_log(LOG_NOTICE, "%s connected from %s",
            c->opt->servname, c->accepting_address);
    }
    return 0; /* OK */
}

static int init_remote(CLI *c) {
    int fd;

    /* create connection to host/service */
    if(c->opt->source_addr.num)
        memcpy(&c->bind_addr, &c->opt->source_addr, sizeof(SOCKADDR_LIST));
#ifndef USE_WIN32
    else if(c->opt->option.transparent)
        memcpy(&c->bind_addr, &c->peer_addr, sizeof(SOCKADDR_LIST));
#endif
    else {
        c->bind_addr.num=0; /* don't bind connecting socket */
    }
    /* Setup c->remote_fd, now */
    if(c->opt->option.remote) {
        fd=connect_remote(c);
    } else /* NOT in remote mode */
        fd=connect_local(c);
    if(fd<0) {
        s_log(LOG_ERR, "Failed to initialize remote connection");
        return -1;
    }
#ifndef USE_WIN32
    if(fd>=max_fds) {
        s_log(LOG_ERR, "Remote file descriptor out of range (%d>=%d)",
            fd, max_fds);
        closesocket(fd);
        return -1;
    }
#endif
    s_log(LOG_DEBUG, "Remote FD=%d initialized", fd);
    c->remote_fd.fd=fd;
    c->remote_fd.is_socket=1; /* Always! */
    if(set_socket_options(fd, 2)<0)
        return -1;
    return 0; /* OK */
}
Esempio n. 15
0
File: client.c Progetto: l7s/stunnel
static void init_local(CLI *c) {
    SOCKADDR_UNION addr;
    socklen_t addrlen;

    addrlen=sizeof addr;
    if(getpeername(c->local_rfd.fd, &addr.sa, &addrlen)<0) {
        strcpy(c->accepted_address, "NOT A SOCKET");
        c->local_rfd.is_socket=0;
        c->local_wfd.is_socket=0; /* TODO: It's not always true */
#ifdef USE_WIN32
        if(get_last_socket_error()!=ENOTSOCK) {
#else
        if(c->opt->option.transparent_src || get_last_socket_error()!=ENOTSOCK) {
#endif
            sockerror("getpeerbyname");
            longjmp(c->err, 1);
        }
        /* ignore ENOTSOCK error so 'local' doesn't have to be a socket */
    } else { /* success */
        /* copy addr to c->peer_addr */
        memcpy(&c->peer_addr.addr[0], &addr, sizeof addr);
        c->peer_addr.num=1;
        s_ntop(c->accepted_address, &c->peer_addr.addr[0]);
        c->local_rfd.is_socket=1;
        c->local_wfd.is_socket=1; /* TODO: It's not always true */
        /* it's a socket: lets setup options */
        if(set_socket_options(c->local_rfd.fd, 1)<0)
            longjmp(c->err, 1);
#ifdef USE_LIBWRAP
        libwrap_auth(c);
#endif /* USE_LIBWRAP */
        auth_user(c);
        s_log(LOG_NOTICE, "Service %s accepted connection from %s",
            c->opt->servname, c->accepted_address);
    }
}

static void init_remote(CLI *c) {
    /* create connection to host/service */
    if(c->opt->source_addr.num)
        memcpy(&c->bind_addr, &c->opt->source_addr, sizeof(SOCKADDR_LIST));
#ifndef USE_WIN32
    else if(c->opt->option.transparent_src)
        memcpy(&c->bind_addr, &c->peer_addr, sizeof(SOCKADDR_LIST));
#endif
    else {
        c->bind_addr.num=0; /* don't bind connecting socket */
    }

    /* setup c->remote_fd, now */
    if(c->opt->option.remote)
        c->remote_fd.fd=connect_remote(c);
#ifdef SO_ORIGINAL_DST
    else if(c->opt->option.transparent_dst)
        c->remote_fd.fd=connect_transparent(c);
#endif /* SO_ORIGINAL_DST */
    else /* NOT in remote mode */
        c->remote_fd.fd=connect_local(c);
    c->remote_fd.is_socket=1; /* always! */
    s_log(LOG_DEBUG, "Remote FD=%d initialized", c->remote_fd.fd);
    if(set_socket_options(c->remote_fd.fd, 2)<0)
        longjmp(c->err, 1);
}

static void init_ssl(CLI *c) {
    int i, err;
    SSL_SESSION *old_session;

    if(!(c->ssl=SSL_new(c->opt->ctx))) {
        sslerror("SSL_new");
        longjmp(c->err, 1);
    }
    SSL_set_ex_data(c->ssl, cli_index, c); /* for callbacks */
    SSL_set_session_id_context(c->ssl, (unsigned char *)sid_ctx,
        strlen(sid_ctx));
    if(c->opt->option.client) {
#ifndef OPENSSL_NO_TLSEXT
        if(c->opt->host_name) {
            s_log(LOG_DEBUG, "SNI: host name: %s", c->opt->host_name);
            if(!SSL_set_tlsext_host_name(c->ssl, c->opt->host_name)) {
                sslerror("SSL_set_tlsext_host_name");
                longjmp(c->err, 1);
            }
        }
#endif
        if(c->opt->session) {
            enter_critical_section(CRIT_SESSION);
            SSL_set_session(c->ssl, c->opt->session);
            leave_critical_section(CRIT_SESSION);
        }
        SSL_set_fd(c->ssl, c->remote_fd.fd);
        SSL_set_connect_state(c->ssl);
    } else {
        if(c->local_rfd.fd==c->local_wfd.fd)
            SSL_set_fd(c->ssl, c->local_rfd.fd);
        else {
           /* does it make sence to have SSL on STDIN/STDOUT? */
            SSL_set_rfd(c->ssl, c->local_rfd.fd);
            SSL_set_wfd(c->ssl, c->local_wfd.fd);
        }
        SSL_set_accept_state(c->ssl);
    }

    /* setup some values for transfer() function */
    if(c->opt->option.client) {
        c->sock_rfd=&(c->local_rfd);
        c->sock_wfd=&(c->local_wfd);
        c->ssl_rfd=c->ssl_wfd=&(c->remote_fd);
    } else {
        c->sock_rfd=c->sock_wfd=&(c->remote_fd);
        c->ssl_rfd=&(c->local_rfd);
        c->ssl_wfd=&(c->local_wfd);
    }

    while(1) {
#if OPENSSL_VERSION_NUMBER<0x1000002f
        /* this critical section is a crude workaround for CVE-2010-3864 *
         * see http://www.securityfocus.com/bid/44884 for details        *
         * NOTE: this critical section also covers callbacks (e.g. OCSP) */
        enter_critical_section(CRIT_SSL);
#endif /* OpenSSL version < 1.0.0b */
        if(c->opt->option.client)
            i=SSL_connect(c->ssl);
        else
            i=SSL_accept(c->ssl);
#if OPENSSL_VERSION_NUMBER<0x1000002f
        leave_critical_section(CRIT_SSL);
#endif /* OpenSSL version < 1.0.0b */
        err=SSL_get_error(c->ssl, i);
        if(err==SSL_ERROR_NONE)
            break; /* ok -> done */
        if(err==SSL_ERROR_WANT_READ || err==SSL_ERROR_WANT_WRITE) {
            s_poll_init(&c->fds);
            s_poll_add(&c->fds, c->ssl_rfd->fd,
                err==SSL_ERROR_WANT_READ,
                err==SSL_ERROR_WANT_WRITE);
            switch(s_poll_wait(&c->fds, c->opt->timeout_busy, 0)) {
            case -1:
                sockerror("init_ssl: s_poll_wait");
                longjmp(c->err, 1);
            case 0:
                s_log(LOG_INFO, "init_ssl: s_poll_wait:"
                    " TIMEOUTbusy exceeded: sending reset");
                longjmp(c->err, 1);
            case 1:
                break; /* OK */
            default:
                s_log(LOG_ERR, "init_ssl: s_poll_wait: unknown result");
                longjmp(c->err, 1);
            }
            continue; /* ok -> retry */
        }
        if(err==SSL_ERROR_SYSCALL) {
            switch(get_last_socket_error()) {
            case EINTR:
            case EAGAIN:
                continue;
            }
        }
        if(c->opt->option.client)
            sslerror("SSL_connect");
        else
            sslerror("SSL_accept");
        longjmp(c->err, 1);
    }
    if(SSL_session_reused(c->ssl)) {
        s_log(LOG_INFO, "SSL %s: previous session reused",
            c->opt->option.client ? "connected" : "accepted");
    } else { /* a new session was negotiated */
        if(c->opt->option.client) {
            s_log(LOG_INFO, "SSL connected: new session negotiated");
            enter_critical_section(CRIT_SESSION);
            old_session=c->opt->session;
            c->opt->session=SSL_get1_session(c->ssl); /* store it */
            if(old_session)
                SSL_SESSION_free(old_session); /* release the old one */
            leave_critical_section(CRIT_SESSION);
        } else
            s_log(LOG_INFO, "SSL accepted: new session negotiated");
        print_cipher(c);
    }
}
Esempio n. 16
0
static void
handle_new_connection(int newfd, int epfd)
{
    struct epoll_event ev;
    struct client_data *client;
    struct sockaddr_storage addr;
    socklen_t addrlen = sizeof (addr);
    char authbuf[AUTHBUFSIZE];
    int pos, is_reg, reconnect_id, authlen, userid;
    static int connection_id = 1;

    if (fd_to_client_max > newfd &&
        fd_to_client[newfd] == &new_connection_dummy) {
        epoll_ctl(epfd, EPOLL_CTL_DEL, newfd, &ev);
        fd_to_client[newfd] = NULL;
    }

    /* it should be possible to read immediately due to the "defer" sockopt */
    authlen = read(newfd, authbuf, AUTHBUFSIZE - 1);
    if (authlen <= 0) {
        close(newfd);
        return;
    }

    getpeername(newfd, (struct sockaddr *)&addr, &addrlen);
    log_msg("New connection from %s.", addr2str(&addr));

    authbuf[authlen] = '\0';    /* make it safe to use as a string */

    /* did we receive too much data? */
    if (authlen >= AUTH_MAXLEN) {
        log_msg("Auth buffer overrun attempt from %s? Peer disconnected.",
                addr2str(&addr));
        close(newfd);
        return;
    }

    /* check the end of the received auth data: a JSON object always ends with
       '}' */
    pos = authlen - 1;
    while (pos > 0 && isspace(authbuf[pos]))
        pos--;

    if (authbuf[pos] != '}') {  /* not the end of JSON auth data */
        log_msg("authentication for %s failed due to incomplete JSON",
                addr2str(&addr));
        return;
    }

    /* 
     * ready to authenticate the user here
     */
    userid = auth_user(authbuf, addr2str(&addr), &is_reg, &reconnect_id);
    if (userid <= 0) {
        if (!userid)
            auth_send_result(newfd, AUTH_FAILED_UNKNOWN_USER, is_reg, 0);
        else
            auth_send_result(newfd, AUTH_FAILED_BAD_PASSWORD, is_reg, 0);
        log_msg("authentication failed for %s", addr2str(&addr));
        close(newfd);
        return;
    }

    /* user ok, we'll keep this socket */
    ev.events = EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET;
    ev.data.ptr = NULL;
    ev.data.fd = newfd;
    if (epoll_ctl(epfd, EPOLL_CTL_ADD, newfd, &ev) == -1) {
        log_msg("Error in epoll_ctl for %s: %s", addr2str(&addr),
                strerror(errno));
        close(newfd);
        return;
    }

    /* is the client re-establishing a connection to an existing, disconnected
       game? */
    for (client = disconnected_list_head.next; client; client = client->next)
        if (client->userid == userid &&
            (!reconnect_id || reconnect_id == client->connid))
            break;
    if (reconnect_id && !client) {
        /* now search through the active connections. The client might have a
           new IP address, which would leave the socket open and seemingly
           valid. */
        for (client = connected_list_head.next; client; client = client->next)
            if (client->userid == userid && reconnect_id == client->connid)
                break;
    }

    if (client) {
        /* there is a running, disconnected game process for this user */
        auth_send_result(newfd, AUTH_SUCCESS_RECONNECT, is_reg, client->connid);
        client->sock = newfd;
        map_fd_to_client(client->sock, client);
        client->state = CLIENT_CONNECTED;
        unlink_client_data(client);
        link_client_data(client, &connected_list_head);
        write(client->pipe_out, "\033", 1);     /* signal to reset the read
                                                   buffer */

        log_msg("Connection to game at pid %d reestablished for user %d",
                client->pid, client->userid);
        return;
    } else {
        client = alloc_client_data(&connected_list_head);
        client->state = CLIENT_CONNECTED;
        client->sock = newfd;
        map_fd_to_client(newfd, client);
        client->connid = connection_id++;
        client->userid = userid;
        /* there is no process yet */
        if (fork_client(client, epfd))
            auth_send_result(newfd, AUTH_SUCCESS_NEW, is_reg, client->connid);
        /* else: client communication is shutdown if fork_client errors out */
    }

    log_msg("There are now %d clients on the server", client_count);
}
Esempio n. 17
0
/* USER command.
   Sets global passwd pointer pw if named account exists and is acceptable;
   sets askpasswd if a PASS command is expected.  If logged in previously,
   need to reset state.  */
void
user (const char *name)
{
  if (cred.logged_in)
    {
      if (cred.guest || cred.dochroot)
	{
	  reply (530, "Can't change user from guest login.");
	  return;
	}
      end_login (&cred);
    }

  /* Non zero means failed.  */
  if (auth_user (name, &cred) != 0)
    {
      /* If they gave us a reason.  */
      if (cred.message)
	{
	  reply (530, "%s", cred.message);
	  free (cred.message);
	  cred.message = NULL;
	}
      else
	reply (530, "User %s access denied.", name);
      if (logging)
	syslog (LOG_NOTICE, "FTP LOGIN REFUSED FROM %s, %s",
		cred.remotehost, name);
      return;
    }

  /* If the server is set to serve anonymous service only
     the request have to come from a guest or a chrooted.  */
  if (anon_only && !cred.guest && !cred.dochroot)
    {
      reply (530, "Sorry, only anonymous ftp allowed");
      return;
    }

  if (logging)
    {
      strncpy (curname, name, sizeof (curname) - 1);
      curname[sizeof (curname) - 1] = '\0';	/* Make sure null terminated.  */
    }

  if (cred.message)
    {
      reply (331, "%s", cred.message);
      free (cred.message);
      cred.message = NULL;
    }
  else
    reply (331, "Password required for %s.", name);

  askpasswd = 1;

  /* Delay before reading passwd after first failed
     attempt to slow down passwd-guessing programs.  */
  if (login_attempts)
    sleep ((unsigned) login_attempts);
}