Kernel Modul -> User Anmeldung dokumentieren

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
aras
Beiträge: 6
Registriert: 12.04.2013 14:35:24

Kernel Modul -> User Anmeldung dokumentieren

Beitrag von aras » 12.04.2013 15:23:38

Hallo alle zusammen,

ich bin gerade dabei ein Kernel Modul zu programmieren bzw. ich versuche es :lol: .
Ein simples Hello World Modul hab ich erfolgreich zum laufen bekommen. Mit dem einladen (insmod) und ausladen (rmmod) hatte ich keinerlei Probleme ;)

So erst mal zu meinem Vorhaben, ich möchte dass wenn sich ein Benutzer anmeldet (Login erfolgreich war) der Name und die Zeit in eine Logdatei geschrieben / gespeichert werden.
Jetzt stellt sich einfach die Frage, wie stellt man das am besten an ;) . Um die Frage auseinander zu nehmen sieht man das es 3 "Teilschritte" sind.

1. Schritt -> Abfangen das sich ein User angemeldet hat (über das Terminal)
Der für mich schwierigste Teil ist dieser hier, da ich zur Zeit absolut keine Ahnung habe, wie ich ein Benutzer nach erfolgreichen Login abfangen kann.
Zwei Ideen hab ich aktuell, wo es aber bei der Umsetzung hapert (falls überhaupt eine von den Ideen umsetzbar ist ^^ ).
Meine erste Idee war es, ob es möglich ist, das "login" Kommando abzufangen.
Und meine 2 Idee war es, eventuell zu überprüfen das ein neuer Prozess nicht vom "root" ist, sondern von einem Benutzer! Sprich dann muss sich ja jemand angemeldet haben. (falls es möglich ist z.B. über die Prozesstabelle dies zu überprüfen).

2. Schritt -> Die Zeit abfangen
Dies hab ich durch mehrere fehlgeschlagenen Versuche dann, doch endlich hinbekommen, aber vielleicht könnte man dies mit Schritt 1. kombinieren oder andere Vorschläge sind sehr gerne gesehen. Realisiert hab ich dies über die Real Time Clock Funktion (siehe Code)

Code: Alles auswählen

/*Nur der Time Ausschnitt*/
#include<asm/rtc.h>

struct rtc_time aktuelle_zeit;
get_rtc_time(&aktuelle_zeit);
printk("Es ist %d:%d:%d Uhr \n", aktuelle_zeit.tm.hour + 2, aktuelle_zeit.tm.min, aktuelle_zeit.tm.sec); // + 2 da UTC Time
3. Schritt -> Daten in die Logdatei schreiben
Dieser Schritt wäre natürlich erst mal der letzte auf der Liste. Da ich dies gerne in einer externen *.txt speichern möchte, würde ich wohl auf die fopen() Funktion zurück greifen. Da ich gelesen habe das diese auch bei der Kernel Programmierung funktionieren soll.

Dann bedanke ich mich schon mal für das Lesen meines Anliegens ^^ und hoffe das der ein oder andere eine Idee hat wie man gerade Schritt 1 realisierbar machen kann.
Des Weiteren hoffe ich das mein Anliegen sowie meine Darstellung des Problems gut erfasst habe.

Zum Schluss natürlich noch System Informationen:
Distribution: Debian 6.0.7
Kernel 2.6.32-5-686

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von r900 » 12.04.2013 16:33:40

aras hat geschrieben:ich möchte dass wenn sich ein Benutzer anmeldet (Login erfolgreich war) der Name und die Zeit in eine Logdatei geschrieben / gespeichert werden.
Das passiert doch bereits..

Code: Alles auswählen

# grep login /var/log/auth.log

aras
Beiträge: 6
Registriert: 12.04.2013 14:35:24

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von aras » 12.04.2013 17:01:14

r900 hat geschrieben: Das passiert doch bereits..

Code: Alles auswählen

