mysql_real_escape_string für eine zusätzliche Variable einbauen



  • Hallo community,

    es geht darum, dass ich in einem Programm eine bereits vorhandene Variable zur Authentifizierung gegen eine MySQL-Datenbank nutzen möchte. Da diese durch Dritte beschrieben werden kann, muss diese natürlich escaped werden. Allerdings macht mir diese Aufgabe sehr zu schaffen, da ich ansonsten nur in Delphi, PHP und Perl unterwegs bin und mit dem Konzept von Pointern & co leider nicht viel am Hut habe 😉
    Durchs Googlen habe ich bereits einen Ansatz gefunden, der compiler läuft durch, aber an der AUTH-Stelle bricht es dann einfach ab. Zuerst werde ich die relevanten Ausschnitte des Original-Quellcodes posten und danach das, was ich versucht habe (meine Aenderungen sind in fett im zweiten Teil hervorgehoben!).

    Würde mich freuen, wenn jemand dort kurz drübergucken könnte 🙂

    Besten Dank,
    Error500

    ORIGINAL Sourcecode:

    static char *parse_select_clause (const char *clause, const char *username,
    				  const char *defdomain,
    				  const char *service,
    				  const char *pass) /* prampec@gmail.com */
    
    {
    	char *str;
    
    	static struct var_data vd[]={
    		{"local_part",	NULL,	sizeof("local_part"),	0},
    		{"domain",		NULL,	sizeof("domain"),	0},
    		{"service",		NULL,	sizeof("service"),	0},
    		{"password",	NULL,	sizeof("password"),	0}, /* prampec@gmail.com */
    		{NULL,		NULL,	0,			0}};
    
    	char *l_part;
    	char *d_part;
    
    	if (clause == NULL || *clause == '\0' ||
    	    !username || *username == '\0')
    		return NULL;
    
    	if (!local_and_domain_part_escaped(username, defdomain,
    					   &l_part, &d_part))
    		return NULL;
    
    	vd[0].value=l_part;
    	vd[1].value=d_part;
    	vd[2].value     = service;
    	vd[3].value     = pass; /* prampec@gmail.com */
    
    	str=parse_string (clause, vd);
    	free(l_part);
    	free(d_part);
    	return str;
    }
    
    static char *local_part_escaped(const char *username)
    {
    	const char *p=strchr(username, '@');
    	size_t n=p ? p-username:strlen(username);
    	char *buf=malloc(n*2+1);
    
    	if (!buf)
    	{
    		perror("malloc");
    		return NULL;
    	}
    
    	mysql_real_escape_string(mysql, buf, username, n);
    	return buf;
    }
    
    static char *domain_part_escaped(const char *username,
    				 const char *defdomain)
    {
    	const char *p=strchr(username, '@');
    	size_t n;
    	char *buf;
    
    	if (p)
    		++p;
    	else
    		p=defdomain;
    
    	n=strlen(p);
    
    	buf=malloc(n*2+1);
    
    	if (!buf)
    	{
    		perror("malloc");
    		return NULL;
    	}
    
    	mysql_real_escape_string(mysql, buf, p, n);
    	return buf;
    }
    
    static int local_and_domain_part_escaped(const char *username,
    					 const char *defdomain,
    					 char **local_ret,
    					 char **domain_ret)
    {
    	if ((*local_ret=local_part_escaped(username)) == NULL)
    		return 0;
    
    	if ((*domain_ret=domain_part_escaped(username, defdomain)) == NULL)
    	{
    		free(*local_ret);
    		return 0;
    	}
    
    	return 1;
    }
    

    Mein gepatchter Sourcecode:

    static char *parse_select_clause (const char *clause, const char *username,
    				  const char *defdomain,
    				  const char *service,
    				  const char *pass) /* prampec@gmail.com */
    
    {
    	char *str;
    
    	static struct var_data vd[]={
    		{"local_part",	NULL,	sizeof("local_part"),	0},
    		{"domain",		NULL,	sizeof("domain"),	0},
    		{"service",		NULL,	sizeof("service"),	0},
    		{"password",	NULL,	sizeof("password"),	0}, /* prampec@gmail.com */
    		{NULL,		NULL,	0,			0}};
    
    	char *l_part;
    	char *d_part;
    	[B]char *pass_part;[/B]
    
    	if (clause == NULL || *clause == '\0' ||
    	    !username || *username == '\0' [B]||
                !pass || *pass == '\0') [/B]
    		return NULL;
    
    	if (!local_and_domain_part_escaped(username, 
    					[B]pass, [/B]
    					defdomain,
    					&l_part, &d_part,
    					[B]&pass_part [/B]
    					))
    		return NULL;
    
    	vd[0].value=l_part;
    	vd[1].value=d_part;
    	vd[2].value     = service;
    	[B]vd[3].value     = pass_part;[/B]
    
    	str=parse_string (clause, vd);
    	free(l_part);
    	free(d_part);
    	[B]free(pass_part);[/B]
    	return str;
    }
    
    static char *local_part_escaped(const char *username)
    {
    	const char *p=strchr(username, '@');
    	size_t n=p ? p-username:strlen(username);
    	char *buf=malloc(n*2+1);
    
    	if (!buf)
    	{
    		perror("malloc");
    		return NULL;
    	}
    
    	mysql_real_escape_string(mysql, buf, username, n);
    	return buf;
    }
    
    static char *domain_part_escaped(const char *username,
    				 const char *defdomain)
    {
    	const char *p=strchr(username, '@');
    	size_t n;
    	char *buf;
    
    	if (p)
    		++p;
    	else
    		p=defdomain;
    
    	n=strlen(p);
    
    	buf=malloc(n*2+1);
    
    	if (!buf)
    	{
    		perror("malloc");
    		return NULL;
    	}
    
    	mysql_real_escape_string(mysql, buf, p, n);
    	return buf;
    }
    
    [B]
    static char *pass_part_escaped(const char *pass)
    {
            size_t n;
            char *buf;
    
            n=strlen(pass);
    
            buf=malloc(n*2+1);
    
            if (!buf)
            {
                    perror("malloc");
                    return NULL;
            }
    
            mysql_real_escape_string(mysql, buf, pass, n);
            return buf;
    }
    /* 
    static char *pass_part_escaped(const char *pass)
    {
    	char *to = new char[(strlen(pass) * 2) + 1];
    	mysql_real_escape_string(mysql, to, pass, strlen(pass));
    	return to;
    
    }
    */
    [/B]
    static int local_and_domain_part_escaped(const char *username,
    					 [B]const char *pass,[/B]
    					 const char *defdomain,
    					 char **local_ret,
    					 char **domain_ret,
    					 [B]char **pass_ret [/B]
    					 )
    {
    	if ((*local_ret=local_part_escaped(username)) == NULL)
    		return 0;
    
    [B]
    	if ((*pass_ret=pass_part_escaped(pass)) == NULL)
    	{
    		free(*local_ret);
    		return 0;
      	}
    [/B]
    
    	if ((*domain_ret=domain_part_escaped(username, defdomain)) == NULL)
    	{
    		free(*local_ret);
    		[B]free(*pass_ret);[/B]
    		return 0;
    	}
    
    	return 1;
    }
    


  • Das ist C. Hier ist das C++-Forum.


  • Administrator

    Und ob er wirklich Hilfe bekommt, mit dieser nichts aussagenden Fehlerbeschreibung und dem ganzen Quellcode, daran wage ich mal zu zweifeln. Wenn zumindest die Fehlerbeschreibung etwas besser wäre, könnte man es sich ja noch überlegen.

    Grüssli



  • Hallo,

    hier nochmal eine ausführlichere Beschreibung 🙂

    Der Funktion parse_select_clause() wird jetzt eine zusätzliche Variable, pass, übergeben. Im ersten Teil ("Originaler Sourcecode") wird diese unbehandelt verarbeitet und letztlich 1-zu-1 an MySQL übergeben (mit allen sich daraus ergebenden Risiken).

    Daher möchte ich die Variable vorher mit mysql_real_escape_string() escapen. Dazu habe ich mir angeguckt, wie im zweiten Teil mit den Variablen username, d_part und l_part verfahren wurde und versucht, das ganze analog für die Variable pass nachzubauen.

    In Zeile 25-30 übergebe ich die Variable pass dann an die Funktion local_and_domain_part_escaped() - dort wird dann in Zeile 128-132 die Funktion pass_part_escaped() aufgerufen, die dann eigentlich nur den Befehl mysql_real_escape_string() aufrufen soll.
    Helfen die zusätzlichen Erklärungen, nachzuvollziehen, worin das Problem genau besteht? 🙂


  • Administrator

    Schon ein wenig besser, insofern dass man schneller deine Änderungen wiederfindet. Aber die Fehlerbeschreibung ist immer noch nichtsaussagend:

    Error500 schrieb:

    ..., aber an der AUTH-Stelle bricht es dann einfach ab.

    Diesen Teilsatz solltest du noch erläutern. Was verstehst du unter AUTH-Stelle? Was heisst "bricht ab"? Stürzt das Programm ab? Wenn ja, mit welcher Fehlermeldung? Oder schliesst sich die Verbindung? Oder wird es gar nicht ausgeführt? usw. usf.

    Grüssli



  • Sooo, ich editiere meinen letzten Post jetzt einfach - habe das Problem jetzt selbst lösen können 🙂

    Die Funktion

    static char *pass_part_escaped(const char *pass)
    {
            size_t n;
            char *buf;
    
            n=strlen(pass);
    
            buf=malloc(n*2+1);
    
            if (!buf)
            {
                    perror("malloc");
                    return NULL;
            }
    
            mysql_real_escape_string(mysql, buf, pass, n);
            return buf;
    }
    

    war soweit völlig ok - das Problem wurde vorher ausgelöst, nämlich genau hier:

    if (clause == NULL || *clause == '\0' ||
                !username || *username == '\0' ||
                [b]!pass || *pass == '\0')[/b]
                    return NULL;
    

    Es kann in dem Programm vorkommen, dass legitimerweise kein Passwort ankommt - nachdem ich die fettgedruckte Zeile rausgenommen habe, klappt nun alles.


Anmelden zum Antworten