LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Fedora (http://www.linuxquestions.org/questions/fedora-35/)
-   -   C Errors on Portknocking (http://www.linuxquestions.org/questions/fedora-35/c-errors-on-portknocking-547233/)

prashanthjj 04-19-2007 01:28 AM

C Errors on Portknocking
 
Eventhough i installed the packages openssl and libslack the errors are came......... the errors are,

nockd.c: In function ‘main’:

knockd.c:110: warning: passing argument 2 of ‘signal’ from incompatible pointer type

knockd.c:111: warning: passing argument 2 of ‘signal’ from incompatible pointer type

knockd.c:115: warning: comparison between pointer and integer

knockd.c:147: warning: passing argument 1 of ‘strcmp’ makes pointer from integer without a cast

/tmp/cc49U7Qc.o: In function `main':knockd.c:(.text+0x193): undefined reference to `BF_set_key'
:knockd.c:(.text+0x213):

undefined reference to `daemon_init'
:knockd.c:(.text+0x24f): undefined reference to `MD5File'

:knockd.c:(.text+0x322): undefined reference to `MD5File'

:knockd.c:(.text+0x61a): undefined reference to `MD5File'

/tmp/cc49U7Qc.o: In function `eval_sequence':knockd.c:(.text+0x87e): undefined reference to `BF_ecb_encrypt'
/tmp/cc49U7Qc.o: In function `end_program':knockd.c:(.text+0xf3f): undefined reference to `daemon_close'

collect2: ld returned 1 exit status

nadroj 04-19-2007 01:40 AM

i imagine you have to link with the appropriate libraries when you compile it? check the documentation of the libraries for info on that.

let us know what you typed to compile it. also, if you want help to fix those warning messages, post your code. the warnings arent deadly, but should and can be avoided.

prashanthjj 04-21-2007 12:35 AM

Complete code
 
Quote:

Originally Posted by nadroj
i imagine you have to link with the appropriate libraries when you compile it? check the documentation of the libraries for info on that.

let us know what you typed to compile it. also, if you want help to fix those warning messages, post your code. the warnings arent deadly, but should and can be avoided.


This is the code which i compiled to do the concept called portknocking at Server side.....


// knockd.c - port knocking daemon
// Copyright (C) 2004 Matt Doyle <jmdoyle@cmu.edu>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.



// #INCLUDES
#include <slack/std.h> // from libslack (libslack.org), used for daemonizing
#include <slack/daemon.h> // from libslack (libslack.org), used for daemonizing
#include <stdio.h>
#include <stdlib.h>
#include <regex.h> // regular expression support
#include <pwd.h>
#include <unistd.h>
#include <sys/types.h>
#include <md5.h> // md5 support
#include <openssl/blowfish.h> // blowfish support
#include <time.h>
#include <signal.h>
#include "knock.h"


// #DEFINES
#define NUMOFSUBEXPS 3 // number of subexpressions in our regular expression


// GLOBALS
struct hostdata *hosts; // linked list of host nodes


// FUNCTION PROTOTYPES
void init_hostdata(struct hostdata *host);
void eval_sequence(struct hostdata *host, BF_KEY bfkey, unsigned short int offset);
void free_node(struct hostdata *host);
struct hostdata *add_host_to_list(struct hostdata *host);
struct hostdata *host_exists(char *remotehost);
void check_timestamps(time_t window);
void modify_ipfilter_firewall(struct hostdata *host);
void end_program(void);


// START MAIN
int main(int argc, char *argv[]){


// VARIABLES
unsigned int sleeptime = 1; // # of seconds to wait between md5 hash checks
char md5hash[33]; // stores md5 hash
char logfile[50]; // log file name
char logline[200]; // stores lines from log file as we pull them out
char remotehost[16]; // stores subexpression from regexp match
char localport[6]; // stores subexpression from regexp match
char offsetstring[6]; // stores offset in string form
char password[MAXPASSWDSIZE]; // encryption/decryption password
regex_t regexp; // stores compiled regular expression
regmatch_t subexps[NUMOFSUBEXPS]; // stores matched subexpressions of our regexp
fpos_t position; // stores file pointer
FILE *logfileptr;
BF_KEY bfkey;
struct hostdata *currenthost; // pointer to current host node being dealt with
time_t window = 10; // amount of time to receive all knocks from a host before freeing the node // FIX!
unsigned short int offset = 0; // port range offset


// CLEAR BUFFERS
memset(md5hash, '\0', sizeof(md5hash));
memset(logfile, '\0', sizeof(logfile));
memset(logline, '\0', sizeof(logline));
memset(remotehost, '\0', sizeof(remotehost));
memset(localport, '\0', sizeof(localport));
memset(offsetstring, '\0', sizeof(offsetstring));
memset(password, '\0', sizeof(password));


// INITIALIZE
memcpy(logfile, "/var/log/messages", sizeof(logfile)-1);
logfileptr = NULL;
hosts = NULL;


// PROMPT FOR ENCRYPTION PASSWORD
strcpy(password, getpass("Enter decryption password: "));
BF_set_key(&bfkey, sizeof(password), password);


// PROMPT FOR PORT OFFSET
printf("Enter port offset: ");
fgets(offsetstring, 5, stdin);
if((offset = (unsigned short int) strtol(offsetstring, NULL, 10)) > 65279){
printf("ERROR: Port offset > 65279\n");
exit(0);
}


// DAEMONIZE
daemon_init(argv[0]);
signal(SIGINT, end_program);
signal(SIGTERM, end_program);


// GET INITIAL MD5 HASH OF LOGFILE
if(MD5File(logfile, md5hash) == NULL){
printf("ERROR: Log file %s not found.\n", logfile);
end_program();
}


// OPEN LOG FILE FOR READING
if((logfileptr = fopen(logfile, "r")) == NULL){
perror("ERROR");
end_program();
}


// COMPILE REGULAR EXPRESSION
if(regcomp(&regexp, "^.+Connection attempt to TCP [0-9.]+:([0-9]+) from [0-9.]+):[0-9]+", REG_EXTENDED) != 0)
{
printf("ERROR: Unable to compile regular expression.\n");
exit(0);
}


// SAVE FILE POINTER FROM INITIAL EOF
fseek(logfileptr, 0, SEEK_END);
fgetpos(logfileptr, &position);
rewind(logfileptr);


// START MAIN WHILE LOOP
//printf("Running...\n\n");
while(1){ // FIX!


// IF LOG FILE UNCHANGED, SLEEP THEN LOOP AGAIN
if(strcmp(MD5File(logfile, NULL), md5hash) == 0){
check_timestamps(window);
sleep(sleeptime);
continue;
}

fsetpos(logfileptr, &position);

// LOOP OVER ALL LOG FILE LINES FROM SAVED POINT ON
while(!feof(logfileptr)){

check_timestamps(window);
memset(logline, '\0', sizeof(logline));
fgets(logline, sizeof(logline), logfileptr);

if(regexec(&regexp, logline, NUMOFSUBEXPS, subexps, 0) == 0){

memcpy(localport, logline+subexps[1].rm_so, (subexps[1].rm_eo-subexps[1].rm_so));
memcpy(remotehost, logline+subexps[2].rm_so, (subexps[2].rm_eo-subexps[2].rm_so));

//printf("%s knocking port %s\n", remotehost, localport);


// ADD HOST ENTRY IF IT DOESN'T EXIST, UPDATE IF IT DOES
if((currenthost = host_exists(remotehost)) == NULL){

currenthost = malloc(sizeof(struct hostdata));
init_hostdata(currenthost);
hosts = add_host_to_list(currenthost);

strcpy(currenthost->originIP, remotehost);
currenthost->knocks_enc[currenthost->knocksreceived] = (unsigned short int) strtol(localport, NULL, 10);
currenthost->knocksreceived++;
}
else{
currenthost->knocks_enc[currenthost->knocksreceived] = (unsigned short int) strtol(localport, NULL, 10);
currenthost->knocksreceived++;
if(currenthost->knocksreceived == MAXNUMOFKNOCKS)
eval_sequence(currenthost, bfkey, offset);
}


memset(localport, '\0', sizeof(localport));
memset(remotehost, '\0', sizeof(remotehost));
memset(subexps, '\0', sizeof(subexps));

} // END IF

else continue;

} // END WHILE


// SAVE NEW LOG FILE HASH AND NEW EOF POINTER
MD5File(logfile, md5hash);
fseek(logfileptr, 0, SEEK_END);
fgetpos(logfileptr, &position);


} // END WHILE


// CLEAN UP
fclose(logfileptr);
end_program();
return 0; // should never get here

} // END MAIN


/* ********** FUNCTION DEFINITIONS ********** */


// INIT_HOSTDATA
// Initializes fields of hostdata structures.
void init_hostdata(struct hostdata *host){

memset(host->originIP, '\0', sizeof(host->originIP));
memset(host->blf_in, '0', sizeof(host->blf_in));
memset(host->blf_out, '\0', sizeof(host->blf_out));
memset(host->knocks_enc, 0, sizeof(host->knocks_enc));
memset(host->knocks_dec, 0, sizeof(host->knocks_dec));
host->knocksreceived = 0;
host->next = NULL;
host->timestamp = time(NULL);

}


// ADD_HOST_TO_LIST
// Adds new host structures to linked list.
struct hostdata *add_host_to_list(struct hostdata *host){

// VARIABLES
struct hostdata *current;

current = hosts;
if(current == NULL)
return host;
while(current->next != NULL){
current = current->next;
}
current->next = host;

return hosts;
}


// HOST_EXISTS
// Tests to see if a node exists for a given host.
struct hostdata *host_exists(char *remotehost){

// VARIABLES
struct hostdata *current;

current = hosts;
while(current != NULL){
if(strcmp(current->originIP, remotehost) == 0)
return current;
current = current->next;
}

return NULL;
}


// EVAL_SEQUENCE
// Extracts knock information from a given host node and modifies the firewall
// accordingly.
void eval_sequence(struct hostdata *host, BF_KEY bfkey, unsigned short int offset){


// VARIABLES
unsigned short int upper = 0;
unsigned short int lower = 0;

//printf("\nKnock sequence: %d %d %d %d %d %d %d %d\n", host->knocks_enc[0], host->knocks_enc[1], host->knocks_enc[2], host->knocks_enc[3], host->knocks_enc[4], host->knocks_enc[5], host->knocks_enc[6], host->knocks_enc[7]);

host->blf_in[0] = ((unsigned char) host->knocks_enc[0]) - offset;
host->blf_in[1] = ((unsigned char) host->knocks_enc[1]) - offset;
host->blf_in[2] = ((unsigned char) host->knocks_enc[2]) - offset;
host->blf_in[3] = ((unsigned char) host->knocks_enc[3]) - offset;
host->blf_in[4] = ((unsigned char) host->knocks_enc[4]) - offset;
host->blf_in[5] = ((unsigned char) host->knocks_enc[5]) - offset;
host->blf_in[6] = ((unsigned char) host->knocks_enc[6]) - offset;
host->blf_in[7] = ((unsigned char) host->knocks_enc[7]) - offset;

BF_ecb_encrypt(host->blf_in, host->blf_out, &bfkey, BF_DECRYPT);

host->knocks_dec[0] = (unsigned short int) host->blf_out[0];
host->knocks_dec[1] = (unsigned short int) host->blf_out[1];
host->knocks_dec[2] = (unsigned short int) host->blf_out[2];
host->knocks_dec[3] = (unsigned short int) host->blf_out[3];
upper = host->blf_out[4] << 8;
lower = (unsigned short int) host->blf_out[5];
host->knocks_dec[4] = upper | lower;
host->knocks_dec[6] = (unsigned short int) host->blf_out[6];

//printf("Decrypted IP: %u.%u.%u.%u\n", host->knocks_dec[0], host->knocks_dec[1], host->knocks_dec[2], host->knocks_dec[3]);
//printf("Action: ");
//if(host->knocks_dec[6] == 1) printf("Open ");
//else if(host->knocks_dec[6] == 0) printf("Close ");
//else printf("NO ACTION ");
//printf("port %d to IP address %d.%d.%d.%d\n\n", host->knocks_dec[4], host->knocks_dec[0], host->knocks_dec[1], host->knocks_dec[2], host->knocks_dec[3]);

modify_ipfilter_firewall(host);
free_node(host);
}


// FREE_NODE
// Removes a processed node from the linked list.
void free_node(struct hostdata *host){

// VARIABLES
struct hostdata *previous;
struct hostdata *current;

if(host == hosts){ // if the node to free is the first in the list
current = host;
hosts = host->next;
free(current);
}
else{
previous = hosts;
current = hosts->next;
while(current != host){
previous = current;
current = current->next;
}
if(current->next != NULL)
previous->next = current->next;
else
previous->next = NULL;

free(current);
}
}


// CHECK_TIMESTAMPS
// Removes expired nodes from the linked list.
void check_timestamps(time_t window){

// VARIABLES
struct hostdata *current;

current = hosts;
while(current != NULL){
if(difftime(time(NULL), current->timestamp) >= window)
free_node(current);
current = current->next;
}
}


// MODIFY_IPFILTER_FIREWALL
// Subroutine for modifying an ipfilter firewall.
void modify_ipfilter_firewall(struct hostdata *host){

// VARIABLES
int ruleexists = 0;
int ruledeleted = 0;
char firewallrule[74]; // stores string of our firewall rule
char filebuffer[74]; // stores lines as they are read out of rule file
char buffer[6]; // storage buffer
regex_t regexp;
FILE *rulefile;
FILE *tempfile;


// INITIALIZE BUFFERS
memset(firewallrule, '\0', sizeof(firewallrule));
memset(buffer, '\0', sizeof(buffer));


// COMPOSE FIREWALL RULE STRING
strncat(firewallrule, " pass in quick on sis0 proto tcp from ", 38);
sprintf(buffer, "%d.%d.%d.%d", host->knocks_dec[0], host->knocks_dec[1], host->knocks_dec[2], host->knocks_dec[3]);
strncat(firewallrule, buffer, 15);
strncat(firewallrule, " to any port = ", 15);
memset(buffer, '\0', sizeof(buffer));
sprintf(buffer, "%d\n", host->knocks_dec[4]);
strncat(firewallrule, buffer, 15);


// COMPILE REGULAR EXPRESSION
if(regcomp(&regexp, firewallrule, REG_EXTENDED) != 0){
printf("ERROR: Unable to compile regular expression.\n");
exit(0);
}


// OPEN KNOCKD FIREWALL RULES FILE
if((rulefile = fopen("/etc/ipf.rules.knockd", "a+")) == NULL){
printf("ERROR: Unable to open ipf.rules.knockd\n");
exit(0);
}


// OPEN TEMPORARY FILE
if((tempfile = fopen("/tmp/temp", "w")) == NULL){
printf("ERROR: Unable to open temporary file.\n");
exit(0);
}


// IMMEDIATELY INSERT RULE IF FILE EMPTY AND ACTION IS TO OPEN
if(feof(rulefile) && host->knocks_dec[6] == 1)
fprintf(rulefile, firewallrule);


// DO NOTHING IF FILE IS EMPTY AND ACTION IS TO CLOSE
else if(feof(rulefile) && host->knocks_dec[6] == 0)
{} // do nothing


// LOOP THROUGH OUR RULE FILE
else{


while(!feof(rulefile)){

fgets(filebuffer, 74, rulefile);
filebuffer[73] = '\0';

// IF RULE MATCHES AND ACTION IS TO OPEN...
if((regexec(&regexp, filebuffer, 0, NULL, 0) == 0) && (host->knocks_dec[6] == 1)){
ruleexists = 1;
break;
}

// IF RULE DOESN'T MATCH AND ACTION IS TO OPEN...
else if((regexec(&regexp, filebuffer, 0, NULL, 0) != 0) && (host->knocks_dec[6] == 1))
continue;

// IF RULE MATCHES AND ACTION IS TO CLOSE...
else if((regexec(&regexp, filebuffer, 0, NULL, 0) == 0) && (host->knocks_dec[6] == 0)){
ruledeleted = 1;
continue;
}

// IF RULE DOESN'T MATCH AND ACTION IS TO CLOSE...
else if((regexec(&regexp, filebuffer, 0, NULL, 0) != 0) && (host->knocks_dec[6] == 0)){
fprintf(tempfile, filebuffer);
continue;
}


} // END WHILE


// APPEND RULE TO OPEN IF IT DOESN'T EXIST
if((ruleexists == 0) && (host->knocks_dec[6] == 1)){
fprintf(rulefile, firewallrule);
fclose(rulefile);
system("ipf -Fa -f /etc/ipf.rules.knockd -f /etc/ipf.rules");
fclose(tempfile);
}


// DELETE RULE IF IT EXISTS AND ACTION IS TO CLOSE
else if((ruledeleted == 1) && (host->knocks_dec[6] == 0)){

fclose(rulefile);
if(unlink("/etc/ipf.rules.knockd")){
printf("ERROR: Unable to delete rule file.\n");
exit(0);
}

fclose(tempfile);
if(rename("/tmp/temp", "/etc/ipf.rules.knockd")){
printf("ERROR: Unable to rename file.\n");
exit(0);
}

system("ipf -Fa -f /etc/ipf.rules.knockd -f /etc/ipf.rules");
}

// DELETE TEMP FILE
if(unlink("/tmp/temp")){
printf("ERROR: Unable to delete temp file.\n");
exit(0);
}


} // END ELSE


}


// END_PROGRAM
// Subroutine for cleaning up and shutting down.
void end_program(void){

daemon_close();
system("ipf -Fa -f /etc/ipf.rules"); // ipfilter dependent, fix this in future
unlink("/etc/ipf.rules.knockd");
exit(0);

}

nadroj 04-21-2007 12:42 AM

did you fix your initial (compiling) problem? if not:
Quote:

Originally Posted by nadroj
let us know what you typed to compile it.

.also please edit your post and put your code in '[code]' tags.

regarding the warnings i can try and help you with those after i sleep.

lulatsch 08-06-2009 04:48 PM

I also have C errors in knockd
 
Code:

src/knockd.c:134: error: ‘PATH_MAX’ undeclared here (not in a function)
src/knockd.c: In function ‘parseconfig’:
src/knockd.c:438: warning: unused variable ‘line’
src/knockd.c: In function ‘get_next_one_time_sequence’:
src/knockd.c:695: warning: unused variable ‘line’
src/knockd.c: In function ‘sniff’:
src/knockd.c:1386: warning: unused variable ‘parsed_stop_cmd’
src/knockd.c:1385: warning: unused variable ‘parsed_start_cmd’
make: *** [src/knockd.o] Error 1
error: Bad exit status from /var/tmp/rpm-tmp.8xQF95 (%build)


RPM build errors:
    Bad exit status from /var/tmp/rpm-tmp.8xQF95 (%build)

I am on Fedora 11.


Please help :(

nadroj 08-08-2009 12:48 PM

search google for the entire string "src/knockd.c:134: error: ‘PATH_MAX’ undeclared here (not in a function)". after a quick search, it appears others have seen this and it may be a bug in the project's code. i also read on one of the page results that this was recently fixed (a few months ago). look into this and make sure you have the fixed version.


All times are GMT -5. The time now is 10:22 PM.