# grep login /var/log/auth.log
Das ist mir durchaus bewusst, aber ich würde gerne eine "eigene" Routine programmieren mit diesem Modul.
Ich könnte natürlich auch den Inhalt aus der "auth.log" nehmen, und in eine andere *.txt kopieren, aber das möchte ich nicht, weshalb ich das gerne selber machen will.
Ich hab es mir dann ungefähr von der Ausgabe vorgestellt wie z.B. mit dem Terminal Befehl:

Code: Alles auswählen

last $USER_NAME

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von r900 » 12.04.2013 17:29:50

aras hat geschrieben:Das ist mir durchaus bewusst, aber ich würde gerne eine "eigene" Routine programmieren mit diesem Modul.
Dann verstehe ich nicht weshalb du so Dinge wie "vom Terminal abfangen" schreibst. Eigentlich müsste doch PAM die richtige Anlaufstelle sein.

exubuntu
Beiträge: 169
Registriert: 29.03.2013 22:25:44

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von exubuntu » 13.04.2013 12:10:59

keine ahnung von kernelprogrammierung aber dein obiges listing ist auch nur waehrend der sommerzeit korrekt oder

aras
Beiträge: 6
Registriert: 12.04.2013 14:35:24

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von aras » 15.04.2013 10:44:46

r900 hat geschrieben:Dann verstehe ich nicht weshalb du so Dinge wie "vom Terminal abfangen" schreibst. Eigentlich müsste doch PAM die richtige Anlaufstelle sein.
Da ich komplett neu im Linux Bereich bin und in der Woche erst mein erstes Kernel Module zum laufen bekommen habe, kann ich wohl nicht alles kennen ;) . Weshalb ich z.B. von PAM vorher noch nicht was gehört habe. Aber das hört sich richtig gut an um später andere Routinen zu bewerkstelligen, erst mal Danke für den Tip ;) . Sollte mein Modul nicht so laufen wie ich es mir aktuell vorstelle werde ich aufjedenfall einiges noch mit PAM anstellen bzw. versuchen später ^^.

Zu meiner Idee nochmal, es muss doch trotzdem möglich sein, das ich eine Funktion habe die erkennt "es hat sich jemand angemeldet" und in dieser Funktion überprüfe ich dann die uid (current->cred->uid). Und dadurch weiß ich welcher User das ist und baue somit meine Ausgabe mit der Zeit in eine Log.

exubuntu hat geschrieben:keine ahnung von kernelprogrammierung aber dein obiges listing ist auch nur waehrend der sommerzeit korrekt oder
Ähm das fragst du mich aber was :D ... Nach dem ich mir die UTC ausgegeben habe merkte ich das ich 2Std. zurück lag, weshalb ich dann einfach die + 2 drangehängt habe. Deshalb muss ich gestehen das ich darüber garnicht nachgedacht habe. Aber Danke für den Tip, das werde ich dann nochmal prüfen wenn das Modul steht.

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von r900 » 15.04.2013 12:19:51

aras hat geschrieben:Zu meiner Idee nochmal, es muss doch trotzdem möglich sein, das ich eine Funktion habe die erkennt "es hat sich jemand angemeldet" und in dieser Funktion überprüfe ich dann die uid (current->cred->uid). Und dadurch weiß ich welcher User das ist und baue somit meine Ausgabe mit der Zeit in eine Log.
Korrigiert mich falls ich mich irre, aber der Kernel, als Schnittstelle zwischen Hard- und Software, hat mit einem login doch gar nichts zu tun. Da die gesamte Authentifizierung über PAM abläuft wäre auch dort der richtige Ansatzpunkt. Du bräuchtest also kein Kernelmodul sondern ein PAM-Modul. Das einzige was mir dazu im Bereich des Kernels einfällt is SELinux.

aras
Beiträge: 6
Registriert: 12.04.2013 14:35:24

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von aras » 15.04.2013 13:39:55

r900 hat geschrieben:Korrigiert mich falls ich mich irre, aber der Kernel, als Schnittstelle zwischen Hard- und Software, hat mit einem login doch gar nichts zu tun. Da die gesamte Authentifizierung über PAM abläuft wäre auch dort der richtige Ansatzpunkt. Du bräuchtest also kein Kernelmodul sondern ein PAM-Modul. Das einzige was mir dazu im Bereich des Kernels einfällt is SELinux.
Ich kann nur sagen :THX: was du immer wieder für einfälle hast -> SELinux auch vorher noch nie gehört gleich mal in meine 2-Do-Liste gepackt .

Ich habe gerade gesehen das der erste Prozess in meiner Liste immer "/usr/bin/gnome-keyring-daemon --daemonize --login" bzw. "x-session-manager" der zweite Prozess ist (zeitlich gesehen nach dem Login).
Meinst du (auch an die anderen natürlich gerichtet) es wäre möglich z.B. einen festen Prozess abzufragen ob dieser gestartet wurde z.B. der "x-session-manager"? Somit würde ich nicht versuchen ein Login zu erfragen sondern ein Prozess ob gestartet oder nicht, und könnte darauf hin fragen wer gerade diesen Prozess gestartet hat. Weil hatte gerade was gelesen über Prozess Status (TASK_RUNNING) ... da schau ich jetzt mal weiter.

Kann schon ganz deprimierend sein wenn das nicht funktioniert wie man will ^^.

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von cosmac » 15.04.2013 14:18:39

hi,

reicht es nicht, wenn du einfach den setuid()-syscall abfängst? Das login-Programm startet ja als root und schaltet irgendwann auf den eigentlichen Benutzer um. Ob dazwischen noch ein bis drei fork() passieren, ist egal, ab dem setuid() läuft ein Benutzer-Prozess.

Damit erfasst du allerdings auch einen daemon, der nur seine root-Rechte abgeben will (z.B. möchte ein Webserver als www-data laufen). Das scheint mir aber eher ein Bonus zu sein.

Zur Sommerzeit: IMHO kannst du nur UTC ins Logfile schreiben, weil der Kernel keine Information über die Zeitzone hat. Direkt die RTC auszulesen hilft auch nicht, weil die ja auch UTC oder irgendeine Zeitzone benutzen kann. Der Trick mit dem 1. settimeofday() nach dem Booten funktioniert auch nur solange, wie sich der Offset nicht ändert. Wenn du Mitte März bootest stimmt der Offset im April nicht mehr. Zusätzlich könnten sich sogar die Regeln für die Zeitumstellung ändern, schau dir mal die Updates von Debiantzdata an.

Userland hat mit all dem keine Probleme, die Umrechnerei mit localtime() sollte immer unmittelbar vor der Anzeige der Zeit passieren.
Beware of programmers who carry screwdrivers.

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von r900 » 15.04.2013 14:50:50

cosmac hat geschrieben:reicht es nicht, wenn du einfach den setuid()-syscall abfängst?
Oh jetzt wird's spannend, da hab ich ja gar nicht dran gedacht. Kann man den denn überhaupt abfangen oder müsste man einen eigenen syscall schreiben der dann das Original aufruft? Hier wird letzteres beschrieben: http://www.tldp.org/LDP/lkmpg/2.6/html/ ... tml#AEN978

EDIT: oder auch hier: http://www.linuxjournal.com/article/4378

aras
Beiträge: 6
Registriert: 12.04.2013 14:35:24

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von aras » 16.04.2013 09:53:57

cosmac hat geschrieben:reicht es nicht, wenn du einfach den setuid()-syscall abfängst?
Ich selbst kann es nicht beantworten, da ich kompletter Neuling bin, aber da r900 schreibt das er daran nicht gedacht hat, könnte es funktionieren.
cosmac hat geschrieben:Damit erfasst du allerdings auch einen daemon, der nur seine root-Rechte abgeben will (z.B. möchte ein Webserver als www-data laufen). Das scheint mir aber eher ein Bonus zu sein.
Darauf komme ich zurück wenn es soweit ist, Danke für den extra Hinweis ;)
cosmac hat geschrieben:Zur Sommerzeit: ...
Auf die RTC bin ich gestiegen, weil das die erste Funktion war die bei mir gut geklappt hat nach mehreren versuchen, welche auch in der "/var/log/messages" zu sehen war als printk() Ausgabe. Aber das sollte ich mir dann nochmal anschauen, wenn das mit dem "setuid()" geklappt hat und ich meine Ausgabe bastle.

Erstmal vielen lieben Dank für die ganzen Infos 8)

_______________
r900 hat geschrieben:Oh jetzt wird's spannend, da hab ich ja gar nicht dran gedacht. Kann man den denn überhaupt abfangen oder müsste man einen eigenen syscall schreiben der dann das Original aufruft? Hier wird letzteres beschrieben: http://www.tldp.org/LDP/lkmpg/2.6/html/ ... tml#AEN978

EDIT: oder auch hier: http://www.linuxjournal.com/article/4378
r900 :hail: Danke für die Links ;) ...


Werde mich in dieser Woche, wenn ich Zeit habe immer mal wieder dran setzen und mich melden wenn ich was neues habe oder auch ein Problem. Jetzt setz ich mich erstmal mit den ganzen sys_calls auseinander bzw. im Zusammenhang mit setuid().

pferdefreund
Beiträge: 3799
Registriert: 26.02.2009 14:35:56

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von pferdefreund » 16.04.2013 19:06:31

Muß es denn so aufwendig sein ? Source vom login-Programm anpassen,
da wird ja wohl die erfolgreiche Anmeldung festgestellt und der user hat ja auch seinen Usernamen eingetippt. Die Uhrzeit sollte dann auch nicht das Problem sein, wenn vor dem Runlevel Multiuser eine Synchonistation mit ntp o. ähnlichem erfolgt. Meine Devise lautet immer keep it simple (nach über 30 Jahren Programmiererfahrung) - hat den Vorteil, dass man sein eigenes Zeug auch noch versteht, wenn man es nach 15 Jahren mal anpassen muß, wie es mir letzt erst passiert ist.

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von r900 » 16.04.2013 19:57:19

pferdefreund hat geschrieben: Source vom login-Programm anpassen, da wird ja wohl die erfolgreiche Anmeldung festgestellt und der user hat ja auch seinen Usernamen eingetippt.
Funktioniert nur nicht bei Anmeldung an der graphischen Oberfläche. Deshalb war ja mein urspruenglicher Vorschlag -> PAM. Ich habe allerdings den Eindruck dass der TE tiefer in die Welt des Kernels eintauchen möchte und daher eher der Weg das Ziel ist. :wink:

pferdefreund
Beiträge: 3799
Registriert: 26.02.2009 14:35:56

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von pferdefreund » 18.04.2013 15:08:47

Na und -xdm, gdm und wie sie alle heißen gibt es doch auch im Quellcode und das Wegschreiben vom User kann doch genausogut ne externe Funktion, die man
im login, gdm xdm kdm usw aufrufen kann - aber "der Weg ist das Ziel" stimmt schon. Ich hab auch schon die unmöglichsten Dinge programmiert, nur um zu wissen, wie.

aras
Beiträge: 6
Registriert: 12.04.2013 14:35:24

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von aras » 20.08.2013 10:04:04

Hallo alle zusammen, sry das ich mich nicht mehr gemeldet hatte (vorallem an die, welche mir geholfen hatten).
Aber wie es so manchmal ist man nimmt sich was vor, dann kommt eine kleinere Krankheit dazwischen, der altägliche Stress und vorallem die Vergessenheit 8) .
Nichts desto trotz würde ich gerne noch meine Lösung präsantieren, vielleicht gibt es hier den ein oder anderen, den es noch interessiert ;) .

Ich hab es doch so gemacht, das ich die Prozesstabelle auf eine entsprechende UID überprüfe ist diese vorhanden (uid = 1000) dann ist der User angemeldet.
Findet das Modul in der Prozesstabelle keine uid = 1000 dann ist der User inaktiv.
Ich habe es also aktuell so, dass nur ein entsprechender User überprüft wird. Aber das könnte man jetzt einfach weiter führen indem man die uid überprüft zu wem Sie gehört und diese dann entsprechend ausgibt.
Und anstatt das es in eine Logdatei geschrieben wird, ist es aktuell "nur" in der /var/log/messages.

Bevor ich herausgefunden hatte, das die uid verschoben wurde und nicht mehr im task_struct ist, sondern in den credentials, hatte ich eine Abfrage die den Namen vom Programm überprüft (siehe unten letzter Kommentar). Da ein Gnome-Panel erst beim Login gestartet wird, hatte es gut funktioniert ;). Aber nur bei einem grafischen Login 8O

Code: Alles auswählen

/* include Libaries */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <asm/rtc.h>

/* Module Informations */
MODULE_LICENSE("GPL");

/* Structs */
struct task_struct *task;
struct rtc_time currentTime;
struct timer_list callbackTimer;

/* Check for User */
int userProcessCheck(void)
{
	int userActive = 0, userInactive = 0;	

	rcu_read_lock();

	for_each_process(task)
	{
		task_lock(task);

		if( task->cred->uid == 1000)
		{
			userActive = 1;	
		}else{
			userInactive = 2;
		}

		task_unlock(task);
	}

	rcu_read_unlock();

		get_rtc_time(&currentTime);

		if(userActive == 1 && userInactive == 2)
		{			
			printk("Benutzer mit der UID: '1000' seit %d:%d:%d Uhr aktiv \n", currentTime.tm_hour + 2, currentTime.tm_min, currentTime.tm_sec);
		}

		if(userActive == 0 && userInactive == 2)
		{
			printk("Benutzer mit der UID: '1000' seit %d:%d:%d Uhr inaktiv \n", currentTime.tm_hour + 2, currentTime.tm_min, currentTime.tm_sec);
		}

	return 0;
}

/* Module Recall */
void module_recall(unsigned long data)
{
	userProcessCheck();

	setup_timer(&callbackTimer, module_recall, 0);
	
	mod_timer(&callbackTimer, jiffies + msecs_to_jiffies(20000));
}


/* Module Start */
static int __init module_putIn(void)
{
	printk("Usermodul wurde eingehaengt \n");

	userProcessCheck();
	setup_timer(&callbackTimer, module_recall, 0);
	
	mod_timer(&callbackTimer, jiffies + msecs_to_jiffies(20000));

	return 0;
}

/* Module Exit */
static void __exit module_putOut(void)
{
	del_timer(&callbackTimer);
	
	printk("Usermodul wurde ausgehaengt \n");
	
	return;
}

module_init(module_putIn);
module_exit(module_putOut);

/* Alternativer Versuch:
 * aber nur Abfrage beim grafischen Login, shell z.B. nicht berücksichtigt
 * if(strcmp(task->comm, "gnome-panel") == 0)*/
Hoffe dem ein oder anderen hilft *es ;)

Benutzeravatar
r900
Beiträge: 1053
Registriert: 09.10.2011 20:06:11
Lizenz eigener Beiträge: GNU Free Documentation License
Wohnort: Stockholm

Re: Kernel Modul -> User Anmeldung dokumentieren

Beitrag von r900 » 23.08.2013 13:33:26

aras hat geschrieben:Nichts desto trotz würde ich gerne noch meine Lösung präsantieren, vielleicht gibt es hier den ein oder anderen, den es noch interessiert ;) .
Ja den gibt es :)

Antworten